ZooKeeper 멀티 서버 구성

 

·       Version : Zookeeper

 

주키퍼를 멀티서버로 구성하려면 서버에 멀티서버에 대한 정보를 추가해야 한다. 주피커 설치 디렉터리에서 conf/zoo.cfg 파일에 아래와 같이 정보를 입력 한다.

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper

clientPort=2181

 

server.1=192.168.1.1:2888:3888

server.2=192.168.1.2:2888:3888

server.3=192.168.1.3:2888:3888

 

zoo.cfg 파일에서 서버 만큼 server.x=IP:Port:Port 입력한다. server 예약어이며, x 서버를 식별하는 ID 숫자를 입력한다. IP 서버의 IP 입력하고, 첫번째 포트는 리더에 접속하기 위한 포트이며, 두번째 포트는 리더를 선출하는데 사용되는 포트이다. 위에서 생성한 설정 파일을 서버에 복사하고, 서버의 데이터 디렉터리에 myid 라는 파일을 만들어서 해당 서버의 아이디를 입력한다. 아래 예제는 서버1에서 데이터 경로가 /data/zookeeper 사용하였다.

vi /data/zookeeper/myid

1 #숫자 입력 종료

 

설정이 완료되고 서버에서 주키퍼 서버를 시작하면, 멀티서버 주키퍼 클러스터로 동작한다. 멀티서버 구성에는 실행되고 있는 서버의 수가 과반수(등록된 서버 + 1)/2) 이하이면 동작하지 않는다. 예를들어 클러스터가 3대일때, 2대의 서버 장애가 발생하면 서비스가 중지 된다. 아래 스크립트는 주키퍼 서버를 시작하는 명령어이다.

bin/zkServer.sh start

 

서버에서 주키퍼를 시작하면 첫번째 서버 시작시 오류 메시지가 나타나는데, 멀티서버로 설정된 주키퍼는 설정 파일에 있는 다른 서버에 접속해 리더 선출과정을 거쳐야 정상으로 작동되기 때문에 설정 파일에 등록된다른 서버를 시작하면 경고가 발생하지 않는다. 서버 메시지에서 “LEADING” 메시지가 표시된 서버가 리더로 선출된 서버이다.

 

아래 표는 주키퍼 환경 설정에 대한 속성과 설명이다.

속성

설명

clientPort

클라이언트로 요청을 받기 위한 포트

dataDir

메모리에 있는 데이터를 스냡샷으로 저장하는 디렉터리 경로

tickTime

주키퍼에서 사용되는 기본 시간 단위. 최소 세션타임아웃은 값의 2배이다.

dataLogDir

트랜잭션 로그를 저장하는 디렉터리. 특별한 설정을 하지 않으면 dataDir 저장. 성능상 다른 디스크의 디렉터리에 분리하는것이 좋다.

globalOutstandingLimit

큐가 많이 쌓이게 되면 메모리 부족으로 정상 작동하지 못하게 된다. 사이즈보다 많은 요청을 받지 못하도록 설정하는 값이며 기본값은 1000 이다.

preAllocSize

트랜잭션 로그 저장을 위해 미리 할당 받은 파일 사이즈. 기본값은 64MB 스냅샷을 자주 만들경우 값을 줄여서 사용한다.

snapCount

트랜잭션 회수가 snapCount 이상되면 메모리 내용을 스냅샷 파일로 저장하고 새로운 트랜잭션 파일을 만든다.

traceFile

설정이 켜져 있으면 클라이언트 요청을 traceFile.year.month.day 형태의 파일명에 저장한다. 주로 디버그 용도로 활용하며 설정이 켜져 있으면 오버헤드가 발생한다.

maxClientCnxns

클라이언트로 부터 동시에 접속할 있는 연결 수를 지정. 연결수는 클라이언트 IP 개수이며, 기본값은 10이며 0 무제한이다.

clientPortBindAddress

서버의 네트워 카드 IP 여러개 일때, 클라이언트가 접속할 서버의 IP주소나 호스트명을 지정한다. 기본값은 모든 IP 주소, 네트워크 카드에 접속 가능하다.

minSessionTimeout

최소 세션 타임아웃이며 단위는 밀리세컨드 (ms)이다. 기본값은 tickTime *2 이다.

maxSessionTimeout

최대 세션 타임아웃이며 단위는 밀리세컨드(ms)이다. 기본값은 tickTime *20 이다.

electionAlg

리더를 선출하는 알고리즘. 기본값은 3이다.
0 : UDP 기반의 기본 리더 선출

