어떻게 실패 지점에 대해 개별적으로 생산자와 소비자 응용 프로그램 사이의 카프카 트랜잭션 동기화를 보장하기 위해?

R. 라자로 :

나는 일반적으로 봄 - 카프카 / 카프카 여전히 조금 새로운입니다. 내 질문은 오히려 간단한이다. 나는이 소비자 만 , 지속적으로 카프카에서 읽고 메시지를 처리하고, 긍정 응답 리스너를 사용하여 수동으로 인정 응용 프로그램을. 나는 상류 의존성이 생산 전용 그들이 나를 소비하기 위해서는 카프카 주제로 메시지를 보내는 담당하는 사람입니다있는 응용 프로그램을. 우리는 최근 생산자와 소비자를 통해 트랜잭션을 구현하지만 오류 지점에 대한 자세한 이해하고 싶었 방법이 손실되지 않도록 다시 압연하는 이러한 트랜잭션을 처리하기 위해? 나는 그것을 사용하는 것이 가장 좋습니다 읽었습니다 AfterRollbackProcessor대신 SeekToCurrentErrorHandler과 함께 카프카 컨테이너 공장에 대한 거래를위한 StatefulRetry설정되는 사실. 내가 트랜잭션을 사용하고있는 이유는 달성하는 것입니다 카프카 정확히 - 한 번 의미를 우리는 데이터베이스 지속성을 많이 다루는 인해 DB 제약 중복 거래를 감당할 수 없기 때문에 자신의 새로운 릴리스를. 내가 있는지 궁금 해서요 @KafkaListener주석이되어야했다 @TransactionalI는이 내가 확실하지 오전 이유 인 경우가 될 수있는 경우하지만, 다른 게시물을하지 않아야한다는 전에 게시물을 읽을했기 때문에. 나는 생산자 및 소비자 응용 프로그램에 대한 많은 질문을 보았다 그러나 나는 (그것이 하루의 끝에서 같은 일이 될 수있는 경우에도)는 각각 그 별도의 역할과 별도의 응용 프로그램에 대한 하나를 보지 못했다. 간단히 말해서, 나는 얼마나 그 경우에 장애를 처리하는 카프카와 트랜잭션을 통합 때 최상의 방법이 무엇인지 알고 싶었다.

게리 러셀 :

카프카 거래는 소비자 전용 응용 프로그램에 대한 불필요한 오버 헤드가 있습니다. 레코드를 생성 할 때 거래에만 유용합니다.

나는 달성하기 위해 거래를한다 사용하고 정확하게-한 번 우리가 데이터베이스 지속성을 많이 취급하기 때문에 자신의 새로운 릴리스의 카프카 의미를 인해 DB 제약 중복 거래를 감당할 수 없습니다.

없습니다 에는 "정확히 한 번"다른 기술이 포함 된 경우에 대한 보장. 정확히 한 번만 적용

read->process->write

읽기 및 쓰기 시나리오는 카프카 . 이것은 일반적인 오해입니다.

또한, 카프카 전용 / 프로세스 / 쓰기, 읽기, 심지어으로 의미가 적용 "정확히 한 번" 전체 말야 만. 즉는는 쓰기가 성공하는 경우에만 최선을 다하고 읽기의 오프셋 (offset)입니다.

process단계는 얻을 것이다 일단 적어도 당신이 상관없이 카프카 쓰기 단계가 있는지의 프로세스 단계에서 다른 곳에서 작성 될 때마다 로직 중복 해제 및 필요하므로 (A 카프카 쓰기가있는 경우) 정확히 한번 트랜잭션을 사용하는 의미 그곳에.

당신은 카프카없이 쓰기로, 카프카에서 읽기와 DB를 작성하는 경우에, @Transactional청취자에 (피하기 중복에 중복 제거 로직) 올바른 접근 방식이다.

