소개 | "대용량 Redis 스토리지 - 피카의 모든 것"에서 피카의 탄생, 피카의 특징, 피카의 핵심과 피카의 활용법을 소개했습니다. 이 기사에서는 pika 동기화 논리의 중요한 파일을 매우 자세히 분석합니다. "write2file"의 데이터 저장 방법 및 구현 원리는 매우 읽을 가치가 있습니다! |
pika는 360 웹플랫폼사업부의 DBA와 인프라팀이 공동으로 개발한 대용량 Redis형 스토리지입니다. pika의 등장은 Redis를 대체하기 위한 것이 아니라 Redis 시나리오를 보완하기 위한 것입니다. Pika는 Redis 프로토콜과 완벽하게 호환되고 느린 복구 시간, 높은 마스터-슬레이브 비용 등 Redis의 편리한 운영 및 유지 관리 설계를 계승한다는 전제 하에 영구 저장소를 통해 대용량 시나리오에서 Redis의 문제를 해결하려고 노력합니다. 동기화, 상대적으로 취약한 단일 스레드 및 로드 베어링 용량 데이터가 제한되어 있고 메모리 비용이 높습니다.
pika 마스터-슬레이브 복제 원리 binlogBinlog 관련 파일에는 매니페스트와 write2file의 두 부분이 포함되어 있습니다. 매니페스트는 현재 로그 파일 번호와 현재 로그 파일 오프셋을 포함하여 로그 메타 정보를 기록합니다. write2file+num은 pika가 받은 모든 redis 쓰기 명령과 매개변수를 기록합니다.
파일 형식매니페스트 파일 형식:
로그 오프셋(8바이트)|con_offset(8바이트, 미사용)|요소 수(4바이트, 미사용)|로그 파일 번호(4바이트).
Binlog 파일 형식:
Binlog 파일의 고정 크기는 100MB입니다. 각 Binlog 파일은 여러 블록으로 구성됩니다. 각 블록의 크기는 64KB로 고정됩니다. 레코드는 여러 블록에 배포될 수 있지만 하나의 Binlog 파일에만 배포되므로 Binlog 파일은 100MB보다 클 수 있습니다.
기록 형식: 헤더|Cmd
헤더: 레코드 길이(3바이트) | 타임스탬프(4바이트) | 레코드 유형(1바이트)
Cmd: 현재 블록의 남은 공간이 레코드를 저장할 수 있는지 여부에 따라 redis 명령의 일부 또는 전부.
구현 수업기초수업
버전: mmap 및 매니페스트 파일을 통해 매핑되는 메타 정보 클래스입니다.
Binlog: mmap 및 write2file 파일을 통해 매핑된 로그 클래스입니다.
PikaBinlogSenderThread: 로그 소비 클래스, 로그 파일 내용을 순차적으로 읽고 로그를 소비합니다.
기본 조작Binlog 구성
//file_size는 구성 파일에서 지정할 수 있으며 기본값은 100MB입니다
Binlog::Binlog(const std::string& binlog_path, const int file_size)
1.1 binlog 파일 디렉터리를 생성합니다.
1.2 로그 디렉터리에 매니페스트 파일이 있는지 확인하세요. 존재하지 않는다면 새로 만드세요.
1.3 매니페스트 파일에 따라 Version 클래스를 초기화합니다.
1.4 매니페스트의 filenum에 따라 해당 로그 파일을 찾고, pro_offset에 따라 파일 추가 위치를 찾고, 로그 포인터를 초기화하고, 로그 내용 길이와 블록 블록 수를 기록합니다.
현재 로그 생성 상태 업데이트
//pro_num: 로그 파일 번호
//pro_offset: 로그 파일 오프셋
//전체 동기화가 필요한 경우 슬레이브 인스턴스에 해당하는 binlog 정보를 업데이트하는 데 사용됩니다
상태 Binlog::SetProducerStatus(uint32_t pro_num, uint64_t pro_offset)
2.1 write2file0을 삭제합니다.
2.2 write2file+pro_num을 삭제합니다.
2.3 새로운 write2file+pro_num 파일을 생성하고, pro_offset 공백을 채우고, version->pro_num을 pro_num으로, version->pro_offset을 pro_offset으로 초기화하고, 매니페스트 파일로 새로 고칩니다.
2.4 현재 파일 크기와 block_offset을 초기화합니다.
현재 로그 생성 상태 업데이트
//filenum: 현재 로그 번호
//pro_offset: 현재 로그 오프셋
상태 Binlog::GetProducerStatus(uint32_t* 파일 번호, uint64_t* pro_offset)
3.1 버전에서 pro_num 및 pro_offset을 읽고 반환합니다.
제작일지
//넣기->생산->물리적 기록 방출
상태 Binlog::Put(const std::string &item)
4.1 현재 로그 파일이 자르기 조건에 맞는지 확인하고, 그렇다면 자르세요.
4.1.1 pro_num은 1씩 증가하고 새 로그 파일을 초기화합니다. version->pro_num=pro_num, version->pro_offset = 0, binlog->filesize = 0, binlog->block_offset = 0.
4.1.2 현재 블록의 남은 크기가 4.1.3 Produce는 항목 크기가 kBlockSize를 초과할 때 여러 EmitPhysicalRecord를 수행하여 binlog 파일에 들어가는 모든 항목 데이터를 완료할 수 있도록 하는 루프입니다. 루프가 정상적으로 종료되는 조건은 left==0입니다. 4.1.3.1 left 4.1.3.2 left > avail인 경우 항목을 저장하는 데 여러 블록이 필요하다는 의미이며 처음으로 Type=kFirstType이고 EmitPhysicalRecord가 여러 번 호출됩니다. 4.1.3.3 왼쪽 > 사용 가능하고 EmitPhysicalRecord가 처음이 아닌 경우 Type=kMiddleType이면 EmitPhysicalRecord를 여러 번 호출합니다. 4.1.4물리적 레코드 방출. 4.1.4.1 RecordHeader(3바이트 길이 + 4바이트 시간 + 1바이트 유형)를 연결하고 데이터를 쓰고 block_offset 및 pro_offset을 업데이트합니다. 소비 로그 //scratch: 소비 결과는 완전한 redis cmd를 반환합니다 //Consume->ReadPhysicalRecord, ReadPhysicalRecord는 매번 완전한 레코드를 읽으며 여러 레코드가 완전한 redis cmd를 구성합니다 상태 PikaBinlogSenderThread::Consume(std::string &scratch) 5.1Consume은 ReadPhysicalRecord를 여러 번 호출할 수 있는 루프입니다. 루프 종료 조건은 읽기 Record_type==kFullType 또는 Record_type==kLastType입니다. 5.1.1 kBlockSize-last_record_offset_ <= kHeaderSize 읽기가 블록의 끝을 읽었고 데이터로 채워졌음을 의미하는 경우 건너뜁니다. 5.1.2 데이터 읽기, last_record_offset_, con_offset 업데이트. 위 내용은 Pika: 대용량 Redis 스토리지에 적용 가능한 시나리오 보완의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!