카프카의 기본 개념과 구조를 보고,
카프카의 처리량을 높이기 위해 설계된 분산 시스템, 페이지 캐시, 배치 전송을 본 후
주키퍼 역할도 봐보자.
- 카프카 기본 개념 구조
- 분산 시스템
- 페이지 캐시
- 배치 전송
리플리케이션
각 메시지들을 복제해서 클러스터내 브로커들에 분산시킨다.
브로커가 하나 종료 되더라도 안전하게 유지 가능.
--partition 1, --replication-factor 3
replication-factor 는 몇개의 리플리케이션을 유지할지 의미다.
3이면 원본을 포함한 복제본이 3개가 있다는 뜻.
(토픽의 파티션이 복제되는것.)
복제 수가 크면 안전하긴 하지만, 리소스를 많이 사용한다.
3일 경우가 꽤 안정적이었다.
파티션
하나의 토픽이 한번에 처리할수있는 한계 때문에
하나의 토픽을 여러개로 나눠서 병렬처리가 가능하게 나눈것이다.
이 파티션 덕에 분산처리가 가능해진다.
파티션 수를 정하는 기준은 모호하다.
메시지크기, 초당 메시지 건수등에 따라 달라져서 정확히 예측 하기 힘듬.
또 파티션수는 늘릴수는 있지만 줄일수는없다.
그러니 처음엔 2, 4 로 작게 시작해서 조금씩 늘리는게 좋다.
컨슈머의 LAG 을 보고 판단...
LAG? 프로듀서가 보낸 메시지수 - 컨슈머가 가져간 메시지 수
컨슈머에 지연이 없는지 확인 할 수 있다.
세그먼트
프로듀서를 이용해 카프카에 메시지를 전송하고, 컨슈머가 메시지를 읽을 수 있다.
그리고 카프카에는 메시지들을 저장한다.
그럼 처음에 프로듀서에서 보내본 "FIRST MESSAGE" 는 어디에 저장될까?
토픽의 파티션0에 저장이 되어있는데, 여기서 각 메시지들은 세그먼트 라는 로그 파일의 형태로 로컬 디스크에 저장이 된다.
실제 data 폴더의 카프카 로그로 가보면
세그먼트 파일이 0000~.log 로 만들어져있고 해당 파일을 xxd 명령어로 hexdump 를 보면 프로듀서에서 보낸 메시지를 확인 할 수 있다.
여기까지 정리해보면
1. 프로듀서는 카프카의 토픽으로 메시지 전송
2. 토픽은 파티션이 하나밖에 없으니까 프로듀서로부터 받은 메시지를 파티션0의 세그먼트 로그 파일로 저장. 만약 파티션이 2개 엮으면 1번 파티션도 추가돼서 거기에 로그가 있었을것.
3. 브로커의 세그먼트 파일에 저장된 메시지는 컨슈머가 읽어갈수있다.
카프카의 핵심 개념
카프카의 높은 처리량, 빠른 응답 속도 안전성 덕에 많이 사용된다.
근데 왜 그렇게 안정적이고 높은 처리량을 갖을까?
분산 시스템
네트워크로 연결된 컴퓨터 그룹.
높은 성능을 목표로 한다.
성능이 높다는 점 뿐만아니라 하나의 서버가 장애가 발생해도 다른 서버에서 처리해서 장애 대응이 좋다.
카프카도 분산처리 시스템이라 리소스가 한계에 도달하면 브로커를 추가해서 스케일 아웃 할수있다.
확장이 용이하다!
페이지 캐시
높은 처리량을 위해 대표적인 기능이 캐시다.
OS는 성능을 높이기 위해 페이지 캐시를 자주 사용하는데
카프카 역시 OS의 페이지 캐시를 활용한다.
디스크에 접근하지 않고 메모리를 사용해 성능을 높인다.
배치 전송 처리
수많은 메시지를 주고 받기때문에, 한번에 수많은 통신을 묶어서 처리해 네트워크 오버헤드를 줄일수있다.
상품의 재고 수량 업데이트 작업과, 구매 로그를 저장소로 보내는 작업이 있다면,
수량 업데이트는 실시간 처리 돼야 하지만, 로그 저장은 배치로 처리해서 성능을 향상시킨다.
압축전송
좀 더 성능이 높은 압축 전송을 사용하는 것을 권장.
카프카가 지원하는 압축 타입은 gzip, snappy, lz4 zstd 등 있다.
압축만으로도 네트워크 대역폭, 회선 비용을 줄일 수 있다.
높은 압축률이 필요한 경우라면 gzip, zstd
빠른 응답 속도는 lz4 나 snappy 가 권장됨.
토픽 파티션 오프셋
카프카는 토픽에 데이터를 저장하는데, 이게 흔히 메일 전송 시스템의 이메일 주소 정도의 개념이다.
토픽은 여러 파티션으로 나뉘고
이 파티셔닝을 통해 높은 처리량 수행가능하다.
이 파티션의 메시지가 저장되는 위치를 오프셋이라고 함.
0,1,2,....
오프셋은 파티션마다 고유한 값이고, 오프셋을 통해 메시지의 순서를 보장하고 컨슈머에서는 마지막까지 읽은 위치를 알 수 있음.
고가용성 보장
리플리케이션을 통해 안전성을 보장한다.
토픽의 파티션을 복제한다.
원본을 리더 복제본을 팔로워라고 부른다.
리플리케이션 수가 많다고 좋진 않음. 위에 설명한거처럼 3개정도가 적당.
주키퍼의 의존성
주키퍼는 분산 어플리케이션의 코디네이터 역할을 하는 어플리케이션으로 많이 사용된다.
주키퍼는 여러 서버를 클러스터로 구성한다.
지노드를 이용해 카프카의 메타 정보가 주키퍼에 기록되고, 주키퍼는 이걸 이용해
브로커의 노드 관리, 토픽 관리 , 컨트롤러 관리 등을 한다.
요새는 카프카가 주키퍼의 의존성을 없애려고 하고 있고 현재는 주키퍼가 삭제된 버전이 릴리스된다.
프로듀서의 기본 동작
프로듀서는 카프카의 토픽으로 메시지를 전송한다.
프로듀서는 여러 옵션을 제공하니 원하는 형태로 다양하게 보낼수있다.
프로듀서 디자인.
ProducerRecord 가 실제 데이터.
레코드는 토픽, 파티션, 키 밸류로 구성.
프로듀서가 카프카로 보낼때 특정 토픽에 메시지를 보낸다.
토픽과 메시지 내용인 value 는 필수값.
특정 파티션을 지정하기 위한 파티션과, 레코드들을 정렬하기 위한 key 는 선택사항임.
그 후에 send() 메소드를 통해 시리얼라이저, 파티셔너를 거치게 된다.
만약 파티션 옵션을 넣었으면 파티셔너는 동작 안하고 특정 파티션으로 가게됨.
파티셔너는 기본적으로 라운드로빈으로 동작한다.
프로듀서는 카프카로 전송하기 전에 잠시 데이터를 모았다가 배치 전송을 하게 된다.
프로듀서의 자세한 옵션들은 책에서 보기.
기본값으로 사용하는 경우가 많다.
프로듀서 예제
프로듀서 전송 방법은
-'메시지 보내고 확인하지 않기'
-'동기 전송'
-'비동기 전송'
이렇게 3가지 방법이 있다.
예제는 책에서 확인.
메시지 보내고 확인하지 않기는 send() 메서드 후 return 값을 확인 하지 않아서
권장 되지 않는 방법이고,
동기전송은
send는 Future 다.
send().get 을 통해 응답을 기다리고 성공 했는지 실패했는지 여부를 확인한다.
이 방식은 신뢰성 있는 메시지 전달 과정이 핵심.
비동기 전송은
send 에 콜백을 함계 호출 하는것.
빠른 전송이 가능하고 실패한 경우 예외 처리나 로그 등에 기록할수있다.
컨슈머의 기본동작
컨슈머는 메시지를 가져오는 역할.
간단해보이지만, 내부적으로는 컨슈머 그룹, 리밸런싱 등 여러 동작을 수행한다.
옵션을 잘 활용하자.
프로듀서가 아무리 빨라도 컨슈머가 느리면 지연이 발생하니 컨슈머 역할이 중요하다.
컨슈머의 기본 동작.
프로듀서가 메시지를 전달하면, 브로커들의 로컬 디스크에 저장된다.
그럼 컨슈머를 이용해서 토픽에 저장된 메시지들을 가져올수있다.
컨슈머 그룹은 하나 이상의 컨슈머들이 모여있는 그룹이다.
이 컨슈머 그룹은 각 파티션 리더에 카프카 토픽에 저장된 메시지를 가져오기 위한 요청을 보낸다.
이때 파티션 수랑 컨슈머 수가 1대1 매칭 되는게 이상적이다.
컨슈머가 더 많으면 이상적이진 않다. 더 빨라지지도 않고 그냥 대기 상태로 존재하기 때문.
어떻게 처리하냐에 따라
컨슈머 동작에서 메시지의 중복, 유실등 여러 상황이 발생할수있다.
최대한 안정적이고 지연이 없게 메시지를 가져오는게 중요. 옵션들을 잘 활용하자.
컨슈머 예제
컨슈머에서 데이터를 가져오는데는 크게 3가지가 있다.
- 오토 커밋
- 동기 가져오기
- 비동기 가져오기
오토 커밋은 기본값으로 가장 많이 사용되는 값이다.
오토 커밋은 오프셋을 주기적으로 커밋해서 (poll) 오프셋을 따로 관리 하지 않아도 되는 장점이 있다.
대신 컨슈머 종료 등이 빈번히 일어나면, 일부 메시지를 못 가져오거나 중복으로 가져오는 경우가 있다.
하지만 카프카가 안정적으로 잘 동작하고 컨슈머도 한번 구동 후 자주 변경되거나 종료 되지 않으니
이 방법을 많이 사용한다.
동기 방식으로 가져오는 방법은 consumer.commitSync()
메시지를 가져온 후 처리까지 완료하고 현재의 오프셋을 커밋한다.
속도는 느리지만 메시지 손실이 거의 없다.
손실되면 안되는 중요한 처리 작업들을 할때 사용
비동기 방식은 consumer.commitAsync()
오프셋 커밋이 실패하더라도 재시도 하지 않는다.
왜 재시도를 안하냐면 1~5번 작업 비동기 방식으로 보냈는데,
1번만 성공을 하고 2,3,4는 실패 후 5번이 성공했을때
2번이 만약 재시도를 해서 성공을 하게 되면 2번이 마지막 오프셋이라고 저장이 되고
다른 컨슈머는 3번부터 가져가게된다.
이런 문제로 비동기는 재시도 하지 않는다.
이걸 보완하기 위해 콜백을 같이 사용한다.
컨슈머 그룹의 이해
컨슈머는 컨슈머 그룹안에 속해있다.
하나의 그룹에 여러 컨슈머가 있을수있다.
컨슈머는 파티션과 1대1 매핑되어 메시지를 가져온다.
'데이터처리 > kafka' 카테고리의 다른 글
카프카의 내부 동작 원리와 구현 (0) | 2022.08.04 |
---|---|
kafka - Quick Start 카프카 실습 따라해보기 (0) | 2020.04.22 |
Apache- Zookeeper 를 알아보자 (0) | 2020.04.22 |