ZooKeeper 트 랜 잭 션 로그 기록 기 SyncRequestProcessor

4981 단어
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 에 기록 해 야 합 니 다. 이 기록 이 디스크 에 동기 화 되 는 것 을 보장 하 는 것 은 아 닙 니 다.따라서 적절 한 시기 에 캐 시 된 트 랜 잭 션 로 그 를 디스크 에 저장 하 는 것 이 필요 합 니 다.
    프로그램의 설계 에서 작가 가 이 고려 에서 두 가지 시 기 를 선택 하여 이 일 을 하 는 것 을 볼 수 있 을 것 이다.
  • 요청 이 없 을 때 (즉, 한가 할 때)
  • 계속 바 쁘 면 toFlush 대기 열 이 일정 수량 (1000) 에 도달 하면 대량 동기 화
  • 주의 점
  • 데이터 스냅 샷 은 트 랜 잭 션 로그 기록 을 할 때마다 ZooKeeper 는 현재 데이터 스냅 샷 이 필요 한 지 확인 합 니 다.이론 적 으로 snapCount 차 사 무 를 수행 한 후에 데이터 스냅 샷 이 시 작 됩 니 다. 그러나 데이터 스냅 샷 이 ZooKeeper 가 있 는 기계 의 전체적인 성능 에 영향 을 미 치 는 것 을 고려 하여 ZooKeeper 클 러 스 터 에서 모든 기계 가 같은 시간 에 데이터 스냅 샷 을 하 는 것 을 피해 야 합 니 다.따라서 ZooKeeper 는 구체 적 인 실현 에서 이 전략 에 따라 엄 격 히 집행 하 는 것 이 아니 라 '과반 랜 덤' 전략 을 취한 다. 즉, 다음 과 같은 조건 에 부합 되 는 데이터 스냅 샷 을 한다.
    logCount > (snapCount / 2 + randRoll)
    그 중에서 logCount 은 현재 기 록 된 사무 로그 수량 을 대표 하고 randRoll1 ~ snapCount/2 간 의 랜 덤 수 이다.따라서 위의 조건 은 우리 가 설정 한 snapCount100000 이면 ZooKeeper 는 50000 ~ 100000 번 의 트 랜 잭 션 로그 기록 후 데이터 스냅 샷 을 한 번 찍 는 것 과 같다.
  • 트 랜 잭 션 로그 파일 전환 이 상기 조건 을 만족 시 킬 때 ZooKeeper 는 데이터 스냅 샷 을 시작 합 니 다.우선 트 랜 잭 션 로그 파일 을 전환 합 니 다.트 랜 잭 션 로그 파일 전환 이란 현재 트 랜 잭 션 로그 가 '가득 쓰기' 되 었 음 을 말 합 니 다. 새로운 트 랜 잭 션 로 그 를 다시 만들어 야 합 니 다.데이터 스냅 샷 을 한 번 할 때마다 트 랜 잭 션 로그 파일 을 다시 만 드 는 것 입 니 다.

  • 소스 코드
    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);
            }
        }
    }

    레 퍼 런 스
  • zookeeper 저장 의 실현 분석
  • Paxos 에서 ZooKeeper 분포 식 일치 성 원리 와 실천 서적
  • 좋은 웹페이지 즐겨찾기