[카프카 핵심 가이드] Chatper 2. 카프카 설치와 구성하기
2019-04-30
제일 먼저 할 일
운영체제 선택하기
이 책에서는 리눅스 운영체제를 기준으로 한다.
자바 설치하기
JDK(Java Development Kit)을 찾아 설치한다.
주키퍼 설치하기
주키퍼는 카프카 배포판에 포함되어 있다.
주키퍼에 클라이언트와 카프카 클러스터에 관한 메타데이터를 저장한다.
주키퍼 앙상블
주키퍼의 클러스터를 앙상블(ensemble)이라고 하며, 하나의 앙상블은 여러 개의 서버를 멤버로 가진다.
요청에 대한 응답을 빠르고 안정적으로 하기 위해 홀수 개의 서버를 멤버로 갖는다.
앙상블의 서버 중 과반수가 작동 가능하다면 언제든 요청 처리가 가능하다.
주키퍼 서버를 앙상블로 구성하려면 각 서버가 공통된 구성 파일을 가져야 한다. 또한 각 서버는 자신의 ID 번호를 지정한 myid 파일을 디렉터리에 가지고 있어야 한다.
카프카 브로커 설치하기
자바와 주키퍼를 설치 및 구성한 이후에 카프카를 설치한다.
브로커 구성
- 핵심 구성 옵션
- broker.id
- 정수로 된 식별자. 하나의 카프카 클러스터 내에서는 고유한 값이어야 한다.
- port
- zookeeper.connect
- log.dirs
- 로그 세그먼트 파일의 위치
- 카프카는 모든 메시지를 로그 세그먼트에 저장한다.
- 두 개 이상의 경로를 지정하면 해당 브로커가 모든 경로에 저장한다.
- num.recovery.threads.per.data.dir
- 카프카는 스레드 풀을 사용해서 로그 세그먼트를 처리한다.
- 기본적으로 로그 디렉터리당 하나의 스레드만 사용하는데, 디렉터리당 스레드 갯수를 지정할 수 있다.
- log.dirs에 지정된 로그 디렉터리마다 적용된다.
- auto.create.topics.enable
- 기본적으로 다음 경우에 브로커가 자동으로 토픽을 생성하게 해준다.
- 프로듀서가 토픽에 메시지를 쓸 때
- 컨슈머가 토픽의 메시지를 읽기 시작할 때
- 클라이언트에서 토픽의 메타데이터를 요청할 때
- false로 지정하면 직접 토픽 생성을 관리한다.
토픽의 기본 설정
- num.partitions
- 새로운 토픽의 파티션 개수
- 기본값은 1
- 브로커가 추가될 때 클러스터 전체에 걸쳐 메시지가 고르게 저장되도록 파티션 개수를 설정해야 한다.
- 보통 클러스터의 브로커 수와 같게 하거나 배수로 토픽의 파티션 개수를 설정한다.
- 토픽 처리량, 컨슈머 처리량 등을 예측해서 정한다.
- log.retention.ms
- 카프카가 얼마 동안 메시지를 보존할지 설정한다.
- log.retention.hours, log.retention.minutes 등이 있으나 작은 단위의 값이 우선순위가 높다.
- log.retention.bytes
- 메시지 보존 기간을 전체 크기 기준으로 설정한다.
- log.segment.bytes
- 로그 세그먼트를 닫고 새로 생성하는 기준 바이트 크기
- 로그 세그먼트가 닫혀야 만기가 되고, 만기가 되어야 보존 기준에 따라 보존된다.
- 디스크 쓰기 효율에 영향을 준다.
- log.segment.ms
- 로그 세그먼트를 닫는 기준 시간
- 디스크 쓰기 효율에 영향을 준다.
- message.max.bytes
- 메시지 최대 크기
- 이보다 큰 메시지를 전송하는 프로듀서에게는 에러를 보낸다.
하드웨어 선택
- 디스크 처리량
- 프로듀서 클라이언트 성능에는 브로커 디스크의 처리량이 가장 큰 영향을 준다.
- 디스크 용량
- 일정 기간에 얼마나 많은 메시지가 보존되어야 하는가에 따라 결정된다.
- 메모리
- 카프카 컨슈머가 읽는 파티션의 메시지는 시스템 메모리의 페이지 캐시에 최적화되어 저장된다.
- 네트워크
- 네트워크 처리량은 디스크 스토리지와 더불어 클러스터 크기 조정에 주된 요소다.
- CPU
클라우드에서 카프카 사용하기
AWS에서는 m4나 r3 타입의 인스턴스가 흔히 사용된다.
- m4는 더 긴 보존기간을 유지할 수 있다.
- r3는 디스크 처리량이 훨씬 더 좋다.
카프카 클러스터
브로커 개수
전체 데이터 크기 / 하나의 브로커가 저장 가능한 데이터 크기를 고려한다.
클러스터의 전체 처리 용량을 고려한다.
브로커 구성
모든 브로커의 구성 파일의 zookeeper.connect 매개변수의 설정값이 같아야 한다.
broker.id 매개변수에는 클러스터의 모든 브로커가 고유한 값을 가져야 한다.
복제를 제어하는 매개변수 등을 관리해야 한다.
운영체제 조정하기
- 가상 메모리
- 리눅스의 가상 메모리 시스템은 작업량에 따라 자동으로 메모리 사용을 조절한다.
- 그러나 처리량이 중요한 애플리케이션에서는 어떻게든 스와핑되는 것을 막아야 한다.
- 스와핑을 아예 하지 않는 것보다는 프로세스 중단 방지를 위해 vm.swappiness 값을 1과 같이 매우 낮은 값으로 설정하는 것이 좋다.
- 더티 페이지의 커널 처리 방법을 조정해 백그라운드 프로세스가 디스크에 써야 하는 더티 페이지의 수를 줄인다.
- vm.dirty_background_ratio의 값을 10보다 작게 설정한다. (대부분 5가 적합)
- 더티 페이지의 전체 크기는 60과 80사이가 바람직하다. (기본값은 20)
- 크기를 늘린 후에는 /proc/vmstat 파일을 확인해 더티 페이지 개수를 모니터링한다.
- 디스크
- 파일 시스템의 선택이 성능에 큰 영향을 줄 수 있다.
- 마운트 옵션은 noatime으로 설정하는 것이 좋다.
- atime(마지막 사용 시간)을 비활성화 하는 옵션
- 네트워크
- 리눅스 커널의 기본 설정은 대용량의 초고속 데이터 전송에 맞게 조정된 것이 아니다.
- 각 소켓의 송수신 버퍼 기본/최대 메모리량 설정 변경한다.
- 버퍼 기본 메모리량: net.core.wmem_deafult, net.core.rmem_default
- 버퍼 최대 메모리량: net.core.wmem_max, net.core.rmem_max
- TCP 소켓의 송수신 버퍼 크기도 설정한다.
- net.ipv4.tcp_wmem, net.ipv4.tcp_rmem
- 위의 소켓 설정값보다 클 수 없다.
- TCP 윈도우 크기 조정을 활성화 할 수 있다.
- net.ipv4.tcp_window_scaling의 값을 1로 설정
- net.ipv4.tcp_max_syn_backlog의 값을 늘리면 더 많은 수의 동시연결을 허용한다.
- net.core.netdev_max_backlog의 값을 늘리면 커널이 더 많은 패킷을 처리한다.
실제 업무 사용 시 고려사항
가비지 컬렉션 옵션
- G1 가비지 컬렉터는 정해진 중지 시간 내로 GC를 수행한다.
- MaxGCPauseMillis
- InitiatingHeapOccupancyPer
- 사용 중인 전체 힙의 비율을 지정하고, G1은 이 비율 이상에서 GC를 시작한다.
- 카프카 브로커는 위의 두 값을 더 작게 설정한다.
- 카프카 시작 스크립트는 G1대신 concurrent mark & sweep을 사용한다.
데이터센터 레이아웃
업무용으로 사용하려면 카프카 클러스터에 replica를 구성하는 것이 중요하다.
한 파티션의 replica가 같은 랙을 공유하지 않도록 한다.
- 각 브로커의 broker.rack 구성을 올바르게 설정한다.
하나의 클러스터에 속한 각 카프카 브로커는 서로 다른 랙에 설치되는 것이 가장 좋다.
주키퍼 공동 사용하기
단일의 카프카 클러스터에 주키퍼 앙상블을 사용하는 것은 바람직하지 않다.
컨슈머는 오프셋을 커밋하기 위해 주키퍼를 사용할 수 있다.
- 오프셋을 커밋하는 간격은 1분이다.
- 다른 컨슈머가 대체되어 메시지를 읽는데 시간이 필요하다.
- 많은 트래픽을 유발하므로 커밋 간격을 잘 선택해야 한다.
- 최신 버전에서는 주키퍼를 직접 사용하지 않아도 되므로 가급적이면 최신 버전을 사용한다.
주키퍼 앙상블에 부담을 많이 주면 다수의 브로커에 문제가 생길 수 있다.