티스토리 뷰

Backend/Kafka

Kafka의 Topic과 Partition

out of coding 2019. 12. 7. 10:31

이전에 제가 이전에 공부한다고 여기저기서 보고 정리했던 워드 문서에서 주워 오는거라...

정리가 미흡합니다. 그냥 쉽게 보시기 바랍니다.

 

  • Kafka는 topic의 Partition이라는 단위로 쪼개서 클러스터의 각 서버들에 분산되어 저장됩니다. 뭔소린지 ㅎ 만약 고가용성을 위해서 복제 설정을 하게 되면 이것 또한 Partition 단위로 각 서버들에 분산되어 복제되고 장애가 발생하면 Partition 단위로 fail over가 수행됩니다.
  • 각 Partition은 0부터 1씩 증가하는 offset 값을 메시지에 부여하는데 이 값은 각 Partition내에서 메세지를 식별하는 ID로 사용되게 됩니다. offset 값은 Partition마다 별도로 관리되므로 topic 내에서 메시지를 식별할 때는 Partition 번호와 offset 값을 함께 사용합니다.
  • Partition의 분산과 복제
    • 분산
      • 3개의 Broker로 이루어진 Cluster에서는 하나의 topic이 3개의 Partition 형태로 분산되어 저장되게 됩니다.
      • Producer가 메시지를 실제로 어떤 Partition으로 전송할지는 사용자가 구현한 Partition 분배 알고리즘에 의해 결정되게 되는데요. 예를 들어 라운드로빈 방식으로 Partition 분배 알고리즘을 구현하여 각 Partition에 메시지를 균등하게 분배하도록 하거나 메시지의 키를 활용하여 알파벳 앞자리로 시작하는 키를 가진 메시지는 한곳에 넣는 방식으로 구성도 가능합니다.
      • 다른 적절하게 분배하는 방식에 대해서는 CRC32값을 Partition 수로 연산을 하여서 동일한 ID에 대한 메시지는 동일한 Partition에 할당되도록 구성도 가능합니다. 공식. CRC32(ID) % Partition
    • 복제
      • 고가용성을 위해서 각 Partition을 복제하여 클러스터에 분산 시킬수 있습니다.
      • 그냥 같은 데이터를 복제하는것이 되는데요. 이것을 추후에 사용할 때 가져다가 사용하는데 어디에서 가져다가 사용해야 할지에 대해서는 약간 의문이 들기는 합니다.
      • 그래서 구성은 Relication factor를 N으로 설정하고 N개의 replica는 1개의 Leader와 N-1개의 Follower로 구성이 되게 됩니다. 이렇게 구성을 하고 Leader에 장애가 발생하게 된다면 Follower에서 새로운 Leader를 만들어 주게 됩니다. 그래서 Kafka는 복제 모델인 ISR 모델은 이론상 f+1개의 replica를 가진 topic은 f개의 장애까지 버틸 수 있도록 되어 있습니다.
      • 그리고 저도 의문을 가진 부분인데 Leader에서만 읽기와 쓰기를 수행한다고 하면 부하 분산이 안 일어날것 같았습니다. 한쪽에 쏠려 버릴수 있기 때문이죠. 그렇지만 각 Partition의 Leader가 클러스터내의 Broker들에 균등하게 분배되도록 알고리즘이 설계되어 있기 때문에 부하는 자연스럽게 분산이 된다고 합니다.
  • Consumer와 Consumer Group
    • 일반적으로 메시징 모델은 두가지로 나눌수 있다고 합니다.
      • Queue : 메시지가 쌓여있는 Queue로 부터 메시지를 가져와서 Consumer Pool에 있는 Consumer 중 하나에 메시지를 할당하는 방식
      • Publish-Subscribe(발행-구독) : topic을 구독하는 모든 Consumer에게 메시지를 브로드 캐스팅하는 방식
    • Kafka는 Consumer Group이라는 개념을 도입하였고 위의 두가지 모델을 발행-구독 모델로 일반화 하였다고 합니다.
    • Kafka의 Partition은 Consumer group 당 오로지 하나의 Consumer의 접근만을 허용하며, 해당 Consumer를 Partition Owner이라고 부르는데요. 따라서 동일한 Consumer group 내의 Consumer들의 Partition 재분배가 발생하고 Broker가 추가/제거 되면 전체 Consumer group에서 Partition 재분배가 일어나게 된다고 합니다.
    • 한번 정해진 Partition Owner는 Broker나 Consumer 구성의 변동이 발생하기 전까지는 계속 유지가 됩니다. 그럼 언제 변경이 되느냐 Consumer가 추가/제거 되게 되면 이런 일이 발생하게 되는데요. 추가/제거 된 Consumer가 속한 Consumer group 내의 Consumer들의 Partition 재분배가 발생하고 Broker가 추가/제거되면서 전체 Consumer group에서 Partition 재분배가 발생하게 된다고 합니다.
    • Consumer group을 구성하는 consumer의 수가 partition의 수보다 작으면 하나의 consumer가 여러 개의 partition을 소유하게 되고, 반대로 consumer의 수가 partition의 수보다 많으면 여분의 consumer는 메시지를 처리하지 않게 되므로 partition 개수와 consumer 수의 적절한 설정이 필요합니다.
    • consumer group에 다수의 consumer를 할당하면 각 consumer마다 별도의 partition으로부터 메시지를 받아오기 때문에 (producer가 각 partition에 메시지를 균등하게 분배한다고 가정할 경우) consumer group은 큐 모델로 동작하게 됩니다.
    • 단일 consumer로 이루어진 consumer group을 활용하면 다수의 consumer가 동일한 partition에 동시에 접근하여 동일한 메시지를 액세스하기 때문에 발행-구독 모델을 구성할 수 있습니다. 이처럼 하나의 consumer에 의하여 독점적으로 partition이 액세스 되기 때문에 동일 partition 내의 메시지는 partition에 저장된 순서대로 처리된다. 만약 특정 키를 지닌 메시지가 발생 시간 순으로 처리 되어야 한다면 partition 분배 알고리즘을 적절하게 구현하여 특정 키를 지닌 메시지를 동일한 partition에 할당되어 단일 consumer에 의해 처리되도록 해야 합니다. 그러나 다른 partition에 속한 메시지의 순차적 처리는 보장되어 있지 않기 때문에, 특정 topic의 전체 메시지가 발생 시간 순으로 처리되어야 할 경우 해당 topic이 하나의 partition만을 가지도록 설정해야 합니다.
  • 파일 시스템을 활용한 고성능 디자인
    • 저는 솔찍히 정확하게는 이해가 안되긴 합니다만 하드디스크를 순차적으로 읽어들이는 방식에 대해서도 찾아봐야 할거 같습니다. 자기 테이프 같은 경우는 순차적인데 이것도 순차적이라니... 이 부분은 조금 더 찾아보고 다른 글에서 다루도록 할게요.
    • 앞에서도 이야기 했듯이 Kafka는 메모리 대신 파일 시스템에 메시지를 쌓아두고 관리를 합니다. 주 저장소의 속도를 생각해보면 메모리에 올리는 방식이 당연히 성능이 좋습니다. 그렇지만 Kafka의 메세지는 하드 디스크로부터 순차적으로 읽혀지기 때문에 하드 디스크의 랜덤 읽기 성능에 대한 단점을 보완하고 동시에 OS페이지 캐시를 효과적으로 활용 할 수 있습니다.
    • 메시지를 파일 시스템에 저장함으로써 얻는 부수적인 효과도 있는데 메시지를 메모리에 저장하지 않기 때문에 메시지가 JVM 객체로 변환되면서 크기가 커지는 것을 방지할 수 있고 JVM의 GC로 인한 성능 저하 또한 피할 수 있습니다. 이건 정말 굿.
    • 또한 Kafka 프로세스가 직접 캐시를 관리하지 않고 OS에 위임하기 때문에 프로세스를 재시작하여도 OS의 페이지 캐시는 그대로 남아 있기 때문에 프로세스 재시작 후 캐시의 워밍업이 필요하지 않게 됩니다. 뭐 물론 OS가 재부팅 되면 소용없겠지만...
    • 그리고 가장 핫한 부분인 파일 시스템에 저장된 메시지를 네트워크를 통해 consumer에게 전송할 때 zero-copy 기법을 사용하여 데이터 전송 성능을 향상 시킨다고 합니다. 뭐 기술 하나에 다른 기술의 집약체를 넣었다고 보면 되겠네요. 역시나 재미있습니다. 유저모드로 카피된 데이터를 어플리케이션에서 처리한 뒤 처리된 데이터를 네트워크로 전송한다면 커널모드와 유저모드간의 데이터 복사가 당연히 발생하게 된다고 합니다. 그러나 어플리케이션에서의 별도 처리 없이 파일 시스템에 저장된 데이터 그대로 네트워크로 전송만 한다면 커널모드와 유저모드 간의 데이터 복사는 불필요한 것이 되고 이것으로 인해 성능 향상을 이루게 되는 겁니다. 이 방법은 벤치마크에 따로면 전송 속도가 2~4배 빠르게 나온다고 합니다.

저도 아직까지는 잘 모르는 Kafka지만 더 배우는게 있으면 글 남기겠습니다.

'Backend > Kafka' 카테고리의 다른 글

Kafka란 무엇인가...  (0) 2019.12.07
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함