소스 코드 판독 redis 지속 화

8130 단어 redis지구 화

왜 지구 화가 필요 합 니까?
Redis 는 서버 가 실 행 될 때 시스템 이 일부 메모리 저장 데 이 터 를 할당 하 는 메모리 형 데이터베이스 이기 때문에 서버 가 끊 기거 나 갑자기 다운 되면 데이터베이스 에 있 는 데 이 터 를 잃 어 버 립 니 다.서버 가 갑자기 꺼 져 도 데 이 터 를 저장 할 수 있 도록 지속 적 인 방식 으로 데 이 터 를 메모리 에서 디스크 에 저장 해 야 합 니 다.
지속 적 인 프로그램 에 있어 서 데 이 터 는 프로그램 에서 컴퓨터 의 디스크 까지 의 절 차 는 다음 과 같다.
1.클 라 이언 트 가 데이터베이스 에 쓰기 명령 을 보 냅 니 다(이때 데 이 터 는 클 라 이언 트 의 메모리 에 있 습 니 다)
2.데이터 베 이 스 는 쓰 인 명령 과 데 이 터 를 받 습 니 다(데이터 가 서버 의 메모리 에 있 을 때)
3.데이터 베 이 스 는 시스템 호출 을 시작 하여 데 이 터 를 디스크 에 기록 합 니 다.(이때 데 이 터 는 커 널 메모리 에 있 습 니 다)
4.운영 체제 에서 데 이 터 를 디스크 컨트롤 러 에 전송 합 니 다(데 이 터 는 디스크 캐 시 에 있 습 니 다)
5.디스크 컨트롤 러 가 실제 데 이 터 를 물리 적 미디어 에 기록 하 는 작업(예 를 들 어 디스크)을 수행 합 니 다.
데이터베이스 차원 만 고려 하면 데이터 가 3 단계 이후 에 안전 합 니 다.이때 시스템 호출 이 시작 되 었 습 니 다.데이터베이스 프로 세 스 가 무 너 져 도 시스템 호출 은 계속 진행 되 고 데 이 터 를 디스크 에 순조롭게 기록 할 수 있 습 니 다.이 단계 이후 4 단계 커 널 에 서 는 커 널 캐 시 에서 디스크 캐 시 에 데 이 터 를 저장 하지만 시스템 효율 문 제 를 위해 기본적으로 이 동작 을 자주 실행 하지 않 고 30s 에서 한 번 정도 실 행 됩 니 다.이 는 이 단계 가 실패 하거나 이 단계 가 진행 되 었 을 때 서버 가 갑자기 꺼 졌 다 는 뜻 입 니 다.그러면 30s 의 데 이 터 를 잃 어 버 릴 수도 있 고 이런 비교적 일반적인 재난 문제 도 고려 해 야 한다.
POSIX API 도 커 널 이 캐 시 데 이 터 를 디스크 에 강제로 기록 하도록 시스템 호출 을 제공 합 니 다.흔히 볼 수 있 는 것 은 fsync 시스템 호출 입 니 다.int fsync(int fd);fsync 함 수 는 파일 설명자 fd 가 지정 한 파일 에 만 작용 하고 디스크 쓰기 작업 이 끝 난 후에 야 돌아 갑 니 다.fsync 를 호출 할 때마다 쓰기 동작 을 초기 화하 고 버퍼 의 데 이 터 를 디스크 에 기록 합 니 다.fsync()함수 가 쓰기 작업 을 끝 낼 때 프로 세 스 를 막 습 니 다.다른 스 레 드 도 같은 파일 을 쓰 고 있 으 면 쓰기 작업 이 끝 날 때 까지 다른 스 레 드 를 막 습 니 다.
지구 화
지구 화 는 프로그램 데 이 터 를 지구 상태 와 순간 상태 에서 전환 하 는 메커니즘 이다.프로그램 에 있어 서 프로그램 이 실 행 될 때 데 이 터 는 메모리 에 있 습 니 다.만약 에 디스크 에 동기 화하 지 않 으 면 전기 가 끊 기거 나 프로그램 이 갑자기 무 너 지면 데 이 터 를 잃 어 버 립 니 다.데 이 터 를 디스크 에 동기 화해 야 데 이 터 를 영구적 으로 저장 할 수 있 습 니 다.다운 영상 데이터 의 유효성 때 문 이 아 닙 니 다.지구 화 는 프로그램 에서 디스크 로 데 이 터 를 동기 화 하 는 동작 과정 이다.

