Kafka Topic의 partition 수 정하기

ADVANTAGES

1. 파티션 수의 증가로 높은 처리량을 기대할 수 있다.

먼저 이해해야할 것은 파티션은 Kafka의 병렬 처리 단위라는 것이다. producer와 broker 측면에서는 서로 다른 파티션에 쓰기를 병렬로 수행 할 수 있다. 따라서 압축과 같은 값 비용 높은 작업은 더 많은 하드웨어 리소스를 활용할 수 있다.
Consumer 측면에서 Kafka는 항상 단일 파티션의 데이터를 하나의 Consumer Thread 에 제공한다. 따라서 Consumer의 병렬 처리 정도는 소비되는 파티션의 수에 의해 결정된다. 그래서 일반적으로 Kafka 클러스터에 파티션이 많을수록 처리량이 높아진다.

파티션 수를 선택하는 방식은 처리량을 기반으로 한다. production(p)을 위해 consumption(c)를 위해 단일 파티션에서 달성 할 수있는 모든 것을 측정한다. 목표 처리량이 t라고 가정 해 보자. 그런 다음 적어도 t/p와 t/c중 최대값으로 파티션이 있어야한다. producer에서 달성 할 수있는 파티션 별 처리량은 일괄 처리 크기, 압축 코덱, 승인 유형, replication factor 등과 같은 구성에 따라 달라진다. consumer 처리량은 consumer Logic이 각 메시지를 처리 ​​할 수있는 속도에 해당하기 때문에 응용 프로그램에 따라 다르다.

시간이 지나 파티션 수를 늘리는 것은 가능하지만 메시지 키를 가지고 produce 되는 경우 주의해야한다. keyed message를 게시할 때 Kafka는 키의 해시를 기반으로 메세지를 결정하여 메시지에 매핑한다. 이렇게하면 동일한 키가 있는 메시지는 항상 동일한 파티션으로 라우팅되도록 보장 할 수 있다. 이러한 보증은 파티션 내의 메시지가 항상 consumer에게 전달되기 때문에 특정 응용 프로그램에서 중요 할 수 있다. 파티션 수가 변경되면 이러한 보증이 더 이상 유지되지 않을 수도 있다. 이러한 상황을 피하기 위해 비트를 과도하게 분할하는 것이 일반적이다. 기본적으로 향후 목표 처리량(예를 들어 1-2년 후)를 기준으로 파티션 수를 결정한다.
처음에는 현재 처리량에 따라 작은 카프카 클러스터를 만들 수 있고, 시간이 지남에 따라 더 많은 broker를 클러스터에 추가하고 기존 broker의 일부를 비례적으로 새로운 broker로 이동할 수 있다. 이 방법을 사용하면 키가 사용될 때 응용 프로그램의 의미를 깨지 않고 처리량 증가를 따라갈 수 있다.

DISADVANTAGES

1. 파티션 수의 증가는 높은 “Open File limit”이 요구된다.

각 파티션은 broker의 파일 시스템에있는 디렉토리에 매핑된다. log 디렉토리에는 log 세그먼트 당 두 개의 파일 (색인 용과 실제 데이터 용)이 있다. 현재 Kafka에서 각 broker는 모든 log 세그먼트의 인덱스와 데이터 파일 모두에 대한 파일을 연다. 그런데 이 점을 단점으로 구분지어 놓긴 했지만, OS에서 변경해주면 되는 구성 문제 일 뿐이다.
(딱히 장점으로 볼 수 없고, 번거로우니 단점으로 넣었다.)

2. 파티션 수의 증가는 가용성을 낮출 수 있다.

Kafka는 높은 가용성과 내구성을 제공하는 클러스터 내 복제를 지원한다. 파티션에는 여러 복제본을 가질 수있고, 각각 다른 broker에 저장이 된다.
복제본 중 하나가 leader로 지정이 되며 나머지 복제본은 follower가 된다.
내부적으로 Kafka는 모든 복제본을 자동으로 관리하여 동기화 상태를 유지한다. 파티션에 대한 producer와 consumer에 대한 요청사항들은 모두 leader에서 제공되며,
broker가 내려가면 해당 broker의 leader가 있는 파티션을 일시적으로 사용할 수 없게 된다. Kafka는 사용할 수없는 파티션의 leader를 다른 복제본으로 자동으로 이동시켜 클라이언트 요청을 계속 처리한다. 이 프로세스는 컨트롤러로 지정된 Kafka broker 중 한 곳에서 수행한다. ZooKeeper에서 영향을 받는 각 파티션에 대한 메타 데이터를 읽고 쓰는 작업이 포함되며, 현재 ZooKeeper에 대한 작업은 컨트롤러에서 순차적으로 수행된다.

일반적인 경우 broker가 정상적으로 종료되면 컨트롤러는 broker를 한 번에 하나씩 종료하는 방식으로 관리자를 이동시킨다. 단일 리더의 이동에는 수 milli 초 밖에 걸리지 않으며,
따라서 클라이언트 관점에서 볼 때 broker가 종료되는 동안 잠시 가용성이 보장되지 않을 수 있다.