1 : UDP 기반의 비인증 빠른 리더 선출(FastLeaderElection)

2 : UDP 기반의 인증 빠른 리더 선출

3 : TCP 기반의 빠른 리더 선출

initLimit

초기에 팔로워가 리더에 접속하거나 데이터를 동기화 시키기 위한 시간으로 단위는 tickTime 이며 initLimit * tickTime으로 계산된다.

leaderServes

클라이언트의 요청을 리더가 받을 것인지에 대한 설정 기본값은 yes 이다. 쓰기 연산이 많은 경우, 리더가 클라이언트 요청을 받게되면 쓰기 연산에 대한 처리와 클라이언트로 부터의 읽기,쓰기 연산을 동시에 하게 되면서 많은 오버헤드가 발생한다. 경우 no 설정하는 것이 좋다.

server.x=ip:port:port

멀티 서버를 구성할 경우 서버 목록 지정. 앞의 포트는 리더에 접속하기 위한 포트이며, 번째는 리더를 선출하는 포트이다.

syncLimit

Sync 수행하는 시간으로 Tick기준이다. 시간동안 sync 안되면 해당 팔로워는 클러스터에서 제외된다.

group.x=id[:id]

계층적 정족수를 설정한다 x 그룹 아이디로 숫자 값을 설정한다. = 이후에는 그룹에 포함될 서버 아이디를 입력하며 구분자는 : 이다.

weight.x= n

서버간 정족수 투표를 할때 서버의 가중치를 설정. X 서버 아이디이며 n 가중치 값을 설정한다. 기본값은 1이다.

 

주키퍼는 자바로 개발되었으며 JVM(Java Virtual Machine)환경에서 운영된다. 그래서 JVM 대한 설정도 고려해야한다. JVM GC(Garbage Collection) 수행할때 모든 스레드가 멈추게 되는 경우도 있다. GC 수행되는 모든 모든 스레드가 동작하지 못하게 되면 예기치 못한 타임아웃이 발생하고, 클라이언트, 서버 모두 정상적인 상황임에도 세션을 유지하지 못하는 상태가 발생한다. 주키퍼 서버를 실행할 GC옵션을 아래와 같이 설정하며 GC 수행중에도 스레드가 동작할 있게 한다.

-XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC

 

외에도 성능이 저하되지 않도록 JVM 메모리 스왑이 발생하지 않도록 해야한다.

 

[참고자료]

·       Clustered (Multi-Server) Setup : https://zookeeper.apache.org/doc/r3.3.2/zookeeperAdmin.html#sc_zkMulitServerSetup

·       How To Install and Configure an Apache ZooKeeper Cluster on Ubuntu 18.04 : https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-an-apache-zookeeper-cluster-on-ubuntu-18-04

·       16 Tuning JVM Garbage Collection for Production Deployments : https://docs.oracle.com/cd/E40972_01/doc.70/e40973/cnf_jvmgc.htm#autoId0

 

 

 

2020-05-16 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, 주키퍼, Zookeeper, 분산 코디네이션

SRE (Site Reliability Engineering) 역할

 

SRE(Site Reliability Engineering) 조직이 해당 시스템, 서비스 제품에서 적절한 수준의 안정성을 달성하도록 지원하는 엔지니어링 분야로,  실패 비용을 줄임으로써, 신속하게 올바른 방향으로 이동할 있도록 지원한다. 과정에서 SRE 자동화, 수치화, 프로세스화를 진행한다. 특히 SRE 관점은 근본적인 문제는 소프트웨어의 문제라고 정의하고 접근한다. SRE 하는 일은 크게 5가지 정도로 나누어 있다.

 

[Metric & Monitoring]

모니터링 지표를 정의하고, 정의된 지표를 모니터링 시스템으로 구성한다. 인사이트를 통해 시스템이 안정적인 상황과 또는 장애가 나는 지표는 무엇인지, 왜인지? 그리고 이러한 지표를 어떻게 개선할 있는지를 고민한다.기본적으로 SRE에서 가장 중요한 부분은 모든것을 데이타화하고, 의사결정을 데이타를 기반으로 한다는 것이다.

 

[Capacity Planning]

시스템을 운영하는데 필요한 하드웨어 리소스(서버, CPU,메모리,디스크,네트워크 ) 확보하는 작업을 진행한다. 수집된 데이터를 통해 서비스 안정성에 필요한 하드웨어를 미리 예측하는 것이다. SRE 엔지니어는 자원 활용의 효율성 측면에서 소프트웨어의 성능을 그리고 안정성 측면에서 소프트웨어의 안정성을 함께 있어야 한다.

 