Redis 의 지구 화
redis 는 RDB 와 AOF 두 가지 지구 화 방식 이 있다.RDB 는 스냅 샷 파일 방식 으로 redis 는 SAVE/BGSAVE 명령 을 실행 하여 데이터 백업 을 실행 하고 redis 현재 데 이 터 를*.rdb 파일 에 저장 하 며 파일 은 모든 데이터 집합 을 저장 합 니 다.AOF 는 서버 가 설정 을 읽 고 지 정 된 시간 에 redis 쓰기 동작 을 추가 하 는 명령 을*.aof 파일 에 추가 하 는 증분 영구 화 방식 입 니 다.
RDB
RDB 파일 은 SAVE 또는 BGSAVE 명령 을 통 해 이 루어 집 니 다.SAVE 명령 은 RDB 파일 이 생 성 될 때 까지 Redis 서비스 프로 세 스 를 막 습 니 다.BGSAVE 명령 은 포크 하위 프로 세 스 를 통 해 하위 프로 세 스 가 RDB 파일 을 만 들 고 부모 프로 세 스 와 하위 프로 세 스 가 데이터 세그먼트 를 공유 하 며 부모 프로 세 스 는 읽 기와 쓰기 서 비 스 를 계속 제공 하고 하위 프로 세 스 는 백업 기능 을 수행 합 니 다.BGSAVE 단 계 는 공유 데이터 세그먼트 를 수정 해 야 할 때 만 복사,즉 COW(Copy On Write)를 한다.SAVE 가 RDB 파일 을 만 들 면 여러 개의 저장 조건 을 설정 할 수 있 으 며,그 중 하나의 조건 만 충족 하면 배경 에서 SAVE 작업 을 수행 할 수 있다.
SAVE 와 BGSAVE 명령 의 실현 코드 는 다음 과 같 습 니 다.

void saveCommand(client *c) {

// BGSAVE       SAVE

if (server.rdb_child_pid != -1) {

addReplyError(c,"Background save already in progress");

return;

}

rdbSaveInfo rsi, *rsiptr;

rsiptr = rdbPopulateSaveInfo(&rsi);

//   rdbSave      (       )

if (rdbSave(server.rdb_filename,rsiptr) == C_OK) {

addReply(c,shared.ok);

} else {

addReply(c,shared.err);

}

}

/*

* BGSAVE      [    "schedule"]

*/

void bgsaveCommand(client *c) {

int schedule = 0;

/*  AOF     ,SCHEDULE    BGSAVE   

* BGSAVE      ,     

*      :BGSAVE     

*/

if (c->argc > 1) {

//      "schedule"

if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"schedule")) {

schedule = 1;

} else {

addReply(c,shared.syntaxerr);

return;

}

}

// BGSAVE    ,   

if (server.rdb_child_pid != -1) {

addReplyError(c,"Background save already in progress");

} else if (server.aof_child_pid != -1) {

// aof    ,  schedule==1,BGSAVE     

if (schedule) {

server.rdb_bgsave_scheduled = 1;

addReplyStatus(c,"Background saving scheduled");

} else {

addReplyError(c,

"An AOF log rewriting in progress: can't BGSAVE right now. "

"Use BGSAVE SCHEDULE in order to schedule a BGSAVE whenever "

"possible.");

}

} else if (rdbSaveBackground(server.rdb_filename,NULL) == C_OK) {//     rdbSaveBackground      

addReplyStatus(c,"Background saving started");

} else {

addReply(c,shared.err);

}

}

