티스토리 뷰
"실전 카프카 개발부터 운영까지" - 고승범 지음
https://book.naver.com/bookdb/book_detail.nhn?bid=21149337
실전 카프카 개발부터 운영까지
아파치 카프카의 공동 창시자 준 라오(Jun Rao)가 추천한 책!국내 최초이자 유일한 컨플루언트 공인 아파치 카프카 강사(Confluent Certified Trainer for Apache Kafka)와 공인 관리자 자격(Confluent Certified Admini
book.naver.com
실무에서 kafka를 사용중인데, 제대로 알고 쓰고자 스터디를 시작했다.
공부한내용 정리 목적으로 블로그에 기록을 남긴다.
📌1주차 목차
1장 카프카 개요
2장 카프카 환경 구성
3장 카프카 기본 개념과 구조
1장 카프카 개요
📝카프카의 특징
✔높은 처리량과 낮은 지연시간
카프카 vs 래빗 MQ
처리량이 높은것은 카프카, 응답속도가 빠른것은 래빗MQ
하지만, 처리량과 응답속도 같이 비교했을 때는 카프카가 독보적
✔높은 확장성
✔고가용성
✔내구성
컨슈머가 메시지를 가져가더라도 삭제X, 설정 시간 또는 로그의 크기만큼 로컬 디스크에 보관된다.
코드의 버그나 장애가 발생해도 과거 메시지 불러와 재처리가 가능하다.
📍추가 개념
람다 아키텍처 : 배치 파이프라인과 실시간 파이프라인이 있는 것을 말함.
배치와 스트림 처리의 장점을 지닌다.
2장 환경 구성
다른 글에 실습내용 정리 예정
3장 카프카 기본 개념과 구조
📝카프카를 구성하는 주요 요소
✔주키퍼 : 아파치 애플리케이션 이름. 카프카의 메타데이터 관리, 브로커의 정상상태 점검을 담당한다.
✔카프카 or 카프카 클러스터 : 아파치 프로젝트 애플리케이션 이름이다. 여러대의 브로커를 구성한 클러스터를 의미한다.
✔브로커 : 카프카 애플리케이션이 설치된 서버 또는 노드를 말한다.
✔프로듀서 : 카프카로 메시지 보내는 역할을 하는 클라이언트
✔컨슈머 : 카프카에서 메시지를 꺼내가는 역할을 하는 클라이언트
✔토픽 : 카프카는 메시지 피드들을 토픽으로 구분하고, 각 토픽의 이름은 카프카 내에서 고유하다.
✔파티션 :
병렬 처리 & 고성능을 얻기 위해 하나의 토픽을 여러 개로 나눈 것을 말한다.
나뉜 파티션 수만큼 컨슈머 연결 할 수 있다.
파티션 수는 초기 생성 후 언제든 늘릴 수 있으나, 한번 늘린 파티션 수는 줄일 수 없다.
✔세그먼트 : 프로듀서가 전송한 실제 메시지가 브로커의 로컬 디스크에 저장되는 파일을 말한다.
✔메시지 or 레코드 : 프로듀서가 브로커로 전송하거나 컨슈머가 읽어가는 데이터 조각을 말한다.
📝리플리케이션
메시지들을 여러 개로 복제해서 카프카 클러스터 내 브로커들에 분산시키는 동작을 말한다.
하나의 브로커가 종료되어도 카프카는 안정성을 유지한다. (고가용성)
📝세그먼트
브로커로 전송된 메시지는 토픽의 파티션에 저장된다.
각 메시지는 세그먼트라는 로그 파일의 형태로 브로커 로컬 디스크에 저장된다.
📝카프카의 핵심 개념
✔분산 시스템
✔페이지 캐시
카프카는 높은 처리량을 위해 몇 가지 기능을 추가했는데, 그중 대표적인것이 '캐시' 이용이다.
페이지 캐시는 직접 디스크에 읽고 쓰는 대신 물리 메모리 중 애플리케이션이 사용하지 않는 일부 잔여 메모리를 활용한다.
디스크 I/O에 대한 접근이 줄어들어 성능 향상된다.
카프카가 직접 디스크에 읽기 쓰기 하지 않는다. 페이지 캐시를 통해 읽기 쓰기 한다고 생각하면 된다.
✔배치 전송 처리
✔압축 전송
✔토픽, 파티션, 오프셋
파티션의 메시지가 저장되는 위치를 오프셋이라 부른다.
오프셋은 순차적으로 증가하는 숫자 형태로 되어있다.
오프셋을 통해 메시지 순서를 보장하고, 컨슈머에서는 마지막 읽은 위치를 알 수 있다.
✔고가용성 보장
고가용성을 위해 리플리케이션 기능을 제공한다.
토픽 자체를 복제하는 것이 아니라 토픽의 파티션을 복제 하는 것이다.
리플리케이션을 구분하기 위해 리더, 팔로워라고 부른다. (리더의 수는 1로 유지)
✔주키퍼 의존성
주키퍼는 여러 대의 서버를 앙상블로 구성하고, 살아 있는 노드 수가 과반수 이상 유지된다면 지속적인 서비스가 가능한 구조이다.
주키퍼는 반드시 홀수로 구성한다.
📝프로듀서
<공통적인 큰 로직>
1. Properties 객체 생성
2. 브로커 리스트 정의
3. 메시지 키 밸류 문자열타입이므로 카프카 기본 StringSerializer지정
4. Properties 객체 전달해 새 프로듀서 생성 new KafkaProducer<>(properties);
5. ProducerRecord 객체 생성
6. send()메소드
✔메시지 보내고 확인하지 않기
/*
6.
send()메소드로 메시지 전송한 후 자바 Future 객체로 RecordMetadata 리턴받지만,
리턴값 무시함. 메시지 성공적으로 전송됐는지 알 수 없음
*/
producer.send(record)
/*
7.
카프카 브로커에게 메시지 전송한 후의 에러는 무시
전송 전에 에러 발생했다면 예외 처리 가능
*/
e.printStackTrace()
/*
8.
프로듀서 종료
*/
producer.close();
운영에서 추천하지 않음.
✔동기 전송
/*
get() 메소드를 이용해 카프카 응답을 기다린다.
메시지 성공적으로 전송되지 않으면 예외 발생
에러없으면 RecordMetadata 얻는다.
*/
RecordMetadata metadata = producer.send(record).get()
동기 전송은 신뢰성 있는 메시지 전달과정의 핵심이다.
✔비동기 전송
/*
프로듀서에서 레코드를 보낼 때 콜백 객체를 같이 보낸다.
*/
producer.send(record, new PeterProducerCallback(record));
동기방식 처럼 모든 메시지에 대한 응답을 기다리면 많은 시간을 소비하게 된다.
비동기방식으로 빠른 전송을 하고, 전송 실패시 예외처리 하여 에러 로그를 기록한다.
📝컨슈머
컨슈머 수가 많다고 바람직한 구성이 아니다.
컨슈머는 리밸런싱 동작을 통해 장애가 발생한 컨슈머의 역할을 동일 그룹 내의 다른 컨슈머가 대신 수행하도록 한다.
✔오토 커밋
props.put("enable.auto.commit", "true"); //백그라운드로 주기적 오프셋 커밋
props.put("auto.offset.reset", "latest"); //가장 마지막 오프셋으로 reset
✔동기 가져오기
props.put("enable.auto.commit", "false");
props.put("auto.offset.reset", "latest"); //가장 마지막 오프셋으로 reset
while{
...
}
consumer.commitSync();
//배치를 통해 읽은 모든 메시지 처리 한 후, '추가 메시지 폴링하기전' 현재 오프셋 동기 커밋
//메시지 손실되면 안될때 동기 방식 사용
✔비동기 가져오기
props.put("enable.auto.commit", "false");
props.put("auto.offset.reset", "latest"); //가장 마지막 오프셋으로 reset
while{
...
}
consumer.commitAsync();
//배치를 통해 읽은 모든 메시지 처리 한 후, '추가 메시지 폴링하기전' 현재 오프셋 비동기 커밋
//메시지 손실되면 안될때 동기 방식 사용
오프셋 커밋을 실패하더라도 재시도 하지 않는다. 그이유는?
1번 오프셋 성공(현재 마지막 오프셋 1)
2번 오프셋 실패(현재 마지막 오프셋 1)
3번 오프셋 실패(현재 마지막 오프셋 1)
4번 오프셋 성공 비동기 커밋(현재 마지막 오프셋4)
이 상태에서 재시도를 한다면 4번 커밋완료 후 2번 오프셋 재시도 성공한다면 마지막 오프셋은 2로 변경된다.
만일 현재의 컨슈머가 종료되고 다른 컨슈머가 이어서 작업한다면 다시 3번부터 메시지를 가져오게 될것이고 중복이 발생한다.
'Kafka' 카테고리의 다른 글
kafka study 2주차 : 내부 동작 원리와 구현(2) (0) | 2022.04.25 |
---|---|
kafka study 2주차 : 내부 동작 원리와 구현(1) (0) | 2022.04.25 |