카프카는 어떻게 신뢰성을 보장할까? 1️⃣ 카프카는 파티션 안의 메시지들 간에 순서를 보장한다.메시지 A 다음에 B가 쓰여졌다면 동일한 프로듀서가 동일한 파티션에 썻을 경우 B의 오프셋이 A보다 큰 것을 보장한다. 2️⃣ 클라이언트가 쓴 메시지는 모든 in-sync replica의 파티션에 쓰여진 뒤에야 commit된 것으로 간주한다.굳이 디스크에 flush될 필요까지는 없으며 프로듀서의 commit 정책을 지정할 수 있다. (acks)완전히 commit된 다음 응답리더에게 쓰여진 다음 응답네트워크로 전송된 다음 바로 응답 3️⃣ commit된 메시지들은 최소 1개의 작동 가능한 replica가 남아 있는 한 유실되지 않는다. 4️⃣ 컨슈머는 commit된 메시지만 읽을 수 있다.메시지를 저장하는 데 있..
전체 글
Reactor에서 Test하기reactor-test라는 테스트 전용 모듈을 통해 여러 가지 유형의 테스트를 지원한다.dependencies { testImplementation 'io.projectreactor:reactor-test'} StepVerifier를 사용한 테스팅Reactor에서 일반 적으로 Flux 또는 Mono를 Reactor Seqence로 정의한 후, 구독 시점에 해당 Operator 체인이 시나리오대로 동작하는지 테스트한다.Reactor Seqence에서 다음에 발생한 시그널, 기대하던 데이터들이 emit 되었는지, 특정 시간 동안 emit된 데이터가 있는지 등을 단계적으로 테스트 Signal 이벤트 테스트expectXXXX() 메서드메서드설명expectSubscription()구..
Reactor에서의 디버깅Reactor는 처리되는 작업들이 대부분 비동기적으로 실행되고, Reactor Sequence는 선언형 프로그래밍 방식으로 구성되므로 디버깅이 쉽지않다. Debug ModeHooks.onOperatorDebug()를 통해서 Debug Mode를 활성화하면 Reactor Sequence를 디버깅할 수 있다.@Slf4jclass DebugModeExam { public static Map fruits = new HashMap(); static { fruits.put("banana", "바나나"); fruits.put("apple", "사과"); fruits.put("pear", "배"); fruits.put("grape", "포도"); } public s..
Reactor에서의 Context는 Operator 같은 Reactor 구성요소 간에 전파되는 key/value 형태의 저장소라고 정의한다. 여기서의 전파란?Downstream에서 Upstream으로 Context가 전파되어 Operator 체인상의 각 Operator가 해당 Context의 정보를 동일하게 이용할 수 있음을 의미한다.Reactor의 Context는 ThreadLocal과 다소 유사하지만 각각의 실행 스레드와 매핑되는 ThreadLocal과 달리 실행 스레드와 매핑되는 것이 아니라 Subscriber와 매핑된다.구독이 발생할때마다 해당 구독과 연결된 하나의 Context가 생긴다. Context 기본 예제@Slf4jclass ContextBasicExam { public static v..
아파치 주키퍼를 사용하는 이유카프카는 현재 클러스터의 멤버인 브로커들의 목록을 유지하기 위해서다.각 브로커는 브로커 설정 파일에 정의되었거나 아니면 자동으로 생성된 고유한 식별자를 가진다.브로커 프로세스는 시작될 때마다 주키퍼 Ephemeral 노드의 형태로 ID를 등록한다.컨트롤러를 포함한 카프카 브로커들과 몇몇 생태계 툴들은 브로커가 등록되는 주키퍼의 /brokers/ids 경로를 구독함으로써 브로커가 추가/제거 될 때마다 알림을 받는다.ID는 중복되지 않으며, 중복된 값이 추가된다면 동일한 브로커 ID를 갖는 ZNode가 있기 때문에 실패하며 에러가 발생한다.더보기ZNode의 종류는 영속 종류에 따라 다음과 같이 구분된다. (참조)Persistent Nodes(영구 노드) : 명시적으로 삭제되기 전..