본문 바로가기

빅데이터/Kafka

대규모 데이터의 카프카 프로듀서 성능 향상 방법

카프카 프로듀서는 acks, linger.ms, batch.size 조절을 통해 성능 향상을 달성 할 수 있습니다. 각 옵션별로 한계점과 성능 향상 방법을 알아보겠습니다. 여기서는 대규모 데이터가 들어오는 것을 가정하였습니다. 

 

가정사항

- Record의 메시지 크기 10Kbytes

- 레코드 유입량 : 1000tps

 

acks

acks는 카프카 프로듀서로 전송한 레코드가 정상적으로 리더 또는 팔로워 파티션에 적재되었는지 확인하는 역할을 합니다. 0으로 설정할 경우 모든 전송 케이스에 대해 성공으로 처리하고 1의 경우 리더 파티션에 적재되었을 경우 성공으로 처리합니다. all(-1)로 설정할 경우에는 리더와 팔로워 파티션(min.insync.replicas)에 적재가 완료되었을 경우 성공으로 처리하지만 all로 처리할 경우 속도가 매우 늦어지게 됩니다. 일반적으로 1을 사용하여 리더 파티션에 적재되면 성공으로 보는 경향이 많습니다. 팔로워까지 복제되었는지 확인하기에는 속도측면에서 얻는 이득이 없기 때문입니다. 물론 브로커 장애가 발생하게 되면 이는 틀어질 수 있지만 전체적인 흐름에 봤을 때 1을 사용하는 것이 트레이드오프 측면에서 훨씬 낫다고 볼 수 있습니다. 0으로 설정할 경우 네트워크 에러 등 여러 장애 상황을 정확히 파악할 수 없기 때문에 1로 설정하는 것이 좋아보입니다.

linger.ms

linger.ms는 배치에 적재되기 전까지 얼마나 데이터를 기다리느냐를 정하는 것입니다. 기본값은 0으로서 send()를 호출하자 말자 바로 전송하는 것입니다. 이 경우 매번 send()가 호출될 때 마다 TCP통신을 맺어 데이터를 전송하기 때문에 대규모 데이터 전송에서는 적합하지 않을 수 있습니다. 이를 위해 일부 딜레이를 가지고 batch.size만큼 데이터가 모일 때까지 기다렸다가 한번에 전체 데이터를 보내는 방법이 적합할 수 있습니다. 이는 네이글 알고리즘을 사용하는 것과 유사하다고 볼 수 있습니다.

네이글 알고리즘 : IP 네트워크에서 데이터는 캡슐화되어 통신한다. 많은 수의 데이터를 자주 통신을 맺어 보내게 되면 비효율성이 커진다. 적은 데이터를 자주 전송해야할 때 패킷을 크게 배치로 묶어 전송하면 네트워크 효율을 높일 수 있다. 문제는 이렇게 데이터를 묶는 작업을 수행할 때 지연이 발생한다는 점이다. 지연과 효율을 trade-off한다면 더욱 효과적인 네트워크 통신이 될 수 있다.

linger.ms를 늘리면 대기 시간이 늘어난다는 이슈가 있지만 전체적인 효율로 봤을 때는 더욱 좋다는 의견이 있습니다. 조금의 지연을 허용하고 어느 정도 배치사이즈만큼 데이터를 기다리고 싶다면 10 또는 100으로 설정하는 것도 좋을것 같네요.

batch.size

프로듀서는 send()에 포함된 레코드를 한번에 하나씩 보낼 수도 있지만 batch.size를 조절함으로서 더 많은 양의 데이터를 한번에 묶어서 전송할 수 있습니다. 다만, 이 경우 동일한 파티션에 전송되는 데이터에 대한 배치 사이즈를 의미합니다. 왜냐면 서로 다른 파티션의 데이터를 배치로 묶어서 전송하는 것은 브로커 특성상 불가능하기 때문입니다. 메시지 사이즈보다 batch.size가 작으면 안되고 반드시 메시지 사이즈는 batch.size보다 작아야합니다. 작은 batch.size는 전체적인 처리량을 낮출 수 있고 너무 큰 배치 사이즈는 메모리를 불필요하게 많이 사용해서 배치를 충분히 활용할 수 없습니다. 10kbytes 크기를 가진 메시지를 최대한으로 전송하고 싶다면 batch.size를 대략 100k 정도로 준다면 최소 1개에서 최대 10개 가량 데이터를 묶어 보낼 수 있기 때문에 효율이 늘어 날 것을 기대할 수 있습니다.

 

참고

- https://developer.confluent.io/tutorials/optimize-producer-throughput/confluent.html

반응형