이전에는 데이터를 전송하는 소스 어플리케이션과 데이터를 받는 타겟 어플리케이션이 존재하는 단방향 통신을 사용했다. 하지만 시간이 지나면서 소스어플리케이션과 타겟 어플리케이션이 많아지면서 데이터를 전송하는 라인이 많아졌다. 이로 인해 데이터를 전송할 때 프로토콜, 포맷의 파편화가 심해지고, 배포와 장애에 대응하기가 힘들어지면서 유지보수또한 어려움을 겪게 되는 복잡한 상황이 나왔다. 이런 복잡한 상황을 해결하기 위해 Kafka가 등장했다. 또한, 서버가 이슈가 생기거나 갑작스럽게 렉이 내려가도 복구하기 쉽고, 낮은 지연과 높은 처리량으로 많은 데이터를 처리할 수 있다. 이런 빅데이터 처리 시대에서는 카프카를 안 쓰이는 곳이 없다. 운영상 특징으로 알만한 모든 기업들은 카프카를 쓰고 있다.
Kafka 개발 전 LinkedIn 데이터 처리 시스템
Kafka 개발 후 LinkedIn 데이터 처리 시스템
카프카(Kafka)란?
Kafka
분산형 스트리밍 플랫폼(A distributed streaming platform)
Kafka의 목표
높은 처리량, 낮은 지연시간을 지닌 플랫폼을 제공하는 것
HOW? 소스 어플리케이션(Kafka Producer)에서 데이터(ex. 클릭로그, 결재로그)를 Kafka에 있는 Topic에 전송하면 타겟 어플리케이션(Kafka Cumsumer)은 그 데이터(ex. 로그적재, 로그처리)를 가져오기만 하기에 처리량이 올라가고, 지연시간은 낮아진다.
특징
1. 소스 어플리케이션에서 보내는 데이터 포맷의 제약이 거의 없다.(json, tsv, avro 등)
2. 큐(queue) 역할을 하는 *Topic이라는 개념이 존재한다. 이 Topic은 데이터베이스의 테이블과 파일시스템의 폴더와 유사한 성질을 가지고 있다.
3. 대용량 실시간 로그처리에 특화되어 설계된 메시징 시스템으로 TPS가 매우 우수하다.
4. 메시지를 메모리에 저장하는 기존 메시징 시스템과는 달리 파일에 저장을 하는데 그로 인해 카프카를 재시작해도 메시지 유실 우려가 감소된다.
구성요소
Topic : Kafka에 저장되는 메시지는 topic으로 분류되며 click_log, send_sms, location_log 같이 이름을 가질 수 있어 관리하기 좋다. topic 내부는 여러 파티션을 가지고 있다. 파티션은 추가는 가능하지만, 삭제는 못한다.
Partition : partition안에는 message의 상대적 위치를 내타내는 offset이 있다. offset은 0번부터 있고 파티션 끝부터 차곡차곡 데이터가 쌓인다. 그렇기에 컨슈머는 이 데이터를 오래된 순서대로 가져가며, 파티션에 데이터가 빠지지 않기 때문에 데이터를 두 번 사용할 수 있다. 예를 들면, 클릭 로그를 분석하고 시각화하기 위해 ES(엘라스틱서치)에 저장하기 위해 사용하고, 클릭로그를 백업하기 위해 하둡에 저장하기 위해 사용한다.*(카프카를 사용하는 중요한 이유). 그러면 파티션에서 데이터는 언제 빠지는가? 옵션을 정해줘 적절하게 데이터가 삭제하게 할 수 있다. opt 1. log.retention.ms : 최대 record 보존시간 설정 opt 2. log.retention.byte : 최대 record 보존크기 (byte) 파티션은 더 이상 데이터가 들어오지 않으면 데이터가 들어올 때 가지 대기한다.
Case 1 만약 새로운 컨슈머가 들어오면 그 데이터 그대로 가져간다. 이때 조건으로는 컨슈머 그룹이 달라야 하며, -auto.offset.reset = earlisest로 세팅되어야 한다.
Case 2 파티션이 여러 개라면 Kafka가 round-robbin 방식으로 분배해서 분산처리되기 때문에 순서 보장이 안된다. offset을 이용해 이전에 가져간 메시지의 위치 정보를 알 수 있고 동시에 들어오는 많은 데이터를 여러 개의 파티션에 나누어 저장하기 때문에 병렬로 빠르게 처리할 수 있다. 파티션은 많을수록 처리량은 올라가지만, 장애 복구 시간이 늘어난다.
Producer : 메시지를 생산하는 주체이며 소스 애플리케이션이 프로듀서라 볼 수 있다.
만든 메시지를 Kafka에 전송하고 전송 시 배치 처리가 가능하다.
프로듀서가 데이터를 보낼 때 키를 지정할 수가 있다. -키가 null이고 기본 파티셔너를 사용할 경우 -> 라운드 로빈으로 할당 -키가 있고, 기본 파티셔너를 사용할 경우 -> 키의 해시값을 구하고 , 특정 파티션에 할당
전송 acks값을 설정하여 효율성을 높일 수 있다. - ACKS=0 : 빠른 전송. 파티션 리더가 받았는지 확인 불가. - ACKS=1 : (Default) 파티션 리더가 받았는지 확인 가능. - ACKS=ALL : 파티션 리더, 팔로워가 메시지를 받았는지 확인가능