ZOOKEEPER #3 (기본과 주의)

[단어 정의]
– 앙상블(Ensemble) : 서버의 집합
– 쿼럼(Quorum) :
설명1) 주키퍼가 올바르게 동작하는데 필요한 주키퍼의 최소 숫자
설명2) 앙상블이 요청을 처리하기에 충분한 주키퍼 서버를 가지고 있을 때 이 집합
ex) 5대의 앙상블/ 3대의 쿼럼
– 스플릿브레인
시스템이 두 부분 이상이 독립적으로 진행되어 시스템이 일관되지 않게 동작하는것
– 주키퍼핸들 : 주키퍼 세션을 의미한다 세션이 살아있는 동안 핸들은 유효하며,
핸들이 종료되면 주키퍼 클라이언트 라이브러리는 세션을 종료하기 위해 주키퍼 서버들에게 알린다
Zookeeper(String connectString, int sessionTimeout, Watch watcher)로 핸들을 생성한다.
ex) 5대에 쿼럼이 2대일 경우 2대는 /z를 알지만 3대는 /z를 모를경우?

[요청의 종류]
– 읽기요청 (exists, getData, getChildren) 은 요청을 받은 주키퍼에서 직접 처리
– 변경요청 (create, delete, setData)는 리더로 전달하고,
리더는 ‘트랜잭션’이라 부르는 상태 변경 사항을 생성해 요청을 처리
ex) /z setData요청 에서 트랜잭션은 ‘/z의 새로운 데이터 와 /z의 새로운 버전 총 2가지’
이 2가지는 항상 원자적으로 수행되어야 하며, 아닐 경우 문제 발생

[트랜잭션]
– 리더가 트랜잭션을 생성할때 트랜잭션ID(zxid)라는 식별자를 부여한다.
– 하나의 zxid에는 에퍽(epoch), 카운터(counter) 각각 32bit 씩 long(64bit)로 이루어진다.

[리더의 선출]
https://issues.apache.org/jira/browse/ZOOKEEPER-1153
– Election 인터페이스의 구현체 3개 중 2개 LeaderElection , AuthFastLeaderElection가 3.4.0에서 deprecated
– 현재 보는 버전(3.4.8)에서는 FastLeaderElection 사용중

– 앙상블에 의해 선출되고, 하나의 리더는 장애가 나기전까지 계속 리더이다.
– 서버의 최초 상태는 LOOKING (새로운 리더를 선출하거나, 이미 존재하는 리더는 찾는 상태)
– QuorumPeer.run 에서 시작한하고, LOOKING 일때 startLeaderElection 를 호출하는걸 확인 할 수 있다.
– LEADING : 투표에 의해 리더가 되면 이 상태로 진행하고, 나머지는 FOLLOWING 상태로 진입한다.

[특별한 데이터 노드 /zookeepr]
– 어플리케이션은 /zookeeper을 쓰면 안된다. 주키퍼의 사용이 예약된 곳이다.
– /zookeeper/quota

[주키퍼의인증 ACL]
– 중요!!! : 부모노드의 권한 정보를 자식이 상속받지 않는다. 그래서 znode를 생성할 때마다 접근권한을 설정해야한다.
– 주키퍼는 각 znode접근에 대해 클라이언트에서 전달된 권한 정보를 확인함으로써 보안을 수행한다.
– 인증 추가 addAuthInfo(String schema, byte[] auth) 를 수행한다.
– 언제든지 인증을 추가할 수 있지만 ‘일반적으로’ 주키퍼 핸들을 생성한 직후에 추가한다.
– 종류1) OPEN_ACL_UNSAFE ; ‘anyone’을 권한 정보
종류2) ‘super’ DigestAuthenticationProvider에 보면 new Id(“super”)를 확인 할 수 있다. SHA1에 의해 digest생성
종류3) digest
종류4) passwd_digest
– kerberos 사용가능
– 커스텀 가능 AuthenticationProvider 를 구현하고 zookeeper.authProvider 설정을 수정하면된다
[세션의 만료]
– 일반적으로 세션의 만료는 클라이언트가 요청한 작업에 장애가 발생했을 경우이다 하지만 그 뿐 아니라
– GC, 네트워크 문제등의 이슈로 발생할 수 있다.
– 중요!!! : 세션 만료의 경우 클라이언트는 주키퍼의 상태가 처음과 다르게 변할 수 있다는 점과, 요청 일부는 수행이 안될 수도 있다는 점을 꼭 기억해야한다.
[ znode의 버전 ]
– 재생성 되면 버전은 초기화 된다! znode의 버전을 중요하게 사용하는 경우라면 항상 기억할 이슈이다.