정확히 카프카의 의미 (읽기 / 프로세스 / 쓰기) 일단 원하는뿐만 아니라 공정 단계에서 DB에 기록 할 경우에, 당신은을 사용할 수있는 ChainedKafkaTransactionManagerDB를 트랜잭션이 카프카 거래와 동기화 (그러나 아직도이되도록 리스너 컨테이너에 )를 DB 커밋 경우에 작은 창은 성공하지만, 카프카 트랜잭션이 실패합니다. 당신은 여전히 그렇다하더라도 중복 제거 로직을 필요 그래서. 이 경우, 당신은 하지 않습니다 원하는 @Transactional리스너에.

편집하다

생산자 만 다른 비트이고; 하자 당신이 (노력) 또는 출력 (압연 다시)에있을 그들 모두를 원하는, 당신은 트랜잭션에 10 개 개의 레코드를 게시하고 싶은 말은. 그런 다음 트랜잭션을 사용해야합니다.

거래에서 생산 된 기록의 소비자해야 isolation.level=read_committed그들이 커밋되지 않은 쓰기를 (기본값은 표시되지 않도록 read_uncommitted).

당신은 한 번에 하나의 기록을 게시하고, 관련된 다른 트랜잭션 자원이없는 경우에만 카프카가 참여하는 경우 트랜잭션을 사용하여 거의 포인트가있다.

하지만, 당신이 등등 DB, 또는 JMS에서 읽기, 카프카에 작성하는 경우, 당신은 아마 DB와 카프카 거래를 동기화 할 것이지만, 다시 중복의 가능성은 여전히 ​​제로가 아닌; 어떻게 그 처리하면 트랜잭션을 커밋 순서에 따라 달라집니다.

일반적으로, 중복 제거는 애플리케이션에 따라 달라집니다; 종종 응용 프로그램 데이터의 일부 키를 사용하므로, 예를 들어, SQL INSERT 문은 이미 DB에 존재하지 않는 그 키 조건으로한다.

카프카는 주제 / 파티션의 조합으로, 각 레코드에 대한 편리한 고유 키를 제공합니다 / 오프셋. 당신은 중복을 방지하기 위해 데이터와 함께 DB 사람들을 저장할 수 있습니다.

EDIT2

SeekToCurrentErrorHandler트랜잭션을 사용하지 않을 경우 (STCEH)이 일반적으로 사용된다 리스너가 예외를 throw 할 때 레코드가 다음 설문 조사에 다시 꺼되도록, 오류 핸들러는 오프셋을 재설정합니다. 시도 몇 개의 후, 우리는 포기하고이 같은은 "복원 기"를, 전화를 DeadLetterPublishingRecoverer다른 주제에 실패한 기록을 작성.

그것은 여전히 ​​있지만, 거래와 함께 사용할 수 있습니다.

오류 핸들러 (트랜잭션의 범위 내에서 호출 하기 전에 예외를 throw하는 경우, 그래서 롤백)을 (그것이 않는 않는 한 회수 장치 "소비하는"실패), 트랜잭션 여전히 롤 백업합니다. 복구에 성공하면 트랜잭션은 커밋됩니다.

AfterRollbackProcessor복구 기능이 STCEH에 추가되기 전에 (ARP)을 첨가 하였다. 그것은 본질적으로 정확히 STCEH 같은 않지만, 실행 외부 (트랜잭션의 범위를 롤백).

모두없는 상처 아무것도 할 구성하면 STCEH 이미이 추구 수행 한 경우 ARP 수행 할 아무 것도 없기 때문에.

단지 로그 메시지에 대한 적절한 로그 범주를 얻을 수 있다면 - 난 아직도하지 않고 거래와 ARP 및 STCEH를 사용하는 것을 선호합니다. 내가 지금 당장 생각할 수없는 다른 이유가있을 수 있습니다.

지금 재시도 및 백 오프가 STCEH 및 ARP 모두에서 지원되는지, 그 주, 전혀 구성 리스너 레벨 상태 재 시도 할 필요가 없습니다. 당신의 브로커에 왕복없이 메모리 시도를 사용하려면 비 저장 재시도 여전히 같은 레코드 (들)을 재 페치 유용 할 수 있습니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=363772&siteId=1