카프카를 구성하는 주요 요소
- 주키퍼(ZooKeeper): 아파치 프로젝트 애플리케이션 이름입니다. 카프카의 * 메타데이터(metadata) 관리 및 브로커의 정상상태 점검(health check)을 담당합니다.
- 카프카(Kafka) 또는 카프카 클러스터(Kafka cluster): 아파치 프로젝트 애플리케이션 이름입니다. 여러 대의 브로커를 구성한 클러스터를 의미합니다.
- 브로커(broker): 카프카 애플리케이션이 설치된 서버 또는 노드를 말합니다.
- 프로듀서(producer): 카프카로 메시지를 보내는 역할을 하는 클라이언트를 총칭합니다.
- 컨슈머(consumer): 카프카에서 메시지를 꺼내가는 역할을 하는 클라이언트를 총칭합니다.
- 토픽(topic): 카프카는 메시지 피드들을 토픽으로 구분하고, 각 토픽의 이름은 카프카 내에서 고유합니다.
- 파티션(partition): 병렬 처리 및 고성능을 얻기 위해 하나의 토픽을 여러 개로 나눈 것을 말합니다.
- 세그먼트(segment): 프로듀서가 전송한 실제 메시지가 브로커의 로컬 디스크에 저장되는 파일을 말합니다.
- 메시지(message)또는레코드(record):프로듀서가브로커로전송하거나컨슈머가읽어가는데이터조각을
말합니다. - 메타데이터: 데이터에 대한 데이터, 즉 데이터를 설명해주는 데이터이다.
카프카에서 리플리케이션
카프카에서 리플리케이션이란 각 메시지들을 여러 개로 복제해서 카프카 클러스터내 보르커들에 분산시키는 동작을 의미합니다. 덕분에 하나의 브로커가 종료되더라도 카프카는 안정성을 유지할 수 있습니다.
ex)
一partition 1, --replicatlon-factor 3
파티션 1개 생성 리플리케이션 3개 유지
정확하게 말하자면 카프카에서 토픽이 리플리케이션 되는것이 아니라 토픽의 파티션이 리플리케이션 되는 것입니다.
리플리케이셔니 많아질 수록 안정성은 높아지지만 그만큼 브로커 리소스를 많이 사용하게 됩니다.
- 테스트나 개발 환경: 리플리케이션 팩터 수를 1로 설정
- 운영 환경(로그성 메시지로서 약간의 유실 허용): 리플리케이션 팩터 수를 2로 설정
- 운영 환경(유실 허용하지 않음): 리플리케이션 팩터 수를 3으로 설정
위 상황이 정답은 아닙니다. 상황에 따라서 4나 5로 설정해도 되지만 리소스가 많이 소모 된다는점을 고려 해야 합니다.
파티션
하나의 토픽이 한번에 처리할 수 있는 한계를 높이기 위해 토픽 하나를 여러 개로 나눠 병렬 처리가 가능하게 만든 것을 파티션이라고 합니다. 하나를 여러 개로 나누면 분산 처리도 가능합니다.
나눠진 수 만큼 컨슈머를 연결할 수 있습니다.
파티션 수를 구하는 공식도 간혹 있습니다만, 각 메시지 크기나 초당 메시지 건수 등에 따라 달라지므로 정확하게 예측 하기는 어렵습니다. 특히 파티션 수는 초기 생성 후 언제든지 늘릴 수 있지만, 반대로 한 번 늘린 파티션 수는 절대로 줄일 수 없다는 점을 반드시 명심해야 합니다.
그렇기 때문에 초기에 파티션을 작개 생성을 해서 처치량이나 환경에 따라서 조금씩 늘려가는 방법이 가장 좋습니다.
- LAG : 프로듀서가 보낸 메시지 수 - 컨슈머가 가져간 메시지 수
파티션 수를 사정하기 위해 계산해주는 공식을 제공하는 사이트 - https://eventsizer.io
세그먼트
세그먼트는 파티션에서 좀 더 확장된 계념입니다. 예를 들어 프로듀서가 hi라고 메시지를 보내서 컨슈머를 이용해 hi를 읽을수 있게 됐다고 가정해 봅니다. 이때 카프카에서는 각 메시지들을 저장하는데 과연 어디에 저장되고 있을까요? 바로 토픽의 파티션에 저장되어 있습니다.
이처럼 프로듀서에 의해 브로커로 전송된 메시지는 토픽의 파티션에 저장되며 각 메시지들은 세그먼트라는 로그 파일의 형태로 브로커의 로컬 디스크에 저장됩니다.
그럼 hi를 보내는 통신과정에서 프로듀서가 카프카에 hi를 보내고, 토픽을 거쳐서 토픽내에 파티션에 배정이 되면 저장된파일이 생기고 저장된 메시지는 컨슈머가 읽어갈 수 있습니다.
카프카의 핵심 개념
카프카의 가장 큰 장점은 높은처리량, 빠른 응답 속도, 안정성 때문입니다. 어떤점 때문에 그럴 수 있을까요?
분산 시스템
분산 시스템은 네트워크 상에서 연결된 컴퓨터들의 그룹을 말합니다. 이는 단일 시스템이 갖지 못한 높은 성능을 목표로 합니다. 분산시스템은 성능이 높다는 장점 외에도 하나의 서버에서 장애가 발생할때 다른 서버에서 대신 처리를 할 수 있으므로 장애 대응이 탁월하며 부하가 높은 경우에 시스템 확장이 용이하다는 장점이 있습니다.
카프카는 분산시스템이므로 위와같은 장점을 가져 올 수 있었습니다.확장 용이
페이지 캐시
카프카가 높은 처리량을 얻기위해 추가한 기능들 중 가장 대표적인 것이 페이지 캐시의 이용입니다.
페이지 케시는 직접 디스크에 읽고 쓰는 무리 메모리 중 애플리케이션이 사용하지 않는 일부 잔여 메모리를 활용 합니다. 이렇게 페이지 캐시를 이용하면 디스크I/O에 대한 접근이 줄어들어서 성능을 높일 수 있습니다.
배치 전송처리
카프카는 프로듀서,컨슈머 클라이언트들과 서로 통신하며, 이들 사이에서 수많은 메시지를 주고 받습니다. 이때 발생하는 수많은 통신을 묶어서 처리할 수 있다면, 단건으로 통신할 때 비해 네트워크 오버헤드를 줄일 수 있을 뿐 아니라 장기적으로는 더욱 빠르고 효율적으로 처리할 수 있습니다.
예를 들어 온라인 상품 구매 프로세스에서 상품의 재고 수량 업데이트 작업은 지연없이 실시간으로 처리돼야 하지만 구매 로그를 저장소로 보내는 작업은 이미 로그가 서버에 기록되어 있으므로 실시간 처리 보다는 배치처리를 하는 것이 효율적일 것입니다. 카프카에서는 이러한 장점을 지는 배치 전송을 권장합니다.
압축 전송
카프카는 메시지 전송시 좀 더 성능이 높은 압축 전송을 사용하는 것을 권장합니다. 카프카에서 지원하는 압축 타입은 gzip,snappy,lz4,zstd등 입니다. 압축을 통해 네트워크 대역폭이나 회선 비용 등을 줄일 수 있습니다. 위 배치 전송처리와 결합해 사용하기때문에 더 좋은 시너지를 낼 수 있습니다.
토픽,파티션,오프셋
카프카는 토픽이라는 곳에 데이터를 저장하는데, 이는 우리가 흔히 사용하는 메일 전송시스템에서 이메일 주소 정도의 개념으로 이해하면 쉽습니다. 토픽은 병령 처리를 위해 여러 개의 파티션이라는 단위로 다시 나뉩니다. 이 파티션의 메시지가 저장되는 위치를 오프셋이라고 부르며 오프셋은 순차적으로 증가하는 숫자형태(64bit)로 돼 있습니다. 카프카에서는 오프셋을 통해 메세지 순서를 보장하고 컨슈머에서는 마지막까지 읽은 위치를 알 수도 있습니다.
고가용성 보장
카프카에서 제공하는 리프릴케이션 기능은 토픽 자체를 복제하는 것이 아니라 토픽의 파티션 을 복제하는 것입니다. 토픽을 생성할 때 옵션으로 리플리케이션을 구분하기 위해 흔히 마스터, 미러 같은 용어를 사용하는데 카프카에서는 리더와 팔로워라고 부릅니다.
이때 리더수는 1을 유지한체 팔로워수만 증가하게 됩니다. 그렇기 때문에 팔로워 수가 많다고 딱히 좋은것은 아닙니다. 팔로워 수만큼 결국 브로커의 디스크 공간도 소비가 되기때문에 이상적인 리플리케이션 팩터수를 유지해야 합니다. 카프카에서 권장하는 팩터수는 3입니다.
리더는 프로듀서,컨슈머로부터 오는 모든 읽기와 쓰기 요청을 처리하며 팔로워는 오직 리더로 부터 리플리케이션하게 됩니다.
주키퍼의 의존성
주키퍼는 카프카에서 코디네이터 역할을 하는 애플리케이션으로 사용되고 있습니다.
주키퍼는 여러대의 서버를 앙상블로(클러스터)로 구성하고 살아있는 노드 수가 과반수 이상 유지된다면 지속적인 서비스가 가능한 구조입니다. 따라서 주키퍼는 반드시 홀수로 구성해야 합니다.
znode를 이용해 카프카의 메타정보가 주키퍼에 기록되며 주키퍼는 이러한 지노드를 이용해 브로커의 노드관리 토픽관리 컨트롤러 관리등 매우 중요한 역할을 하고 있습니다.하지만 최근에 카프카의 성장세에 주키퍼의 한계가 들어나면서 카프카에서 주키퍼의 의존성을 제거하려고 노력중입니다.
프로듀서 디자인
ProducerRecord라고 표시된 부분은 카프카로 전송하기 위한 실제 데이터이며, 레코드는 토픽,파티션,키,벨류로 구성됩니다. 프로듀서가 카프카로 레코드를 전송할때 카프카의 특정 토픽으로 메시지를 전성합니다.
레코드에서 토픽과 벨류는 필숫값이며 특정파티션을 지정하기 위한 레코드의 파티션과 특정 파티션에 레코드들을 정령하기위한 레코드의 키는 필숫값이 아닌 선택사항입니다.
다음으로 레코드들은 프로듀서의 send()메소드를 통해 시리얼라이저,파티셔너를 거치게 됩니다. 만약 프로듀서 레코드의 선택사항인 파티션을 지정했다면, 파티셔너는 아무 동작도 하지 않고 지정된 파시션으로 레코드를 전달하는데, 기본적으로는 라운드 로빈 방식으로 동작합니다.
이렇게 프로듀서 내부에서는 send()메소드 동작 이후 레코드들을 파티션별로 잠시 모아두게 됩니다. 레코드들을 모아두는 이유는 프로듀서가 카프카로 전송하기전, 배치전송을 하기 위합입니다. 전송이 실패하면 재시도 동작이 이뤄지고 지정된 횟수만큼의 제시도가 실패하면 최종실패를 전달하며 전송이 성공하면 케타데이터를 리턴하게됩니다.
주요 프로듀서 옵션
- bootstrap.servers :카프카 클러스터는 클러스터 마스터라는 개념이 없으므로, 클러스터 내 모든 서 버가 클라이언트의 요청을 받을 수 있습니다. 클라이언트가 카프카 클러스터에 처음 연결하기 위한 호스트와 포트 정보를 나타냅니다.
- client.dns.lookup :하나의 호스트에 여러 IP를 매핑해 사용하는 일부 환경에서 클라이언트가 하 나의 ip와 연결하지 못할 경우에 다른 IP로 시도하는 설정입니다. use_all_ dns_ips가 기본값으로, DNS에 할당된 호스트의 모든 IP를 쿼리하고 저장합 니다. 첫 번째 IP로 접근이 실패하면. 종료하지 않고 다음 IP로 접근을 시도합 니다. 「esolve_canonlcal_bootstrap_se「ve「s_only 옵션은 커버로스 (Kerberos) 환경에서 FQDN을 얻기 위한 용도로 사용됩니다.
- acks:프로듀서가 카프카 토픽의 리더 측에 메시지를 전송한 후 요청을 완료하기를 결 정하는 옵션입니다.
0,1. allH)로 표현하며, 0은 빠른 전송을 의미하지만, 일부 메시지 손실 フt e 성이 있습니다. 1은 리더가 메시지를 받았는지 확인하지만. 모든 팔로워를 전부 확인하지는 않습니다. 대부분 기본값으로 1을 사용합니다. all은 팔로워가 메시 지를 받았는지 여부를 확인합니다. 다소 느릴 수는 있지만. 하나의 팔로워가 있 는 한 메시지는 손실되지 않습니다. - buffer.memory::프로듀서가 카프카 서버로 데이터를 보내기 위해 잠시 대フᅵ(배치 전송이나 딜레 이 등)할 수 있는 전체 메모리 바이트(byte)입니다.
- compression.type :프로듀서가 메시지 전송 시 선택할 수 있는 압축 타입입니다. none, gzip, snappy. Iz4, zstd 중 원하는 타입을 선택할 수 있습니다
- enable.idempotence : 설정을 true로 하는 경우 중복 없는 전송이 가능하며, 이와 동시에 max. in.flight.requests.per.connection^ 5 0|uK retries는 0 이상, acks는 a U 로 설정해야 합니다.
- max.in.flight.requests. per.connection :하나의 커넥션에서 프로듀서가 최대한 ACK 없이 전송할 수 있는 요청 수입니 다. 메시지의 순서가 중요하다면 1로 설정할 것을 권장하지만, 성능은 다소 떨어
집니다. - retries :일시적인 오류로 인해 전송에 실패한 데이터를 다시 보내는 횟수입니다.
- batch.size :프로듀서는 동일한 파티션으로 보내는 여러 데이터를 함께 배치로 보내려고 시 도합니다.적절한 배치 크기 설정은 성능에 도움을 줍니다.
- linger.ms :
배치 형태의 메시지를 보내기 전에 추가적인 메시지를 위해 기다리는 시간을 조 정하고,배치 크기에 도달하지 못한 상황에서 Unger.ms 제한 시간에 도달했 을 때 메시지를 전송합니다. - transactional.id :‘정확히 한 번 전송’을 위해 사용하는 옵션이며,동일한 T「ansactionalId에 한해 정확히 한 번을 보장합니다.옵션을 사용하기 전 enable, idempotence 를 true로 설정해야 합니다.
컨슈머의 기본 동작
프로듀서가 카프카의 토픽으로 메시지를 전송하면 해당 메시지들은 브로커들의 로컬 디스크에 저장됩니다. 그리고 우리는 컨슈머를 이용해 토픽에 저장된 메시지를 가져올 수 있습니다. 컨슈머는 하나이상의 컨슈머들이 모여있는 그룹에 반드시 속하게 됩니다. 그리고 이컨슈머 그룹은 각 파티션의 리더에게 카프카토픽에 저장된 메시지를 가져오기 위한 요청을 보냅니다. 이때 파티션 수와 컨슈머수는 일대일로 매핑되는 것이 이상적입니다. 파티션 수 보다 컨슈머수가 많게 구현하는 것은 바람직한 구성이 아닙니다.
컨슈머의 주요 옵션
컨슈머를 사용하는 목적이 최대한 안정적이며 지연이 없도록 카프카로부터 메시지를 가져오는 것인데, 이를 위한 옵션을 잘 이해하고 사용해야만 자신이 원하는 형태로 컨슈머가 동작할 것입니다.
- bootstrap.servers :프로듀서와 동일하게 브로커의 정보를 입력합니다.
- fetch.min.bytes:한 번에 가져올 수 있는 최소 데이터 크기입니다.만약 지정한 크기 보다 작은 경우,요청에 응답하지 않고 데이터가 누적될 때까지 기 다립니다.
- group.id :컨슈머가 속한 컨슈머 그룹을 식별하는 식별자입니다.동일한 그룹 내의 컨슈머 정보는 모두 공유됩니다.
- heartbeat.interval.ms:하트비트가 있다는 것은 컨슈머의 상태가 active임을 의미합니 다.session.timeout.ms와 밀접한 관계가 있으며,session, timeout.ms보다 낮은 값으로 설정해야 합니다.일반적으로 session.timeout.ms의 1/3로 설정합니다.
- max•partition.fetch•bytes: 파티션당 가져올 수 있는 최대 크기를 의미합니다.
- session.timeout.ms :이 시간을 이용해,컨슈머가 종료된 것인지를 판단합니다.컨슈머는 주기적으로 하트비트를 보내야 하고,만약 이 시간 전까지 하트비트 를 보내지 않았다면 해당 컨슈머는 종료된 것으로 간주하고 컨슈머 그룹에서 제외하고 리밸런싱을 시작합니다.
- enable.auto.commit :백그라운드로 주기적으로 오프셋을 커밋합니다.
- auto.offset.reset: 카프카에서 초기 오프셋이 없거나 현재 오프셋이 더 이상 존재하지 않는 경우에 다음 옵션으로 reset합니다.
•earliest: 가장 초기의 오프셋값으로 설정합니다. •latest:가장 마지막의 오프셋값으로 설정합니다. •none:이전 오프셋값을 찾지 못하면 에러를 나타냅니다 - fetch.max.bytes : 한 번의 가져오기 요청으로 가져올 수 있는 최대 크기입니다.
- group.instance.id: 컨슈머의 고유한 식별자입니다.만약 설정한다면 static 멤버로 간주되어,불필요한 리밸런싱을 하지 않습니다.
- Isolation.level :트랜잭션 컨슈머에서 사용되는 옵션으로,read_uncommitted는 기본값으로 모든 메시지를 읽고,「ead_committed는 트랜잭션이 완료된 메시지만 읽습니다.
- max.poll.records :한 번의 polA()요청으로 가져오는 최대 메시지 수입니다.
- partition.assignment.strategy :파티션 할당 전략이며,기본값은 range입니다.
- fetch.max.watt.ms :fetch.mln.bytes에 의해 설정된 데이터보다 적은 경우 요청에 대한 응답을 기다리는 최대 시간입니다.
'kafka' 카테고리의 다른 글
카프카의 내부 동작 원리 (1) | 2023.10.19 |
---|---|
카프카 도입 컷트라인 (0) | 2023.10.19 |
카프카 환경 구성 (0) | 2023.10.19 |
카프카 공부노트/주요특징 (1) | 2023.10.19 |
카프카 공부노트/개요편 (1) | 2023.10.19 |