본문 바로가기
카테고리 없음

아파치 카프카 컨슈머와 리밸런싱

by 오피스포디 2024. 1. 13.
반응형

오늘 내용은 아파치 카프카가 무엇이고, 어떤 역할을 하는지 알고 있다는 가정하에 작성하였습니다. 카프카는 메세지 큐이고 전달할 메세지를 토픽에 저장했다가 컨슈머에게 메세지를 전달하는데, 이 때 카프카와 컨슈머 사이에 어떤 변화가 있을 때 일어나는 리밸런싱에 대해 살펴보고자 합니다.

카프카 컨슈머와 컨슈머 그룹

카프카는 프로듀서가 토픽에 메세지를 보내면 이를 여러 파티션에 나눠서 저장합니다. 이 때 이 메세지들은 컨슈머가 요청해서 가져가고, (폴링) 각 컨슈머는 파티션의 데이터를 가져갑니다.

 

컨슈머는 여러 개가 모여서 컨슈머 그룹을 형성합니다. 흔히 말하는 "컨슈머가 토픽의 데이터를 가져간다" 라는 개념은 사실상 컨슈머 그룹이 토픽의 데이터를 가져가는 것이고, 컨슈머는 파티션의 데이터를 가져가게 됩니다.

 

우선 아래와 같이 예를 들어보겠습니다. 어떤 토픽 A가 4개의 파티션을 가지고 있고, 컨슈머 그룹 A가 하나의 컨슈머를 가지고 있다고 하겠습니다.

4개의 파티션을 가진 카프카 토픽 A와 1개의 컨슈머를 가진 컨슈머 그룹 A
4개의 파티션을 가진 카프카 토픽 A와 1개의 컨슈머를 가진 컨슈머 그룹 A

 

위의 예시에서, 컨슈머 그룹 A는 하나의 컨슈머만을 가지고 있기 때문에, 이 컨슈머 1에서 토픽 A의 모든 파티션 (4개) 에서 데이터를 가져갑니다. 이 때 컨슈머 1이 파티션 1~4를 소유하고 있다고 이야기합니다.

 

하지만 컨슈머 하나로 파티션 4개의 데이터를 모두 처리하기가 힘들 수 있으므로, 카프카 토픽에 랙이 많이 쌓이거나 아니면 컨슈머 앱이 불안정해질 수 있습니다. 이를 방지하기 위해 컨슈머를 늘릴 필요가 있습니다. 컨슈머를 하나 더 추가했다고 합시다.

4개의 파티션을 가진 카프카 토픽 A와 2개의 컨슈머를 가진 컨슈머 그룹 A
4개의 파티션을 가진 카프카 토픽 A와 2개의 컨슈머를 가진 컨슈머 그룹 A

 

그러면 컨슈머 그룹에 컨슈머가 2개가 되었고, 컨슈머 그룹 A의 컨슈머들이 4개 파티션을 2개씩 소비하게 됩니다. 즉, 달리 말하면 소유권을 나눠서 가지게 됩니다. 이를 리밸런싱이라 합니다. 잠시 후 자세히 설명하겠습니다.

 

이제 컨슈머를 더 늘려봅니다. 파티션의 갯수와 컨슈머의 갯수를 일치시켜 봅시다. 즉 컨슈머도 이제 4개가 되었습니다. 아래 그림입니다.

 

4개의 파티션을 가진 카프카 토픽 A와 4개의 컨슈머를 가진 컨슈머 그룹 A
4개의 파티션을 가진 카프카 토픽 A와 4개의 컨슈머를 가진 컨슈머 그룹 A

 

뭔가 깔끔하죠? 각 파티션을 각각의 컨슈머가 하나씩 나눠서 가져갑니다. 근데 이런 상황에서도 데이터가 너무 많이 들어와서 자꾸 랙이 쌓인다고 가정해 볼께요. 이제까지 컨슈머를 늘려서 해결했으니까 이번에도 하나 더 늘려보겠습니다.

 

4개의 파티션을 가진 카프카 토픽 A와 5개의 컨슈머를 가진 컨슈머 그룹 A
4개의 파티션을 가진 카프카 토픽 A와 5개의 컨슈머를 가진 컨슈머 그룹 A

 

