카프카 설치 및 구성 옵션 톺아보기
핵심 구성 옵션
1. broker.id
•
모든 카프카 브로커가 가져야하는 식별자값
•
기본값은 0이지만 어떤 값도 가능
•
하나의 카프카 클러스터 내에서는 고유한 값이어야한다.
•
번호는 임의 선택 가능. 유지보수 작업중에 브로커 간에 숫자 바꾸는 것도 가능. 그러나 숫자 바꾸는건 권장하지 않음.
2. listeners
•
카프카의 실행에 사용되는 tcp 포트
•
기본값은 9092
- 어떤 포트번호로도 설정가능하지만 1024보다 작은 값으로 설정한다면 카프카가 root 권한으로 시작되어야하기에 바람직하지 않다.
3. zookeeper.connect
•
브로커의 메타데이터를 저장하기 위한 주키퍼의 위치
•
기본값은 localhost:2181/
•
[호스트이름:포트/경로] 의 형식으로 입력하면 된다.
◦
여기서 경로는 일반적으로 chroot 경로를 사용한다.
◦
다른 애플리케이션들과 충돌하지 않고 주키퍼 앙상블을 공유해서 사용
4. log.dirs
•
카프카는 모든 메시지를 로그 세그먼트 단위로 파일에 모아서 디스크 디렉토리에 저장한다.
•
여러 경로를 쉼표로 구분하여 지정가능
•
두개이상의 경로가 지정되면 해당 브로커가 모든 경로에 파티션을 저장한다.
•
사용빈도가 가장 적은 데이터를 교체하는 방식으로 한 파티션의 모든 로그 세그먼트를 같은 경로에 저장.
•
브로커가 새로운 파티션을 저장할때는 가장 적은 디스크 용량을 사용하는 경로가 아닌, 가장 적은 수의 파티션을 저장한 경로를 사용한다.
5. num.recovery.threads.per.data.dir
•
카프카는 스레드 풀을 사용해서 로그 세그먼트를 처리한다.
[ 스레드 풀을 사용하는 경우 ]
1) 브로커가 정상적으로 시작될때 : 각 파티션의 로그 세그먼트 파일을 열기 위해 사용
2) 장애 발생이후 다시 시작될 때 : 각 파티션의 로그 세그먼트를 검사하고 불필요한 부분을 삭제하기 위해 사용
3) 종료될때 : 로그 세그먼트 파일을 정상적으로 닫기 위해 사용
•
기본적으로 로그 디렉토리당 하나의 스레드만 사용한다.
•
스레드들은 브로커의 시작과 종료 시에만 사용되기 때문에 병행처리를 하도록 가능한 많은 수의 스레드를 설정하는 것이 좋다.
•
설정 값의 의미 : log.dirs 별 쓰레드 수
◦
num.recovery.threads.per.data.dir = 8, log.dirs = 3 ⇒ 전체 스레드 수: 24
6. auto.create.topics.enable
•
기본값은 true
•
다음의 경우, 브로커는 자동으로 토픽을 생성한다.
1) 프로듀서가 토픽에 메시지를 쓸때
2) 컨슈머가 토픽의 메시지를 읽기 시작할때
3) 클라이언트에서 토픽의 메타데이터를 요청할때
7.
auto.leader.rebalance.enable
•
리더 역활이 여러 브로커에 균등하게 분산되도록 함 (false)
•
전체 파티션 중 특정 브로커에 리더 역활이 할당된 파티션 비율이 leader.imbalance.per.broker.percentage에 설정된 값을 넘어가게 되면 리밸런싱 일어남
8.
delete.topic.enable
•
클러스터의 토픽을 임의로 삭제하지 못하게 막음
토픽 기본설정
1. per.topic 매개변수 사용 (kafka 2.0)
•
토픽당 로그 보유시간, 토픽당 로그 보유 바이트, 토픽당 로그 보유 세그먼트 등을 토픽에 지정 가능.
•
그러나 지금은 그렇게 할 수 없으며, 관리도구를 사용해야한다.
2. num.partitions
•
새로운 토픽이 몇개의 파티션으로 생성되는지를 지정 (기본값 = 1)
•
자동 토픽생성이 활성화 될때(auto.create.topics.enable=true) 사용된다.
•
파티션은 증가시킬수 있지만 감소시킬 수는 없다
•
토픽의 크기가 확장되는 방법이 파티션 ⇒ 브로커가 추가될 때 클러스터 전체에 걸쳐 메시지가 고르게 저장되도록 파티션 개수를 설정하는 것이 중요하다.
클러스터의 브로커수와 같게 하거나 배수로 토픽의 파티션 개수를 설정한다.
⇒ 브로커마다 파티션이 고르게 분산될 수 있고, 저장메시지도 고르게 분산될것이다.
[ 파티션 개수 산정시 고려할점 ]
1) 단위 시간당 토픽의 데이터 처리량은?
•
예를 들어, 초당 100KB 또는 1GB를 예상하는가?
2) 한 파티션의 데이터를 읽을때 목표로 하는 최대 처리량은?
•
파티션 하나는 항상 한 컨슈머가 소비한다.
3) 하나의 파티션에 데이터를 생성하는 프로듀서당 최대 처리량도 컨슈머와 같은 방법으로 산정할 수 있다. 그러나 대개 프로듀서는 컨슈머보다 훨씬 빠르게 처리되므로 처리량을 조사하지 않아도 무방하다.
4) 키를 사용해서 파티션에 메시지를 쓰는 경우에는 향후에 파티션을 추가할때 개수 산정이 어려울 수 있다.
•
따라서 현재보다는 향후에 예상되는 사용방법을 기준으로 처리량을 추산하자.
5) 브로커마다 파티션 개수와 디스크 용량및 네트워크 처리속도를 고려하자.
6) 파티션 개수를 너무 많이 고려하지 말자.
•
왜냐하면 각 파티션은 브로커의 메모리와 그 외 다른 자원을 사용하므로 리더 선정에 더 많은 시간이 소요되기 때문.
7) 위 모든 것을 고려해 파티션 개수를 너무많이 산정하지 말자. 초당 1Gb로 토픽을 읽고 쓰기 원하는데 각 컨슈머가 초당 50MB만 처리할수 있다면 (DB 쓰기관련 이슈로 인해) 최소한 20개(1000/50) 의 파티션이 필요하다. 자세한 정보가 없다면 파티션 크기를 하루에 6GB미만으로 제한할것을 권한다. (왜?)
⇒ 결론 : 파티션 개수 나중에 바꾸려면 생각해야될게 많을 수 있으니까 처음 정할때 잘 정해야 되는데 더도 덜도 말고 컨슈머가 견딜만한 정도의 양이 한 파티션에 배정될 정도의 개수로 나눌것!
참고. kafka 브로커, topic, partition, segment 구조
1.
Producer는 kafka의 A라는 Topic으로 메시지를 전달합니다.
2.
A Topic은 partition이 하나여서 0이며 Producer로부터 받은 메시지를 Partition의 Segment log파일에 저장합니다
3.
Broker의 Segment log file에 저장된 메시지는 Consumer가 읽어 갈 수 있습니다.
4.
Consumer는 A Topic을 컨슘 해서 해당 토픽 내 파티션 0의 segment log file에서 메시지를 가져옵니다.
Producer에 의해서 브로커로 전송된 메시지는 토픽의 파티션에 저장되며, 각 메시지들은 세그먼트라는 로그 파일의 형태로 브로커의 로컬 디스크에 저장됩니다.
(카프카의 브로커 > 토픽 > 파티션 > 세그먼트(세그먼트 로그 파일)에 저장을 합니다)
위 내용이 숙지가 되었다면 아래를 이해할 수 있습니다.
3. log.retention.ms
•
메시지 보존 기간 설정
•
보통 log.retention.hours로 설정하는데 이 경우, log.retention.ms 나 log.retion.minutes를 적게되면 그 값으로 오버라이딩 되니까 그냥 log.retention.ms를 쓰는 것을 권장함
4. log.retention.bytes
•
저장된 메시지들의 전체 크기를 기준으로 만기 처리
•
이 값은 모든 파티션에 적용된다.
•
log.retention.ms , log.retention.bytes 둘다 설정할 경우 둘중 하나의 조건이 충족될 때 메시지가 삭제된다.
5. log.segement.bytes
•
앞의 메시지 보존설정은 개별 메시지가 아닌 로그 세그먼트 파일을 대상으로 처리된다.
◦
참고로 세그먼트가 작성이 완료될 때까지, 메세지는 커밋이 되거나 삭제가 되지 못한다.
◦
즉 처리되지 못한 메세지도 세그먼트 작성 중이라면 삭제가 되거나 버려지지 않음
•
메시지가 카프카 브로커에 생성될 때는 해당 파티션의 로그 세그먼트 파일끝에 추가된다.
•
로그 세그먼트에는 메시지의 내용만 저장되는 것이 아니라 메시지의 key, value, offset, message size와 같은 정보가 함께 저장됩니다.
•
하나의 로그 세그먼트 크기가 너무 커지면 파일 관리가 어렵기 때문에 최대 크기는 1GB 기본값으로 설정되어 있습니다.
◦
해당 설정 값은 log.segment.bytes 매개변수에 지정된 크기 (기본값은 1GB)가 되면 해당 로그 세그먼트 파일이 닫히고 새로운 것이 생성되어 열리게 됩니다.
◦
그리고 닫힌 로그 세그먼트 파일은 만기가 된 것으로 간주한다. 따라서 로그 세그먼트의 크기를 더 작은 값으로 지정하면 더 빈번하게 파일이 닫히고 새로 생성되므로 전반적인 디스크 쓰기 효율이 감소된다.
•
1GB보다 크기가 커진다면?
◦
Rolling 전략을 사용
◦
ex) 하나의 로그 세그먼트에 계속 메시지를 덧붙이다가 1GB에 도달하면 close한뒤 새로운 로그 세그먼트를 생성하는 방식
•
1GB 크기의 로그 세그먼트 파일이 무한히 늘어날 경우를 대비해 관리 계획을 수립해야 합니다.
•
관리 계획은 크게 로그 세그먼트 삭제와 컴팩션으로 구분할 수 있습니다.
•
만일 토픽의 데이터 저장률이 낮다면 로그 세그먼트의 크기를 조정하는 것이 중요하다.
◦
예
▪
하루에 100MB의 메시지만 토픽에 수록되고 log.segment.bytes의 값이 기본값으로 1GB인 경우, 하나의 로그 세그먼트를 채우는데 10일이 소요된다.
▪
그러나 로그 세그먼트 파일은 닫혀야만 만기가 될 수 있으므로 만일 log.retention.ms가 1주일로 설정되어 있다면 로그 세그먼트에 저장된 메시지들은 17일동안 보존될 것
▪
왜냐하면 마지막 메시지를 스면서 로그 세그먼트 파일이 닫히는데 10일이 소요되고, 다시 보존기간인 7일이 지나야 만기가 되기 때문
•
특정 타임스탬프 시간으로 파티션의 오프셋을 요청할 수 있는데 이경우에도 log.segment.bytes가 관여된다.
◦
특정 시간에 해당하는 로그 세그먼트 파일을 찾기 때문. 지정된 타임스탬프 이전에 생성되고 마지막 수정시간이 해당 타임스탬프 이후인 로그 세그먼트 파일을 찾는다.
◦
그리고 찾은 로그 세그먼트파일의 시작 오프셋과 파일 이름을 반환한다.
6. log.segment.ms
•
지정된 시간이 되면 로그 세그먼트 파일을 닫는다. 위의 log.segment.bytes 와 대응된다.
•
기본적으로 이 속성은 설정되있지 않기때문에 로그 세그먼트 크기 제한으로만 닫히게 된다.
•
디스크 성능이 좋지 않다면 이 속성은 피하자.
◦
왜? 다수의 로그 세그먼트가 동시에 닫히는 것에 의해 디스크 성능에 영향을 끼칠 수 있기 때문.
7. message.max.bytes
•
브로커가 감당할 수 있는 하나의 메세지의 최대크기.
◦
기본값은 1000000 (1mb)
•
프로듀서가 이 값보다 큰 메시지를 보내는 경우 프로듀서에 에러를 날린다. 당연히 컨슈머에도 이 값보다 큰 메세지를 보내지는 않는다.
◦
만약 압축을 풀어서 보내려는데 이 값보다 커진다면 압축해서 보내야 합니다..!
•
기본값이 클수록 네트워크 비용, 요청당 작업시간, 처리량 문제가 생기기 때문에 성능 튜닝시 고려할 요소중 하나다.