Kafka 운영자가 말하는 TIP
이번에는 kafka 파티션 재배치에 대해 알아보고, log 디렉토리 사용이 균등하지 않을 때 조치할 수 있는 방법에 대해 말씀드리도록 하겠습니다. 해당 내용을 모를 경우 kafka 운영하시면서 난감한 상황에 마주칠 수 있다고 생각됩니다. 잘 읽어보시고 도움이 되셨으면 합니다. 이 글을 처음 보시는 분들은 이전 글도 보시면 좋을 것 같습니다.
Kafka 운영자가 말하는 Kafka Consumer Group
Kafka 운영자가 말하는 Kafka 서버 실전 로그 분석
kafka disk 구성
저는 kafka 구성을 하면서 서버 하나당 4장의 disk를 RAID 구성하지 않고 각각 개별 disk로 mount 하여 사용하고 있습니다. kafka 서버에서 disk를 구성하는 방법에 대해 잠깐 말씀드리자면, 크게 2가지의 형태로 나누어 볼 수 있을 것 같습니다.
- RAID 구성
장점 : disk 하나가 장애가 나더라도 online 상태로 교체 가능 / disk 장애 상황에 대해 쉽게 대처 가능
단점 : 4장의 disk를 RAID 1 + 0로 묶으면, disk 사용 공간이 절반으로 줄어들게 되어, disk 사용 부분에서는 비효율적이며 비용이 비쌈.
- 개별 구성
장점 : 각 disk를 mount 하여 사용하므로, 각 disk 사용 공간을 최대로 사용 가능
단점 : disk 장애 발생 시 online 처리가 불가능
kafka 공식 문서에서 disk 구성 관련 내용을 살펴보면 구 버전에서는 각 disk를 마운트 하여 사용하는 구성을 선호하였으나, 최근 버전에서는 비용의 여유가 있다면 RAID 구성을 추천하기도 합니다. 각 구성에 따라 장단점이 있기 때문에, 각자의 상황을 고려하여 선택하시면 됩니다.
kafka 파티션 분산
kafka에서는 각 broker의 리소스를 최대한 활용하기 위해 각 토픽들을 균등하게 broker들에게 분산하도록 설계되어 있습니다. 그래서 각 파티션들은 broker들에게 비교적 균등하게 분산되어 있습니다. 만약 broker들에게 분산되어 있는 파티션의 위치가 마음에 들지 않으면 관리자가 수동으로 조정할 수 있습니다. 주의할 점은 각각의 파티션은 broker들에게 고르게 분산되어 있지만, broker 내의 log 디렉토리까지는 균등하게 분산되어 있지 않습니다. 약간 이해가 안 될 수 있기 때문에 그림으로 설명드리도록 하겠습니다. 그림으로 설명드리기 전 몇 가지 가정을 하도록 하겠습니다.
broker 수 : 3EA topic 명 : peter partition 수 : 6EA broker log 디렉토리 : /data1, /data2, /data3
위 내용을 바탕으로 peter 토픽을 생성하게 되면 다음과 같이 생성됩니다.
partition 수가 정확히 broker 수의 2배이므로, 하나의 broker당 두 개의 partition이 분산됩니다. 만약 원하는 형태로 분산되지 않았다면 kafka에서 제공하는 command를 이용하여 수동으로 위치를 재배치할 수도 있고, kafka manager를 이용하여 변경하실 수 있습니다. command를 이용하게 되면, json 파일을 미리 만들어야 하는 사전 작업이 좀 필요합니다. 개인적인 의견으로는 kafka manager를 이용하여 변경하시기를 권장해드립니다.
kafka 파티션 reassgin
이해를 돕기 위해 replication factor는 1이라고 가정하고 설명하도록 하겠습니다. 먼저 현재 토픽이 어떻게 구성되어 있는지를 확인해보겠습니다. 토픽 정보를 보기 위해서, kafka가 설치된 디렉토리로 이동하신 후 다음 명령어를 실행하시면 됩니다.
1
bin/kafka-topics.sh --describe --zookeeper peter-zk001:2181 --topic peter
실행하시면, 아래와 같이 peter topic의 상세 정보를 확인하실 수 있습니다.
1 2 3 4 5 6 7
Topic:peter PartitionCount:6 ReplicationFactor:1 Configs: Topic: peter Partition: 0 Leader: 2 Replicas: 2 Isr: 2 Topic: peter Partition: 1 Leader: 3 Replicas: 3 Isr: 3 Topic: peter Partition: 2 Leader: 1 Replicas: 1 Isr: 1 Topic: peter Partition: 3 Leader: 2 Replicas: 2 Isr: 2 Topic: peter Partition: 4 Leader: 3 Replicas: 3 Isr: 3 Topic: peter Partition: 5 Leader: 1 Replicas: 1 Isr: 1
위 내용으로 현재 배치되어 있는 파티션 정보를 정리해 보면, 아래의 그림과 같이 되어 있습니다.
각각의 broker마다 2개씩 균등하게 분배되어 있으나, 각 파티션을 broker 순서대로 2개씩 재배치해보겠습니다. 가장 먼저 해야 할 것은 "custom-reassignment.json"이라는 파일을 만들어야 합니다. 파일명은 원하시는 이름으로 하셔도 상관없습니다. 미리 준비한 "custom-reassignment.json" 파일 내용을 살펴보면, 아래와 같습니다.
1 2 3 4 5 6 7 8 9 10
{"version":1,"partitions": [ {"topic":"peter","partition":0,"replicas":[1]}, {"topic":"peter","partition":1,"replicas":[2]}, {"topic":"peter","partition":2,"replicas":[3]}, {"topic":"peter","partition":3,"replicas":[1]}, {"topic":"peter","partition":4,"replicas":[2]}, {"topic":"peter","partition":5,"replicas":[3]} ] }
topic 이름과, 파티션 번호와 replicas 번호를 넣어주시면 됩니다. 위의 json 파일의 내용을 그림으로 나타내면 아래와 같습니다.
이제, 해당 json 파일 내용을 적용시킬 차례입니다. kafka가 설치된 디렉토리로 이동하신 후 다음 명령어를 실행하시면 됩니다.
1
bin/kafka-reassign-partitions.sh --zookeeper peter-zk001:2181 --reassignment-json-file custom-reassignment.json --execute
실행하신 후 "Successfully started reassignment of partitions." 이런 메시지가 나타나면 적용이 완료된 것입니다. 이제 topic 상세정보 보기를 통해서 아래와 같이 변경된 것을 확인하실 수 있습니다.
1 2 3 4 5 6 7
Topic:peter PartitionCount:6 ReplicationFactor:1 Configs: Topic: peter Partition: 0 Leader: 1 Replicas: 1 Isr: 1 Topic: peter Partition: 1 Leader: 2 Replicas: 2 Isr: 2 Topic: peter Partition: 2 Leader: 3 Replicas: 3 Isr: 3 Topic: peter Partition: 3 Leader: 1 Replicas: 1 Isr: 1 Topic: peter Partition: 4 Leader: 2 Replicas: 2 Isr: 2 Topic: peter Partition: 5 Leader: 3 Replicas: 3 Isr: 3
broker 사이에는 파티션이 2개씩 broker 순서에 맞추어 이상적으로 재배치되었습니다. 그러면 이번에는 broker 안에서 각각의 log 디렉토리에 어떻게 파티션이 분산되었는지 살펴보겠습니다. 위에서 제가 각 broker의 log 디렉토리는 /data1, /data2, /data3 이렇게 3개가 있다고 가정을 했기 때문에 하나의 broker가 가지고 있는 파티션 수 2개와 log 디렉토리 수 3개가 서로 일치하지 않으므로, 아래 그림과 같을 수 있습니다.
하지만 항상 위와 같이 배치되는 것이 아니라, 아래의 그림과 같이 배치가 될 수도 있습니다.
만약 log 디렉토리의 최대 크기는 제한되어 있고 해당 log 디렉토리로 사이즈가 큰 파티션이 몰려 있을 수 있습니다. 설명을 위해서 아래 그림을 준비했습니다.
log 디렉토리의 전체 사이즈는 500G로 제한되어 있고, /data1과 /data3은 50G만 사용하고 있습니다. 하지만 /data2에만 사이즈가 큰 파티션이 몰려 있어 450G의 공간을 사용 중에 있어 관리자 입장에서 아주 난감한 상황입니다. 조금 난감한 상황이지만, 지금 현재 kafka 버전에서는 이런 경우 대응할 수 있는 command가 지원되지 않고 있습니다. 그럼 어떻게 할 수 있을까요?
log 디렉토리의 파티션을 이동하기
log 디렉토리의 파티션을 이동시키기 위한 방법이 있는데, 수작업으로 해야 합니다. 또한 해당 작업을 하시기 전, kafka 데몬을 종료하신 후 진행하셔야 합니다.
- log 디렉토리의 파티션을 이동시켜야 하는 broker 서버를 중지
- /data2로 이동
- recovery-point-offset-checkpoint, replication-offset-checkpoint 파일을 열어서 이동시켜야 할 파티션 정보를 복사하고 line을 삭제(두 번째 줄에 숫자가 있는데, -1 해주셔야 합니다.)
- /data3로 이동시켜야 한다고 하면, /data3로 이동
- recovery-point-offset-checkpoint, replication-offset-checkpoint 파일을 열어 3번에서 복사한 내용을 추가( 두 번째 줄에 숫자를 +1 해주셔야 합니다.)
- mv /data2/peter-3 /data3/peter-3
- broker start
위 작업을 통해 원하는 형태로 파티션들을 이동시켰다면, 아래와 같은 형태가 될 것입니다.
위의 파티션 이동 작업이 필요는 하지만, 수동으로 진행하다 보니 번거로운 것이 사실입니다. 그래서 제가 스크립트를 하나 만들려고 하였으나, 검색하면서 우연하게 위 작업을 어느 분이 스크립트로 만들어 github에 KafkaPartitionMover라고 공유한 것을 찾았습니다. 제가 다운로드하여서 테스트를 해보니, 정상적으로 잘 동작하였습니다. 만약 kafka 운영하시면서 log 디렉토리 이동이 필요하신 분들은 수동으로 하지 마시고, 해당 스크립트를 사용하여 편하게 작업하시면 될 것 같습니다. 간략한 사용 방법은 아래와 같습니다.
$ ./PartMove.sh -sd /data1 -dd /data2 --partitions peter-0
sd는 source이고, dd는 destination 입니다. 위 명령어는 /data1/peter-0를 -> /data2/peter-0으로 옮기는 예제입니다. 이제 kafka 운영하시면서 데이터가 한쪽에 몰려 있어 고민하지 마시고 자유롭게 이동시키세요^^ 긴 글 읽어주셔서 감사합니다.