2309 words
12 minutes
[kafka]10. Iempotency

개요#

카프카에서 신뢰성을 보장한다는 것은 크게 두 가지로 나뉜다

  • 최소 한번 전달하기 : 매개변수 구성과 시스템 설계의 Best Practices 활용
  • 정확히 한번 전달하기 : 멱등성 프로듀서와 트랜잭션의 조합

01. 멱등성 프로듀서#


Concept

  • idempotency : 멱등성. 멱등성 자체는 동일한 작업을 여러번 실행해도 한 번만 실행한 것과 결과가 같은 것을 의미한다.

멱등성 프로듀서 작동원리#

NOTE

모든 메시지가 고유한 PID와 sequence id를 가지고 있어야 한다

  1. 각 프로듀서가 고유한 PID를 할당받음(Producer가 초기화될 때 브로커로부터 발급됨)
  2. 프로듀서는 각 메시지에 순차적인 sequence Id를 할당함

중복 검사 과정

  • Producer가 메시지를 보낼 때 (Topic, Partition, PID, sequence id) 를 식별자로 사용
  • 브로커는 이 정보를 사용하여 중복 메시지를 감지
  • 동일한 식별자( Topic, Partition, PID, sequence id) 로 메시지를 받으면 브로커는 적절한 에러를 반환

브로커가 예상보다 높은 sequence id를 받으면 out-of-order sequence error를 반환


Concept

  • max.in.flights.requests.per.connection : 프로듀서가 브로커로 보낼 수 있는 최대 요청 수 . 브로커는 할당된 모든 파티션에 쓰여진 5개 메시지를 추적하기 위해 고유 식별자를 사용한다.

멱등성 프로듀서의 한계#

멱등성 프로듀서는 프로듀서의 내부 로직으로 인한 재시도를 통해 생기는 중복만 방지한다. 만약 동일한 메시지를 가지고 producer.send() 를 두 번 호출하면 멱등성 프로듀서가 개입하지 않는만금 중복된 메시지가 생길 수 있다. 즉 멱등성 프로듀서는 프로듀서 자체의 재시도 매커니즘으로 인한 중복만 방지한다.

02. 트랜잭션#

NOTE

트랜잭션이 정확히 한번 처리를 보장하는 방식

  1. Tranasactional Producer를 활용한 atomic multipartition write에 기반한다.
  2. 기본적인 아이디어는 오프셋을 커밋하는 것과 결과를 쓰는 것은 둘 다 메시지를 파티션에 쓰는 것을 수반한다 는 것에 기반.

Concept

  • atomic multipartition write : 여러 파티션에 거친 쓰기 작업을 원자적으로 수행하는 것
  • transactional producer : transactional.id 설정이 잡혀있고 ininitTransactions()
  • zombie fencing : 어플리케이션의 좀비 인스턴스가 중복 프로듀서를 생성하는 것을 방지하기 위한 메커니즘. epoch라는 개념을 사용하여 좀비 프로듀서를 식별한다. 같은 transactional.id를 가진 프로듀서가 새로운 epoch를 가지면 이전 epoch의 프로듀서는 좀비 프로듀서로 간주한다.
  • isolation.level : 트랜잭션이 진행 중일 때 다른 컨슈머가 해당 메시지를 읽을 수 있는 수준을 정의한다. read uncommitted, read committed 두 가지 격리 수준을 제공. read committed는 커밋된 트랜잭션의 메시지만 읽을 수 있다. read uncommitted는 트랜잭션의 상태와 관계없이 모든 메시지를 읽을 수 있다.

isolation.level#

트랜잭션이 진행 중일 때 다른 컨슈머가 해당 메시지를 읽을 수 있는 수준

read uncommitted : 트랜잭션의 상태와 관계없이 모든 메시지를 읽을 수 있다. read committed : 커밋된 트랜잭션의 메시지만 읽을 수 있다.

  • Read Committed를 사용할 때의 고려사항:

메시지 지연: 트랜잭션이 커밋될 때까지 대기 필요 추가적인 메모리 사용: 트랜잭션 상태 추적에 필요 처리량 감소: 트랜잭션 상태 확인에 따른 오버헤드

  • Read Uncommitted를 사용할 때의 고려사항:

빠른 처리: 즉시 메시지 처리 가능 낮은 오버헤드: 트랜잭션 상태 확인 불필요 데이터 일관성 위험: 롤백될 수 있는 데이터 처리 가능성

결국은 가용성과 일관성 사이의 trade-off

트랜잭션의 동작방식#

Chandy-Lamport 알고리즘#

기본적인 목적은 여러 노드가 독립적으로 동작하고 메시지를 주고받는 상황에서 **특정 시점의 전체 시스템 상태를 캡처(파악)**하는 것이다.