[Change Management]

대부분의 시스템 장애의 원인은 대략 70% 시스템에 변경을 주는 경우에 발생한다. SRE 점진적인 배포와 변경을 관리한다.배포 또는 장애시 빠르고 정확하게 해당 문제를 찾아낼 있도록 해야하며 마지막으로 문제가 발생하였을때 빠르게 롤백할 있도록 해야한다.

 

[Emergency Response]

일반적으로 장애 복구 단계에서 사람이 직접 매뉴얼로 복구를 하게 되면 장애 복구 시간이 많이 소요된다. 사람이 컨트롤을 하되 가급적이면 단계는 자동화 되는게 좋으며, 사람이 해야 하는 일은 되도록이면 메뉴얼화 되어 있는 것이 좋다. SRE 자동화 뿐만아니라 메뉴얼, 프로세스를 함께 제공한다.

 

[Culture]

운영에 필요한 작업뿐만 아니라 SRE 문화를 전반적으로 만들고 지켜나가는 작업을 진행한다.  데이타에 기반한 합리적인 의사결정과 서로 비난하지 않고 장애 원인을 분석하고 이를 예방하는 포스트모템 문화, 그리고 책임을 나눠가지는 문화를 장려하고 선순환 구조를 만들 있도록 해야한다.

 

[참고자료]

·       IO116-Improving Reliability with Error Budgets, Metrics, and Tracing in Stackdriver : https://drive.google.com/file/d/1iOMaYIwlUBiGoG2mf8MFzl3EHy5xGJpq/view

·       Search Reliability Engineering (부제: 지진에도 흔들리지 않는 네이버 검색시스템) : https://www.slideshare.net/deview/216sresearchreliabilityengineering

·       네이버 검색의 SRE 시스템 : https://d2.naver.com/helloworld/2047663

·       SRE(사이트 안정성 엔지니어링) 소개 : https://docs.microsoft.com/ko-kr/learn/modules/intro-to-site-reliability-engineering/

 

 

 

2020-05-13 / Sungwook Kang / http://sungwookkang.com

 

SRE, Site Reliability Engineering, DevOps, 사이트안정성엔지니어링, 사이트신뢰성엔지니어링, 시스템운영, SiteReliability, 서비스운영, 모니터링자동화, 시스템운영자동화

ZooKeeper 리더선출과 데이터 ACID 정책

 

·       Version : Zookeeper

 

주키퍼를 사용하여 분산 시스템을 관리할 경우 주키퍼는 반드시 멀티 서버로 운영해야한다. 멀티서버로 운영할 경우 네트워크 단절, 트랜잭션 타임아웃등의 상황에 대비해야한다. 특히 일부 주키퍼 서버 장애발생시 해당 서버에 접속된 클라이언트의 세션에 대한 처리, 장애복구 서버간 데이터 동기화 등이 고려되어야 한다. 주키퍼는 이러한 문제를 자체적으로 해결하기 때문에 마스터 서버 구성시 주키퍼를 사용함으로써 상대적으로 쉽게 해결할 있다.

 

주키퍼를 멀티서버로 설치하면 모든 서버는 동일한 데이터를 가지고 있다. 클라이언트는 모든 서버에 접속해서 읽기, 쓰기 요청을 보낼수 있다. 읽기 연산은 모든 데이터가 동기화 되어 있기 때문에 자체 서버에서 제공할 있지만, 쓰기연산은 특정 서버가 마스터 역할을 수행하면서 쓰기 작업이 정상적으로 수행되었는지 확인할 필요가 있다. 이러한 역할을 하는 서버를 리더(leader)라고 한다.

주키퍼는 클러스터내에서 자동으로 리더를 선출한다. 클러스터가 재시작되거나 장애가 발생하면 자동으로 리더를 선출하며 리더를 선출하는 방법 순서는 아래와 같다.

1.       서버는 자신의 현재 트랜잭션ID(zxid) 자신을 후보자로 지명해 모든 서버로 전송

2.       서버는 트랜잭션 아이디를 받은 자신이 최대값이 아니면 다시 최대값을 갖고 있는 서버를 후보자로 지명하여 모든 서버에 전송

3.       과반수 이상의 서버로부터 후보자로 지명된 서버는 리더로 선출

4.       다른 서버는 팔로워(follower) 동작

 

분산처리 시스템에서 ACID 속성중 정합성(Consistency) 독립성(Isolation) 보장하는것은 쉽지 않다. 주키퍼는 데이터 저장시 아래와 같은 사항을 보장한다.