그러나 broker가 비정상 종료되면 (예 : kill -9) 관찰 된 비 가용성은 파티션 수에 비례 할 수 있다. broker에 총 2,000 개의 파티션이 있고 각 파티션에 2 개의 복제본이 있다고 가정하면,
대략이 broker는 약 1000 개의 파티션을 위한 리더가 될 될 것이다.
이 broker가 불완전하게 실패하면 1000 개의 모든 파티션을 정확히 같은 시간에 사용할 수 없게된다. 단일 파티션에 대해 새로운 리더를 선출하는 데 5ms가 걸린다고 가정하면,
모든 1000 개의 파티션에 대해 새로운 리더를 선출하는 데 최대 5 초가 걸린다.
따라서 일부 파티션의 경우 관찰 된 비가용성은 5 초에 실패 감지 시간을 더한 값이 될 수 있다.

broker가 고장났을 경우 새로운 leader를 선출하는 프로세스는 컨트롤러가 새로운 broker에게 장애 조치를 수행 할 때까지 시작되지 않는다. 컨트롤러 fail over는 자동으로 발생하지만 새 컨트롤러를 초기화하는 동안 ZooKeeper에서 모든 파티션의 일부 메타 데이터를 읽어야한다. 예를 들어 Kafka 클러스터에 10,000 개의 파티션이 있고 ZooKeeper에서 메타 데이터를 초기화하는 데 파티션 당 2ms가 걸리면 비가용성 시간이 20 초가 더해진다.

일반적으로 비정상 종료는 드물다. 그러나 이 드문 케이스까지에서도 가용성에 신경을 써야한다면 broker 당 파티션 수를 2 ~ 4,000 개로 제한하고 클러스터의 총 파티션 수를 수만 개로 제한하는 것이 좋다.

3. 파티션 수의 증가는 종단 간 Latency을 늘릴 수 있다.

Kafka의 종단 간 Latency은 메시지가 producer에 의해 게시 된 후 consumer가 메시지를 읽을 때까지의 시간으로 정의된다. Kafka는 모든 비동기화 복제본에 메시지가 복제 된 때만 consumer에게 메시지를 노출한다. 따라서 메시지를 커밋하는 시간은 종단 간 Latency의 상당 부분을 차지할 수 있다.
기본적으로 Kafka broker는 두 개의 broker간에 복제본을 공유하는 모든 파티션에 대해 단일 스레드를 사용하여 다른 broker의 데이터를 복제한다. 우리의 실험에 따르면 한 broker에서 다른 broker로 1000 개의 파티션을 복제하면 대기 시간이 약 20ms 늘어날 수 있다. 이는 종단 간 Latency가 최소 20ms임을 의미하며, 이는 일부 실시간 응용 프로그램에 비해 너무 높을 수 있다.

이 문제는 더 큰 클러스터에서 완화된다. 예를 들어, broker에 1000 명의 파티션 리더가 있고 동일한 Kafka 클러스터에 다른 broker가 10개 있다고 가정하면,
나머지 10개의 broker는 평균적으로 첫 번째 broker에서 100 개의 파티션만 가져와야한다. 따라서 메시지를 커밋하기 때문에 추가되는 Latency은 수십 ms가 아닌 단지 수 ms에 불과한다.

경험에 비추어 볼 때 broker 당 파티션 수를 100 x broker x replication-factor로 제한하는 것이 좋다.

4. 파티션 수의 증가는 클라이언트 메모리가 보다 많이 요구된다.

파티션 수를 늘리면 생성자의 더 많은 파티션에 메시지가 누적된다. 사용 된 메모리 총량이 구성된 메모리 제한을 초과 할 수 있으며, 이 경우 Producer는 새로운 메시지를 막거나 삭제해야하는데 그 어느 쪽도 좋은 선택은 아니다. 이러한 일이 발생하지 않도록하려면 더 큰 메모리 크기로 Producer를 다시 구성해야한다.

일반적으로 좋은 처리량을 얻으려면 Producer에서 생성되는 파티션 당 최소 수십 KB를 할당하고 파티션 수가 크게 증가 할 경우 총 메모리 양을 조정해야한다.

비슷한 문제가 Consumer에게도 존재하는데, Consumer는 파티션 당 메시지 묶음을 가져온다. Consumer가 소비하는 파티션이 많을수록 더 많은 메모리가 필요하며, 일반적으로 Consumer에만 문제가 된다.

요약

일반적으로 파티션 수를 증가시키면 높은 처리량을 기대할 수 있다. 그러나 대기시간이나 가용성 같은 것들을 고려할 때 과도한 파티션 수가 가져올 수 있는 side effect는 알아야만 한다.
2015년 12월에 작성된 글이므로 현재 스펙과 다를 수 있습니다.

위 글은 confluent의 포스팅을 바탕으로 작성되었습니다.

comments powered by Disqus