ZooKeeper 트 랜 잭 션 로그 기록 기 SyncRequestProcessor
SyncRequestProcessor
는 ZooKeeper 의 핵심 스 레 드 ZooKeeperCriticalThread
로 서 ZooKeeper 요청 처리 체인 의 트 랜 잭 션 로그 기록 프로세서 입 니 다. 주로 트 랜 잭 션 요청 을 트 랜 잭 션 로그 파일 에 기록 하 는 동시에 ZooKeeper 를 터치 하여 데이터 스냅 샷 을 진행 합 니 다.데이터 구조
LinkedBlockingQueue<Request> queuedRequests
: 이전 RequestProcessor
호출 nextProcessor.processRequest(request)
은 request 를 이 대기 열 에 배열 하여 처 리 를 기다 리 고 있 습 니 다.Thread snapInProcess
: 스냅숏 스 레 드 를 책임 지고 데이터 스냅숏 과정 이 ZooKeeper 의 메 인 절차 에 영향 을 주지 않도록 합 니 다. 데이터 스냅숏 을 위 한 별도의 비동기 스 레 드 를 만들어 야 합 니 다.LinkedList<Request> toFlush
: 지속 화 과정 에서 그룹 제출 (Group Commits) 을 사용 하여 디스크 I / O 작업 을 최적화 합 니 다.하나의 장면 을 상상 합 니 다. 클 라 이언 트 가 대량의 업무 요청 을 할 때 매번 요청 을 쓸 때마다 디스크 에 동기 화하 면 성능 에 문제 가 생 길 수 있 습 니 다.디스크 에 오래 지속 되 어야 하 는 Request 를 저장 하기 위해 이 링크 를 설정 합 니 다.int snapCount
: 기본 값 은 100000 입 니 다. ZooKeeper 가 snapCount
번 의 트 랜 잭 션 로그 기록 을 한 후에 데이터 스냅 샷 을 하 는 것 을 의미 합 니 다.toFlush
및 flush 타 이 밍toFlush
대기 열 은 저장 요청 에 사용 할 수 있 으 며 읽 거나 쓸 수도 있 습 니 다.ZooKeeper 는 스 레 드
SyncRequestProcessor
를 사용 하여 요청 을 처리 하기 때문에 이 스 레 드 는 합 리 적 인 작업 을 해 야 합 니 다. 그렇지 않 으 면 전체적인 성능 에 영향 을 줄 수 있 습 니 다.클 라 이언 트 가 읽 기 요청 을 한다 면 flush 를 진행 할 필요 가 없습니다. 그러나 요청 을 쓰 려 면 요청 을 log 에 기록 해 야 합 니 다. 이 기록 이 디스크 에 동기 화 되 는 것 을 보장 하 는 것 은 아 닙 니 다.따라서 적절 한 시기 에 캐 시 된 트 랜 잭 션 로 그 를 디스크 에 저장 하 는 것 이 필요 합 니 다.프로그램의 설계 에서 작가 가 이 고려 에서 두 가지 시 기 를 선택 하여 이 일 을 하 는 것 을 볼 수 있 을 것 이다.
snapCount
차 사 무 를 수행 한 후에 데이터 스냅 샷 이 시 작 됩 니 다. 그러나 데이터 스냅 샷 이 ZooKeeper 가 있 는 기계 의 전체적인 성능 에 영향 을 미 치 는 것 을 고려 하여 ZooKeeper 클 러 스 터 에서 모든 기계 가 같은 시간 에 데이터 스냅 샷 을 하 는 것 을 피해 야 합 니 다.따라서 ZooKeeper 는 구체 적 인 실현 에서 이 전략 에 따라 엄 격 히 집행 하 는 것 이 아니 라 '과반 랜 덤' 전략 을 취한 다. 즉, 다음 과 같은 조건 에 부합 되 는 데이터 스냅 샷 을 한다. logCount > (snapCount / 2 + randRoll)
그 중에서 logCount
은 현재 기 록 된 사무 로그 수량 을 대표 하고 randRoll
은 1 ~ snapCount/2
간 의 랜 덤 수 이다.따라서 위의 조건 은 우리 가 설정 한 snapCount
이 100000
이면 ZooKeeper 는 50000 ~ 100000
번 의 트 랜 잭 션 로그 기록 후 데이터 스냅 샷 을 한 번 찍 는 것 과 같다.소스 코드
int logCount = 0;
int randRoll = r.nextInt(snapCount/2); // 0~snapCount/2
while (true) {
Request si = null;
if (toFlush.isEmpty()) {
si = queuedRequests.take(); // toFlush , flush,
} else {
si = queuedRequests.poll(); // ,
if (si == null) { // queuedRequests , toFlush , ZooKeeper , flush
flush(toFlush);
continue;
}
}
if (si == requestOfDeath) {
break;
}
if (si != null) {
if (zks.getZKDatabase().append(si)) { // si
logCount++;
if (logCount > (snapCount / 2 + randRoll)) { // ,
randRoll = r.nextInt(snapCount/2);
zks.getZKDatabase().rollLog(); //
if (snapInProcess != null && snapInProcess.isAlive()) {
LOG.warn("Too busy to snap, skipping");
} else {
snapInProcess = new ZooKeeperThread("Snapshot Thread") { //
public void run() {
try {
zks.takeSnapshot();
} catch(Exception e) {
LOG.warn("Unexpected exception", e);
}
}
};
snapInProcess.start(); // ZooKeeper ,
}
logCount = 0;
}
} else if (toFlush.isEmpty()) { // ( ) toFlush
// , ,
// ???
if (nextProcessor != null) {
nextProcessor.processRequest(si);
if (nextProcessor instanceof Flushable) {
((Flushable)nextProcessor).flush();
}
}
continue; // nextProcessor si , toFlush
}
toFlush.add(si);
if (toFlush.size() > 1000) { // 1000, flush
flush(toFlush);
}
}
}
레 퍼 런 스
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.