·       순차적 정합성(Sequential Consistency) : 주키퍼 클러스터에 저장되는 데이터는 강한 정합성(Strong Consistency) 보장하지 않고, 이벤추얼 정합성(Eventual Consistency) 보장한다. 이벤추얼 정합성은 일정 시간이 지나면 정합성이 맞춰지는 속성이다. 특정 클라이언트로부터 데이터 저장에 대한 요청이 있을때 , 분산되어 있는 주키퍼 서버에 반영되는 순서는, 클라이언트에서 전송된 요청 순서대로 처리되는것을 보장한다.

·       원자성(Atomic) : 전체가 수행되거나 전체가 실패되는 행위로, 부분적인 성공은 존재하지 않는다.

·       단일 이미지 제공 (Single System Image) : 클라이언트는 어떤 주키퍼 서버에 접속하더라도 동일한 데이터 뷰를 제공 받는다.

·       안정성 (Reliability) : 주키퍼에 저장된 데이터는 클라이언트의 명시적인 호출에 의해 수정되지 않는한 영속성을 가지고 있다.

 

 

 

2020-05-13 / Sungwook Kang / http://sungwookkang.com

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, 주키퍼, Zookeeper, 분산 코디네이션

Zookeeper 세션(Session)

 

·       Version : Zookeeper

 

주키퍼에서 세션(session)  주키퍼 서버와 클라이언트의 연결을 의미한다. 세션 상태는 5가지가 있다.

·       Connecting : 클라이언트가 주키퍼 서버와 연결을 시도하고 있는 상태이다.

·       Connected : 서버와 연결된 상태로, z노드에 연산을 수행할 있는 상태이다.

·       Closed : close() 메소드에 의해 명시적으로 연결을 종료했거나, 세션 타임아웃, 인증 실패 등으로 서버와 연결이 종료된 상태

·       Disconnected : 시스템 장애, 네트워크 장애등으로 서버와의 접속이 끊긴 상태이다. Disconnected 상태에서는 클라이언트가 자동으로 파라메터로 받은 서버 대에 다시 접속을 시도하며, 이때. 서버 접속시 발급받은 64비트의 세션 아이디를 재접속시 사용하여 세션값을 계속 유지 있다. Disconnected 상태에서는 임시노드는 삭제되지 않는다.

·       Session Expired : 세션 타임아웃 시간동안 세션 유지 요청이 없으면 세션을 무효화한다. 세션 타임아웃 시간을 너무 짧게 설정하면 세션이 너무 자주 끊겨 임시 노드가 삭제되는 문제가 있으며, 타임 아웃 시간이 너무 길면 Session Expired 상태에 대한 이벤트를 받는데 오래 걸린다.

 

 

주키퍼는 세션 연결과 읽기 연산시 이벤트를 받을 있는 와처(watcher) 설정하는 기능을 제공한다. 와처는 세션의 상태가 변경되었거나 관심 있는 노드의 상태가 변경되었을때 클라이언트가 이벤트를 받아 처리할 있게 하는 기능을 제공한다. 와처는 옵저버(Observer) 패턴을 취하고 있어 이벤트 대상에 콜백 객체를 등록하고 조건에 만족한 이벤트가 발생하면 콜백 객체로 등록된 와처를 호출하는 방식을 취한다.

 

클라이언트가 주키퍼 서버에 연결되면 Peer-To-Peer FIFO 네트워크 채널을 생성한다. 네트워크 채널은 세션이 종료될 때까지 유지한다. , 한번 생성된 소켓은 계속 사용한다. 특정 z노드에 와처를 등록하면 클라이언트에서는 메모라에 와처 객체를 등록한다. 주키퍼 서버로는 z노드의 패스와 클라이언트 호스트 정보를 전달하고, 서버에는 z노드와 와처를 등록한 클라이언트 목록을 가지고 있으며 z노드 상태가 변경되서을때 와처 목록에 있는 클라이언트로 변경 내역을 전송한다. 주키퍼 와처는 한버 이벤트를 받으면 등록된 와처는 삭제된다. 따라서 이벤트를 계속 받기 위해서는 와처를 계속 등록해야 한다.

 

[참고자료]

·       ZooKeeper Sessions : https://zookeeper.apache.org/doc/r3.3.5/zookeeperProgrammers.html#ch_zkSessions

·       ZooKeeper Watches : https://zookeeper.apache.org/doc/r3.3.5/zookeeperProgrammers.html#ch_zkWatches

 

 

 

2020-05-12 / Sungwook Kang / http://sungwookkang.com

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, 주키퍼, Zookeeper, 분산 코디네이션

+ Recent posts