RDB 파일 이 있 으 면 서버 가 꺼 져 있 거나 서버 가 추가 되 어 데이터베이스 서버 를 다시 시작 해 야 하면 RDB 파일 을 불 러 와 서 백업 한 데 이 터 를 복원 할 수 있 습 니 다.그러나 bgsave 는 시간 이 오래 걸 리 고 실시 간 으로 부족 하여 정지 할 때 대량의 데 이 터 를 잃 어 버 릴 수 있 습 니 다.
AOF(Append Only File)
RDB 파일 은 데이터베이스 의 키 값 대 데 이 터 를 저장 하고 AOF 는 데이터베이스 에서 실행 되 는 쓰기 명령 을 저장 합 니 다.
AOF 의 실현 절 차 는 세 단계 가 있다.
append->write->fsync
append 는 AOF 버퍼 에 추가 명령 을 내 렸 습 니 다.write 는 버퍼 의 내용 을 프로그램 버퍼 에 기록 하고 fsync 는 프로그램 버퍼 의 내용 을 파일 에 기록 합 니 다.AOF 지구 화 기능 이 켜 진 상태 일 때 서버 는 명령 을 수행 할 때마다 redisServer 구조 체 의 aof 에 명령 을 프로 토 콜 형식 으로 추가 로 기록 합 니 다.buf 버퍼,구체 적 인 프로 토 콜 은 설명 하지 않 습 니 다.
AOF 의 지구 화 발생 시기 에 appendfsync 설정 옵션 이 있 습 니 다.이 옵션 은 세 가지 값 이 있 습 니 다:always:모든 내용 을 aof 파일 everysec 에 기록 하고 동기 화 합 니 다:aofbuf 버퍼 의 내용 을 AOF 파일 에 기록 합 니 다.마지막 으로 AOF 파일 을 동기 화 한 no:aofbuf 버퍼 에 있 는 모든 내용 을 AOF 파일 에 기록 하지만 AOF 파일 과 동기 화 되 지 않 습 니 다.운영 체제 에서 동기 화 를 결정 합 니 다.기본 값 인 30s 입 니 다.
AOF 영구 화 모드 는 쓰 는 명령 마다 AOF 파일 에 추가 되 며,서버 가 계속 실행 되면 서 AOF 파일 이 커지 고,AOF 에서 발생 하 는 파일 이 너무 크 지 않도록 서버 가 AOF 파일 을 다시 쓰 고,같은 키 를 작 동 하 는 동일 한 명령 을 합 쳐 파일 크기 를 줄인다.
예 를 들 어 한 직원 의 이름,성별 등 정 보 를 저장 해 야 한다.
> hset employee_12345 name "hoohack"
> hset employee_12345 good_at "php"
> hset employee_12345 gender "male"
이 해시 키 를 입력 한 상태 에서 만 AOF 파일 은 세 개의 명령 을 저장 해 야 합 니 다.삭제 나 값 을 업데이트 하 는 작업 이 있 으 면 명령 이 더 많 고 파일 이 더 커 집 니 다.다시 쓰 면 파일 의 크기 를 적 절 히 줄 일 수 있 습 니 다.
AOF 재 작성 의 실현 원 리 는 먼저 서버 에 있 는 데이터 베 이 스 를 옮 겨 다 니 며 데이터 베 이 스 를 옮 겨 다 니 며 각 데이터베이스 에 있 는 모든 키 대상 을 찾 아 키 쌍 의 키 와 값 을 가 져 오고 키 의 유형 에 따라 키 쌍 을 재 작성 하 는 것 이다.예 를 들 어 위의 예 는 다음 명령 으로 합 칠 수 있 습 니 다.
> hset employee_12345 name "hoohack" good_at "php" gender "male"。
AOF 의 재 작성 은 대량의 기록 작업 을 수행 합 니 다.Redis 는 단일 스 레 드 이기 때문에 서버 가 직접 재 작성 을 호출 하면 서버 가 다른 명령 을 처리 할 수 없 기 때문에 Redis 서버 는 AOF 재 작성 을 수행 하 는 단독 프로 세 스 를 새로 만 들 었 습 니 다.
Redis 재 작성 프로 세 스 실행:

하위 프로 세 스 가 AOF 재 작성 을 수행 할 때 서버 에서 클 라 이언 트 의 명령 을 받 은 후 클 라 이언 트 가 보 낸 명령 을 먼저 실행 한 다음 에 실 행 된 쓰기 명령 을 AOF 버퍼 에 추가 하고 실 행 된 쓰기 명령 을 AOF 재 작성 버퍼 에 추가 합 니 다.하위 프로 세 스 가 재 작성 작업 이 완료 되면 서버 에 완 료 된 신 호 를 보 내 고 서버 는 AOF 재 작성 버퍼 의 모든 내용 을 AOF 파일 에 추가 한 다음 기 존의 AOF 파일 을 원자 적 으로 덮어 씁 니 다.
RDB 와 AOF 의 장단 점.
RDB 영구 화 방식 은 서버 를 통 해 데 이 터 를 읽 기만 하면 백업 중인 파일 을 프로그램 에 불 러 올 수 있 으 며,AOF 방식 은 가짜 클 라 이언 트 를 만들어 야 실행 할 수 있 습 니 다.
RDB 의 파일 은 비교적 작 아서 어느 시점 이전의 데 이 터 를 저장 하여 재해 대비 와 주종 동기 화 에 적합 하 다.
RDB 백업 시간 이 오래 걸 리 고 데이터 양 이 많 으 면 다운 되 는 상황 에서 일부 데 이 터 를 잃 어 버 릴 수 있 습 니 다.또한 RDB 는 설정 을 통 해 특정한 조건 에 도달 할 때 만 실행 되 며,이 기간 내 에 다운 되면 이 부분의 데 이 터 를 잃 어 버 릴 수 있 습 니 다.
AOF 방식 은 같은 데이터 집합의 경우 RDB 방식 보다 파일 크기 가 클 수 있다.
AOF 의 지속 화 방식 도 설정 을 통 해 다 릅 니 다.기본 설정 은 초당 동기 화 입 니 다.가장 빠 른 모드 는 모든 명령 을 동기 화 하 는 것 입 니 다.가장 나 쁜 방식 은 시스템 이 fsync 를 실행 할 때 디스크 파일 에 버퍼 를 동기 화 하 는 것 입 니 다.대부분의 운영 체 제 는 30s 입 니 다.보통 1 초 에 한 번 씩 동기 화 되도록 설정 되 어 있 기 때문에 최대 1s 의 데 이 터 를 잃 어 버 릴 수 있 습 니 다.
어떤 동기 화 방식 이 더 좋 습 니까?
RDB 와 AOF 방식 의 결합.정시 작업 을 시작 합 니 다.서버 의 현재 상태 데 이 터 를 시간 당 백업 하고 날짜 와 시간 으로 이름 을 짓 습 니 다.다른 정시 작업 을 시작 하여 잘못된 백업 파일(예 를 들 어 48 시간 전)을 정기 적 으로 삭제 합 니 다.AOF 를 1s 로 한 번 설정 합 니 다.이렇게 되면 최대 1s 의 데 이 터 를 잃 어 버 리 는 동시에 redis 에 눈사태 가 발생 하면 전날 의 상태 로 신속하게 회복 되 어 서 비 스 를 중단 하지 않 을 수 있다.
총결산
Redis 의 지속 화 방안 도 변 함 이 없 는 것 이 아니 라 종이 의 이론 은 실천 성과 와 결합 하여 타당 성 을 증명 해 야 한다.

좋은 웹페이지 즐겨찾기