[연결이 끊어졌을 때 ]
– 세션이 살아 있는 동안에는 작업 순서에 대해 순서를 보장하지만, 장애상태에서는 달라 질 수 있다.
– 미처리된 요청은 취소함 동기호출은 예외 발생, 비동기는 콜백을 호출
– 취소됨을 알려만 주지 재처리 안하기 때문에 취소된 작업은 클라이언트에서 반드시 처리애햐한다. (다시할지 안할지)
– 절대로! 주키퍼가 뭘 해주지는 않는다.
– 중요! 취소되었다고 재요청을 할경우 무한 요청에 빠질수 있다. 재시도 횟수를 두거나, 핸들을 닫던가 해야한다.

[데이터의 제한]
– Znode의 데이터 제한은 1mb
– 옵션에 의해 수정가능하지만 별로…

[애플리케이션의 주키퍼 서버 임베딩]
– 주키퍼는 고가용성을 보장하지만, 애플리케이션에 임배딩하는것은 이 장점을 버리는 것과 같다. 하나가 죽으면 같이 죽을 확률이 높기 때문이다.
– App안에서 주키퍼 서버 자체를 만드는 것은 비추천하지만, 만약 필요로 하다면 주키퍼 테스트를 참고하라

Zookeeper #1

* 주키퍼의 Origin
 – Yahoo 에서 개발
 – Pig 처럼 많인 프로젝트가 동물 이름이었고, 이러한 시스템들은 동물원의 동물과 같다고 느낌 -> 사육사(Zookeeper)

* 주키퍼가 사용된 예
 – HBase : 클러스터 마스터 선출과 가용 서버들의 목록을 저장 / 클러스터 메타데이터 관리
 – Kafka : 장애 감지/ 토픽 발견/ 토픽 생성 소모 상태를 관리
 – Solr : 솔라클라우드에서 클러스터의 메타데이터 저장, 업데이트 관리
 – Facebook message : 샤딩/ 장애복구/ 서비스발견을 관리
– Druid :  내부 통신에 이용

* 주키퍼 모드
 – Standalone : 단독 서버, 복제 안됨
 – quorum(쿼럼)

* Znode
 – 용량제한 1MB
 – ACL(접근권한관리)를 할 수 있다
 – 주키퍼는 모든 데이터를 메모리에서 관리하기 때문에 Znode역시 메모리에 올라간다
 – child 또는 바이트 배열의 데이터를 저장한다

* Znode Mode
 – Persistent Node : 명시적인 삭제 명령(delete)이 있기 전까지 계속 유지되는 Node
 – Ephemeral Node : Node를 생성한 ‘세션’ 이 유효한 동안에만 유지되는 Node. Ephemeral 는 child znode를 가질수 없다.
 – Sequence Node : (위의 2개의 노드는 각각 이 타입을 사용 할 수 있다)
                   생성지 Sequence가 자동으로 붙는 Node (ex task-00000001) 유일한 이름을 보장 / 생성 순서 확인 가능

* Watch
 – 1회성 작업이다. 계속 노티를 받으려면 클라이언트에서 매번 새로운 watch를 설정해야한다.
   : so, 알림을 받고 새로운 watch를 등록하려는 순간에 새로운 변경사항이 발생 할 수 있다.
         이 다음 새로 watch를 등록하면서 값을 읽기 때문에 놓치지는 않는다.
 – 클라이언트가 감시하는 znode의 변경 사항의 ‘순서’를 보장해준다
 – 데이터 변경/ Child변경 등에 따라 다른 종류의 알림을 생성한다.

* 쿼럼의구성
 – 1. server.1=127.0.0.1:2222:2223
   server.n각 항목은 서버 n이 사용하는 주소, 포트를 지정한다.3개의 필드
   첫번째 필드는 서버 주소, 2,3번째 필드는 쿼럼 통신, 리더 선출에 사용하는 TCP포트이다.
 – 서버가 시작할때 주키퍼는 data 디렉토리의 myid 파일에 있는 내용을 읽어서 자신의 ID를 인식한다