어떠신가요? 그림에서 보기에 뭔가 컨슈머 5번은 아무것도 안하고 노는 거 같지 않나요? 맞습니다. 카프카에서는 하나의 파티션을 2개 이상의 컨슈머가 소비할 수 없습니다. 그러니까, 각 파티션은 최대 하나의 컨슈머에만 연결되어 있을 수 있습니다. (반대는 가능합니다.) 아래 그림을 보겠습니다.

 

컨슈머는 여러개의 파티션을 소비할 수 있지만, 하나의 파티션을 여러개의 컨슈머가 소비할 수는 없다
컨슈머는 여러개의 파티션을 소비할 수 있지만, 하나의 파티션을 여러개의 컨슈머가 소비할 수는 없다

 

이렇게 만들어둔 이유는 뭘까요? 그건 카프카의 순서 보장 때문입니다. 카프카는 토픽 전체에서의 순서 보장은 지원하지 않지만 같은 파티션의 순서는 보장합니다. 설명하자면 이렇습니다.

 

  1. 카프카의 프로듀서가 메세지 1을 파티션 1에 전송한 후 메세지 2를 파티션 2에 전송했다.
  2. 카프카의 컨슈머 그룹 내에서 컨슈머 1이 메세지 1을 소비하고 컨슈머 2가 메세지 2를 소비했다.

이 때 메세지 1이 메세지 2보다 반드시 먼저 소비될까요? 그렇지 않습니다. 컨슈머들의 컨디션에 따라 프로듀서가 나중에 보낸 메세지 2가 메세지 1보다도 먼저 소비될 수 있습니다. 즉, 토픽 레벨에서의 순서 보장은 카프카에서 지원되지 않습니다.

 

하지만 파티션 수준에서는 다릅니다. 파티션 하나에는 컨슈머 하나만 연결될 수 있으므로, 파티션 1에 메세지 1과 메세지 2가 순차적으로 들어왔다면 이는 순차적으로 소비됩니다.

그럼에도 발생하는 지연 상황에서는

카프카 토픽의 최대 파티션 갯수만큼 컨슈머를 설정해서 파티션과 컨슈머가 1대 1이 되도록 했는데도 지연이 해소되지 않는다면, 컨슈머만 늘려 봐서 소용이 없습니다. 이럴 때는 카프카 파티션 수를 늘리고, 그에 맞추어서 컨슈머 수도 같이 늘려주어 처리량이 늘어날 수 있도록 해야 합니다.

 

카프카에서는 파티션 갯수 조정을 비교적 쉽게 할 수 있으나, 주의할 것은 늘리는 방향으로만 가능하다는 점입니다. 파티션을 줄이고 싶다면, 해당 토픽은 폐기하고 다른 토픽을 생성하여 파티션 갯수를 조정해야 합니다.

 

리밸런싱

이제는 위에서 잠시 나왔던 리밸런싱에 대해 이야기해 보겠습니다. 리밸런싱이란 위에서 컨슈머 갯수가 달라졌을 때 (위에서는 늘어났음) 각 파티션의 데이터를 균형있게 소비하게 하기 위해 일어난다고 이야기했습니다. 컨슈머는 2개가 되었는데 여전히 컨슈머 1이 모든 파티션을 소비하고 있으면 안되잖아요?

리밸런싱이 필요한 경우

일단 한가지 경우는 나왔습니다. 컨슈머 갯수가 변경된 경우죠. 그런 경우만 있을까요?

 

  1. 컨슈머 갯수가 변경된 경우 : 컨슈머 그룹에 포함된 컨슈머가 늘어나거나 줄어들었을 때 둘 다 해당합니다.
  2. 컨슈머에 문제가 생겼을 경우 : 컨슈머가 모종의 이유로 정상적으로 동작하지 않을 경우에 리밸런싱이 수행됩니다.
  3. 토픽의 파티션이 늘어난 경우 : 사실상 컨슈머 갯수가 변경된 것이나 똑같습니다.

리밸런싱이 필요한 경우
리밸런싱이 필요한 경우

 

리밸런싱 방식

리밸런싱을 위해 카프카에서는 컨슈머 그룹을 관리하는 Group Coordinator 가 있습니다. 이는 카프카 브로커 측에 속해 있으며 컨슈머 그룹에 어떤 컨슈머들이 속해있는지, 어떤 컨슈머들이 살아있는지에 대한 상태관리 등을 수행합니다. 하지만 이 이상, 그러니까 컨슈머들 간에 각각 몇개의 파티션을, 어떤 파티션을 소유할 것인지에 대해서는 개입하지 않고, 컨슈머 그룹 중 리더인 컨슈머가 알아서 정하게 둡니다.

 

