You will be fine

<Kafka> 6. 데이터 정합성 보장하기

by BFine
반응형

출처&참고 : https://product.kyobobook.co.kr/detail/S000201464167

 

카프카 핵심 가이드 | 그웬 샤피라 - 교보문고

카프카 핵심 가이드 | 카프카를 창시한 사람들이 쓰고, 카프카 개발에 참여한 한국인 개발자가 옮긴 핵심 실무서모든 엔터프라이즈 애플리케이션은 로그 메시지, 지표, 사용자 행동 혹은 외부로

product.kyobobook.co.kr

 

가. 멱등적 프로듀서 (Idempotence Producer) 

 a. Exactly Once

  -  어플리케이션이 복잡해지면서 이벤트 중복 처리로 인해 문제가 발생할 수 있는 시스템이 존재한다.

  -  이를 해결하기 위해서 카프카는 Exactly Once 기능을 제공하고 있다. 이 기능은 멱등적 프로듀서와 트랜잭션을 통해 구현된다.

      => Producer 설정은 단순 enable.idempotence = true 통해 할 수 있다.

 

 b. 작동원리

  -  멱등적 프로듀서 기능을 활성화하면 모든 메세지는 고유한 프로듀서 ID와 시퀀스 넘버가 부여된다. 

      => 시퀀스 넘버는 파티션들에 쓰여진 마지막 5개(기본값)의 메세지들을 추적하기위해 이 식별자를 사용한다.

  -  브로커가 중복된 시퀀스 넘버 메세지를 감지하면 에러를 발생시키고 메시지를 거부한다. (로깅 및 지표에는 반영)

      => 이전보다 높은 시퀀스 넘버를 받는 경우에도 동일하게 에러를 발생시킨다.

 

 c. 한계점

  -  이 기능은 프로듀서의 내부 로직이나 네트워크 에러로 인해 재시도가 발생할 경우 생기는 중복만을 방지한다.

  -  예를들어 producer.send()를 두번 호출하면 전송된 레코드가 실제로 동일한 레코드인지 확인할 방법이 없다.

      => 멱등적 프로듀서는 프로듀서 내부 또는 브로커와의 통신 오류에서 발생하는 중복만 방지한다

 

나. 트랜잭션

 a. 정확성 보장

  -  트랜잭션 기능은 카프카 스트림즈를 사용해서 개발된 어플리케이션에 정확성을 보장하기 위해 도입되었다. 

  -  예를들어 토픽에서 데이터를 읽고 처리하고 결과를 다른 토픽에 쓰는 어플리케이션이 있을때 각 단계에서 오류가 발생할 수 있다.

      => 원본 메시지의 오프셋은 커밋되었으나 결과는 쓰여지지 않거나 반대 상황인 경우

  -  이러한 문제를 해결하기 위해 카프카는 Atomic Multi-Partition Write 기능을 구현하여 읽기-처리-쓰기 작업의 원자성을 보장한다.

  -  RDBMS 처럼 카프카 트랜잭션도 isolation.level을 설정 할수가 있다. (read_committed, read_uncommitted) 

 

 b. Atomic mulipartition write

  -  이 기능을 사용하려면 트랜잭션 프로듀서를 사용해야한다. 일반 프로듀서와의 차이점은 transactional.id가 존재한다는 점이다.

  -  transactional.id는 프로듀서 설정의 일부로 프로듀서가 재시작되더라도 동일한 ID를 유지한다.

 

 c. 작동원리

  -  기본 알고리즘은 Chandy-Lamport snapshot 알고리즘을 영향을 받아서 구현되었다

      => 알고리즘은 통신 채널을 통해 마커(marker) 라는 제어 메세지를 보내고 이 마커 도착 기준으로 상태를 일관되게 기록한다.

  -  다수의 파티션에 대해 트랜잭션이 커밋되었거나 중단되었다는 것을 표시하기 위해 위의 마커 메세지를 사용한다.

      => 트랜잭션 코디네이터가 커밋 메세지를 받으면 트랜잭션과 관련된 모든 파티션에 커밋 마커를 쓴다.

  -  위에서 일부 파티션에만 커밋메세지가 쓰여진 상태를 처리하기 위해 2PC(Phase Commit)과 트랜잭션 로그를 사용한다.

      1.진행중인 트랜잭션이 존재를 연관된 파티션들과 함께 기록한다.

      2.트랜잭션 로그에 커밋 또는 중단 시도를 기록한다.

      3.모든 파티션에 트랜잭션 마커를 쓴다

      4.트랜잭션이 종료되었음을 로그에 쓴다. 

  -  이 모든 과정을 처리하기 위해 카프카는 트랜잭션 로그를 __transaction_state 라는 내부 토픽을 사용한다. 

 

 d. 트랜잭션으로 해결할 수 없는 문제

  -  하나의 트랜잭션에서 외부 DB에 결과를 쓰고 카프카에 오프셋을 커밋하는 매커니즘은 지원하지 않는다.

      => 이를 해결하는 일반적인 방법은 아웃박스 패턴을 사용하는 것이다.

      => DB 테이블을 아웃박스로 사용하고 릴레이 서비스가 테이블 업데이트 내역을 카프카에 메세지로 쓰는 방법이 있다.

  -  마찬가지로 더 복잡한 DB를 읽어서 카프카에 쓰고 다시 다른 DB에 쓰는 등 프로세스에 대한 end-to-end guarantee 에 대한 기능은 없다.

 

 e. 트랜잭션 ID와 펜싱 

  -  카프카 2.5 버전부터 트랜잭션 ID와 컨슈머 그룹 메타데이터를 함께 사용하는 펜싱이 도입되었다.

  -  예를들어 같은 그룹의 컨슈머 A,B가 있고 결과물을 프로듀서 A,B 를 통해 다른 토픽에 쓴다고 했을때 컨슈머 A가 장애가 발생해도 정상적으로 동작한다.

     => 트랜잭션 ID와 그룹 정보가 함께 사용되므로 트랜잭션의 연속성을 유지하며 트랜잭션을 관리할 수 있다. (컨슈머 A는 펜싱됨)

 

 f. 성능 

  -  트랜잭션 기능은 동기적으로 작동하므로, 트랜잭션 초기화와 커밋 요청에 약간의 성능 오버헤드가 발생할 수 있다.

     => 컨슈머는 커밋 마커를 읽어오는 작업이 추가되어 성능 저하를 유발할 수 있어서 성능 최적화 고려 대상이 될 수 있다.

  -  ack나 트랜잭션 로그 기록 역시 성능 저하가 있을수 있으며 멱등적 프로듀서는 메세지의 고유성을 추적해야하는 작업이 추가되어 체크가 필요하다.

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기