You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1 멱등적 프로듀서란?
동일한 작업을 여러번 실행해도 한 번 실행한 것과 같은 서비스를 멱등적이라고 한다.
// 멱등적 X
UPDATE t Set x=x+1 where y=5
// 멱등적 O
UPDATE t Set x=18 where y=5
1.1 카프카 프로듀서의 멱등적 작동 원리
멱등적 프로듀서 기능을 켜면 메시지는 고유한 프로듀서 ID와 시퀀스 ID를 가지게 된다.
따라서 메시지마다 고유한 식별자가 추가됨
각 브로커느 할당된 모든 파티션들에 쓰여진 마지막 5개 메시지를 이 고유 식별자로 추적한다. (max.in.flights.requests.per.connection : 추적 메시지 개수)
따라서 이런 고유 식별자를 가지고 중복처리를 수행한다.
+) 예상보다 높은 시퀀스 넘버의 메시지를 받게된다면 out of order sequence number에러를 발생시킨다. (2번 메시지가 와야하는데 23번 메시지가 온 상황)
작동이 실패했을 경우
프로듀서 재시작
프로듀서에 장애가 발생할 경우, 보통 새 프로듀서를 생성해서 장애가 난 프로듀서를 대체한다.(쿠버네티스와 같은 장애 복구 프레임워크 사용)
멱등적 프로듀서기능이 켜있을 경우 브로커로부터 프로듀서 ID를 생성받는다. (꺼져있을 경우 새로운 ID발급) 따라서 프로듀서ID와 시퀀스 넘버를 가지고 메시지 중복체크를 진행한다.
브로커 장애
브로커에 장애가 발생할 경우 파티션에 대해 새 리더를 선출하게 된다.
리더의 경우 새 메시지가 쓰여질 때 마다 인-메모리 프로듀서 상태에 최근 N개의 시퀀스 넘버를 가지고 있다.
트랜잭션은 어떻게 정확히 한 번을 보장하는가?
읽기, 처리, 쓰기 작업이 원자적으로 이루어져야 한다.
카프타 트랜잭션은 원자적 다수 파티션 쓰기기능을 도입했다.
이는 메시지 커밋을 다수 파티션에 원자적으로 쓰는 것을 의미한다. (커밋 메시지에 consumer-offsets를 같이 넣음)
예: 프로듀서가 3개의 파티션에 메시지를 동시에 쓰는 작업이 있을 때, Kafka는 모든 파티션에 대한 쓰기를 하나의 **단위 작업(Transaction)**으로 간주합니다.
성공: 모든 파티션에 데이터 커밋.
실패: 모든 파티션에서 작업이 취소(롤백).
이를 활용하기 위해서는 트랜잭션적 프로듀서를 활용해야 한다. 트랜잭션적 프로듀서와 보통 프로듀서의 차이점이란 transactional.id 설정이 잡혀있어 내부적으로 프로듀서의 아이디와 비교하여 메시지 처리를 진행하게 된다.
transactional.id 설정
트랜잭션적 프로듀서를 설정하려면 transactional.id를 명시해야 합니다.
Kafka는 이 ID를 통해 프로듀서를 인식하고 트랜잭션 상태를 관리합니다.
(예: 어떤 메시지가 커밋됐는지, 롤백됐는지 등)
같은 ID를 가진 다른 프로듀서가 연결을 시도하면 충돌을 방지하기 위해 작업을 차단하거나 실패시킵니다.
프로듀서 뿐만 아니라 컨슈머 격리 수준을 조절해야 한다.(isolation.level 설정 값)
read_committed
커밋된 트랜잭션에 속한 메시지나 처음부터 트랜잭션에 속하지 않은 메시지만 리턴(트랜잭션진행 중 메시지는 리턴 X)
read_uncommitted(default)
트랜잭션에 속하고 있는 메시지도 리턴
즉 read_comitted 모드로 작동중인 컨슈머는 read_uncommitted로 작동중인 컨슈머보다 더 뒤에 있는 메시지를 할당 받는다.
전체 데이터 흐름 예시
Kafka 트랜잭션을 활용하여 정확히 한 번을 보장하는 흐름은 다음과 같습니다:
클라이언트가 트랜잭션적 프로듀서를 설정:
transactional.id를 설정하여 트랜잭션 단위 작업을 시작.
프로듀서가 메시지를 쓰기 시작:
여러 파티션에 데이터를 보냄.
모든 데이터가 성공적으로 기록될 때까지 커밋하지 않음.
트랜잭션 커밋:
모든 데이터가 성공적으로 ISR에 쓰이면 트랜잭션을 커밋.
만약 중간에 실패가 발생하면 롤백(모든 데이터를 삭제) 처리.
컨슈머 읽기 모드에 따라 다르게 동작:
read_committed 컨슈머: 커밋된 데이터만 처리.
read_uncommitted 컨슈머: 롤백된 데이터를 포함하여 읽기 가능.
**카프카 트랜잭션 쉬운 예**
두 가지 작업을 한 트랜잭션으로 묶는 경우
상황
- 당신은 Kafka에서 2개의 파티션에 데이터를 쓰고, 컨슈머 오프셋도 업데이트해야 합니다.
트랜잭션 없이:
- 파티션 A는 성공했는데 파티션 B는 실패하면 데이터 불일치가 발생할 수 있음.
- 컨슈머 오프셋 업데이트는 실패하고, 같은 데이터를 두 번 처리할 수 있음.
트랜잭션과 함께:
1. 트랜잭션 시작:
- Kafka에게 "지금부터 한 묶음으로 작업할 것"이라고 알림.
2. 메시지 전송 및 오프셋 업데이트:
- 파티션 A, B에 데이터를 보냄.
- 모든 작업이 성공했는지 확인.
3. 커밋(또는 롤백):
- 모든 작업이 성공 → 커밋.
- 하나라도 실패 → 롤백.
컨슈머 격리 수준(isolation.level) 간단 요약
1. read_committed (권장):
- 컨슈머가 커밋된 메시지만 읽음.
- 트랜잭션 진행 중이거나 롤백된 메시지는 건너뜀.
- 정확히 한 번 처리가 필요한 경우 사용.
2. read_uncommitted (기본값):
- 트랜잭션 상태와 상관없이 모든 메시지를 읽음.
- 롤백된 메시지도 처리될 수 있어 중복/오류 가능.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
정확히 한 번 이란?
으로 이루어진다.
1 멱등적 프로듀서란?
동일한 작업을 여러번 실행해도 한 번 실행한 것과 같은 서비스를 멱등적이라고 한다.
// 멱등적 X
UPDATE t Set x=x+1 where y=5
// 멱등적 O
UPDATE t Set x=18 where y=5
1.1 카프카 프로듀서의 멱등적 작동 원리
멱등적 프로듀서 기능을 켜면 메시지는 고유한 프로듀서 ID와 시퀀스 ID를 가지게 된다.
따라서 메시지마다 고유한 식별자가 추가됨
각 브로커느 할당된 모든 파티션들에 쓰여진 마지막 5개 메시지를 이 고유 식별자로 추적한다. (max.in.flights.requests.per.connection : 추적 메시지 개수)
따라서 이런 고유 식별자를 가지고 중복처리를 수행한다.
+) 예상보다 높은 시퀀스 넘버의 메시지를 받게된다면 out of order sequence number에러를 발생시킨다. (2번 메시지가 와야하는데 23번 메시지가 온 상황)
작동이 실패했을 경우
프로듀서 재시작
프로듀서에 장애가 발생할 경우, 보통 새 프로듀서를 생성해서 장애가 난 프로듀서를 대체한다.(쿠버네티스와 같은 장애 복구 프레임워크 사용)
멱등적 프로듀서기능이 켜있을 경우 브로커로부터 프로듀서 ID를 생성받는다. (꺼져있을 경우 새로운 ID발급) 따라서 프로듀서ID와 시퀀스 넘버를 가지고 메시지 중복체크를 진행한다.
브로커 장애
브로커에 장애가 발생할 경우 파티션에 대해 새 리더를 선출하게 된다.
리더의 경우 새 메시지가 쓰여질 때 마다 인-메모리 프로듀서 상태에 최근 N개의 시퀀스 넘버를 가지고 있다.
읽기, 처리, 쓰기 작업이 원자적으로 이루어져야 한다.
카프타 트랜잭션은 원자적 다수 파티션 쓰기기능을 도입했다.
이는 메시지 커밋을 다수 파티션에 원자적으로 쓰는 것을 의미한다. (커밋 메시지에 consumer-offsets를 같이 넣음)
이를 활용하기 위해서는 트랜잭션적 프로듀서를 활용해야 한다. 트랜잭션적 프로듀서와 보통 프로듀서의 차이점이란 transactional.id 설정이 잡혀있어 내부적으로 프로듀서의 아이디와 비교하여 메시지 처리를 진행하게 된다.
프로듀서 뿐만 아니라 컨슈머 격리 수준을 조절해야 한다.(isolation.level 설정 값)
read_committed
커밋된 트랜잭션에 속한 메시지나 처음부터 트랜잭션에 속하지 않은 메시지만 리턴(트랜잭션진행 중 메시지는 리턴 X)
read_uncommitted(default)
트랜잭션에 속하고 있는 메시지도 리턴
즉 read_comitted 모드로 작동중인 컨슈머는 read_uncommitted로 작동중인 컨슈머보다 더 뒤에 있는 메시지를 할당 받는다.
Kafka 트랜잭션을 활용하여 정확히 한 번을 보장하는 흐름은 다음과 같습니다:
클라이언트가 트랜잭션적 프로듀서를 설정:
transactional.id를 설정하여 트랜잭션 단위 작업을 시작.
프로듀서가 메시지를 쓰기 시작:
여러 파티션에 데이터를 보냄.
모든 데이터가 성공적으로 기록될 때까지 커밋하지 않음.
트랜잭션 커밋:
모든 데이터가 성공적으로 ISR에 쓰이면 트랜잭션을 커밋.
만약 중간에 실패가 발생하면 롤백(모든 데이터를 삭제) 처리.
컨슈머 읽기 모드에 따라 다르게 동작:
read_committed 컨슈머: 커밋된 데이터만 처리.
read_uncommitted 컨슈머: 롤백된 데이터를 포함하여 읽기 가능.
Beta Was this translation helpful? Give feedback.
All reactions