이는 분산 스냅샷 문제이며 카프카는 이를 위해 Tranaction Marker라는 특수한 메시지를 사용한다.

2PC(2 Phase Commit)#


Concept

  • 2PC : 2 Phase Commit. 분산시스템에서 모든 참여자의 트랜잭션의 원자성을 보장하기 위한 합의 프로토콜의 일종

준비단계

  • 모든 참여자들이 트랜잭션을 완료할 수 있는지 확인하는 단계
  • 참여자들은 이 단계에서 필요 리소스에 대한 락을 획득

커밋단계

  • 실제 트랜잭션 실행
  • 준비단계에서 하나라도 부정적인 응답이 오면 모든 참여자는 롤백

트랜잭션의 한계#

트랜잭션으로 해결할 수 없는 문제를 다룬다.

  1. 스트림 처리 어플리케이션에서 외부 효과를 발생시키는 작업

  2. 카프카 토픽에서 읽어서 DB에 쓰는 경우

  3. 데이터베이스에서 읽어서 카프카에 쓰고, 여기서 다시 다른 DB에 쓰는 경우

  4. 한 클러스터에서 다른 클러스터로 데이터를 복제하는 경우

  5. 발행 구독 패턴

  • 메시지를 쓰고 나서 커밋하기 전에 다른 어플리케이션이 응답하기를 기다리는 패턴은 반드시 피해야 한다. 다른 어플리케이션은 트랜잭션이 커밋될 때까지 메시지를 받지 못할 것이기 때문에 결과적으로 데드락이 발생할 수 있다.

03. 트랜잭션 성능#

  • 트랜잭션 초기화와 커밋 요청은 동기적으로 동작하기 때문에 성공적으로 완료하거나 실패하거난 타임아웋 하거나 할 때 까지 어떤 데이터도 전송되지 않는다. 따라서 오버헤드는 더 증가한다.

  • 프로듀서에 있어서 트랜잭션 오버헤드는 트랜잭션에 포함된 메시지의 수와는 무관하다. 따라서 트랜잭션마다 많은 수의 메시지를 넣는 것이 상대적으로 오버헤드가 적다.

  • 트랜잭션 기능이 컨슈머 성능에 미치는 핵심적인 영향은 read_commited consumer mode에서는 아직 완료되지 않는 트랜잭션의 레코드들이 리턴되지 않는다는 것이다. 트랜잭션 커밋 사이의 간격이 길어질 수록 컨슈머는 메시지가 반환될 때까지 더 오래 기다려야 한다.

Takeaway#


Key Takeaway

  • 리더 레플리카는 새 메시지가 쓰여질 때마다 인 메모리 프로듀서 상태에 저장된 최근 5개 sequence id를 업데이트한다. 팔로워 레플리카는 메시지를 복제할 때마다 자체적인 인메모리 버퍼를 업데이트한다.
  • 멱등성 프로듀서는 프로듀서의 내부 로직으로 인한 재시도를 통해 생기는 중복만 방지한다. 만약 동일한 메시지를 가지고 producer.send() 를 두 번 호출하면 멱등성 프로듀서가 개입하지 않는만금 중복된 메시지가 생길 수 있다. 즉 멱등성 프로듀서는 프로듀서 자체의 재시도 매커니즘으로 인한 중복만 방지한다.
  • 트랜잭션은 근본적인 매커니즘을 뜻한다. 카프카 스트림즈는 멱등성을 구현하기 위해 트랜잭션 기능을 사용한다. 스파크 스트리밍이나 플링크와 같은 다른 스트림 처리 프레임워크의 경우 사용자에게 멱등성을 제공하기 위해 다른 매커니즘을 사용한다
  • 트랜잭션은 대부분 프로듀서 쪽 기능이다. 컨슈머에 올바른 isolation level이 설정되지 않을 경우 멱등성을
  • 트랜잭션이 정확히 한번 처리된다는 것은 기본적으로 읽기, 처리, 쓰기 작업이 원자적으로 이루어진다는 것을 의미한다.
  • atomic 하다는 것은 기본적으로 모든 작업이 성공하거나 아니면 모든 작업이 실패한다는 것을 의미한다. 카프카에서는 트랜잭션을 사용하여 이러한 atomicity를 보장한다.
  • 메시지를 쓰고 나서 커밋하기 전에 다른 어플리케이션이 응답하기를 기다리는 패턴은 반드시 피해야 한다. 다른 어플리케이션은 트랜잭션이 커밋될 때까지 메시지를 받지 못할 것이기 때문에 결과적으로 데드락이 발생할 수 있다.

Reference#

  • 카프카 핵심 가이드
[kafka]10. Iempotency
https://yjinheon.netlify.app/posts/02de/kafka/de-kafka-10_idempotency/
Author
Datamind
Published at
2025-01-10
License
CC BY-NC-SA 4.0