먼저 컨슈머가 추가되었을 때 리밸런싱 순서에 대해 알아보면 다음과 같습니다.

 

  1. findCoordinator : 새로운 컨슈머가 일단 본인이 참여하고자 하는 그룹의 코디네이터를 찾는 호출입니다.
  2. joinGroup : 코디네이터를 찾고 나면, 새 컨슈머가 나 이그룹에 끼워줘 라는 요청을 합니다. 그러면 코디네이터에서는 어떤 컨슈머들이 유효한지 하트비트를 통해 판정하고, 유효한 컨슈머들에게는 리밸런싱할 거라는 것을 알려줍니다. 리밸런싱 사실을 알게된 컨슈머들은 나 이 그룹이니까 빼지 말라는 요청 (joinGroup) 을 보냅니다.
  3. 리더 컨슈머 선출 : 모든 유효한 컨슈머로부터 joinGroup 요청이 오면, 그룹 코디네이터는 가장 먼저 joinGroup 요청을 보낸 컨슈머를 리더로 선출하고, 리더에게 이 사실과 함께 컨슈머 정보를 알립니다. 컨슈머 추가의 경우에는 새 컨슈머가 가장 먼저 이를 보냈으므로, 새로 참여한 컨슈머가 리더가 됩니다.
  4. 소유권 재조정 : 컨슈머 그룹 리더는 전달받은 정보를 이용하여 파티션 소유권을 조정하고, 이를 그룹 코디네이터에게 전달합니다.
  5. 컨슈머에게 정보 전달 : 그룹 코디네이터가 팔로워를 포함한 모든 컨슈머에게 조정된 파티션 소유권을 알리고 리밸런싱을 종료합니다.

위의 예시에서는 컨슈머가 추가될 때의 리밸런싱 과정을 예시로 들었지만, 다른 경우에도 최초에 리밸런싱이 일어나게 되는 트리거가 다를 뿐, 그 이후의 과정은 동일합니다. 예를 들어 컨슈머 하나가 종료될 경우 (앱 재배포 등으로) 에는 "나 이제 종료할거야" 라는 호출을 컨슈머가 그룹 코디네이터에게 보내면, 코디네이터가 이를 인지하고 리밸런싱 과정을 시작하게 됩니다.

 

만약에 컨슈머 하나가 이상 동작을 보이면 해당 컨슈머는 하트비트 (자신이 살아있다는 뜻으로 주기적으로 보내는 메세지) 를 더이상 보내지 않게 되고, 하트비트가 날아오지 않으면 그 컨슈머의 심장이 멈췄다고 생각하고 그룹 코디네이터는 바로 리밸런싱을 실시하게 됩니다.

 

리밸런싱 시에도 리밸런싱 전과 마찬가지로 파티션 별 오프셋은 동일하게 유지되어야 하므로, 이를 브로커에 저장하여 리밸런싱 후에 해당 오프셋 이후부터 읽어갈 수 있도록 합니다.

리밸런싱의 위험성

위의 리밸런싱 과정을 보면, 리밸런싱 중에는 그룹 코디네이터가 일단 모든 컨슈머들을 멈춰놓고 유효한 컨슈머 확인을 진행하게 됩니다. 그러면 그 시간동안은 해당 토픽의 어떤 메세지도 처리되지 않습니다. 이를 Stop The World 라고 부르며, 이 또한 실시간이 필요한 서비스에서는 중요한 요소가 됩니다.

 

만약에 컨슈머 앱의 재배포가 필요하면 컨슈머 앱을 종료할 때 한 번 리밸런싱이 일어나고 (컨슈머가 사라지므로), 다시 배포 후 시작할 때 또 리밸런싱이 일어납니다. (컨슈머가 추가되므로) 이 뿐아니라 파티션이 늘어날 때도, 이에 대응하여 컨슈머를 늘릴 때도 항상 리밸런싱이 일어나므로, 설정을 변경하기 전에 충분히 숙고하여 진행하는 것이 좋습니다.

 

 

 

아파치 카프카 컨슈머와 리밸런싱
아파치 카프카 컨슈머와 리밸런싱

반응형

댓글