1P by neo 28일전 | favorite | 댓글 1개

업데이트_2024-11-13

  • 초기 보고서에서는 auto-commit이 활성화된 소비자가 최근 poll에서 반환된 오프셋을 자동으로 커밋하여 데이터 손실이 발생할 수 있다고 주장했음.
  • 그러나 여러 독자들은 auto-commit 소비자가 실제로는 최근 poll이 아닌 그 이전 poll의 오프셋을 커밋한다고 반박했음.
  • Java Kafka 클라이언트 실험 결과도 이를 뒷받침하며, 클라이언트마다 다르게 동작할 수 있음.
  • auto-commit에 대한 구체적인 주장을 보고서에서 제거했으며, 추가 연구가 필요함.

배경

  • Kafka는 복제, 샤딩, append-only 로그를 제공하는 인기 있는 스트리밍 시스템임.
  • Bufstream은 클라우드 환경에서 데이터 거버넌스와 비용 효율성을 우선시하는 Kafka의 대체 솔루션임.
  • Kafka와 유사하게 Bufstream은 _토픽_이라 불리는 부분적으로 정렬된 로그 모음을 제공하며, 각 토픽은 _파티션_으로 나뉨.
  • Bufstream은 표준 Kafka 클라이언트와 호환되며, Kafka API를 제공하는 무상태 서비스인 에이전트, 데이터를 저장하는 오브젝트 스토어, 그리고 _조정 서비스_로 구성됨.
  • Bufstream은 데이터 저장을 오브젝트 스토리지 서비스에 직접 기록하여 비용을 절감하고, 무상태, 자동 확장 가능한 VM으로 운영될 수 있음.

클라이언트 안전성

  • Bufstream은 다양한 스트리밍 애플리케이션을 위해 설계되었으며, 안전한 동작을 위해 다양한 클라이언트 구성 옵션을 설정함.
  • Kafka와 마찬가지로 acks = all을 기본으로 사용하며, enable.auto.commit = false로 설정하여 데이터 손실을 방지함.
  • auto.offset.reset = earliest를 사용하여 소비자가 전체 로그를 관찰할 수 있도록 함.

트랜잭션

  • Bufstream은 Kafka의 트랜잭션 시스템을 지원하며, 복잡한 구성을 통해 약한 형태의 원자성을 제공함.
  • 소비자는 read_uncommitted 또는 read_committed 격리 수준에서 실행될 수 있으며, read_committed는 일부 현상(G1a, G1c)을 방지함.
  • Kafka, Redpanda, Bufstream 모두에서 G0 현상이 발생하며, 이는 문서화된 격리 수준과 일치하지 않음.

테스트 설계

  • Bufstream 0.1.0부터 0.1.3까지 테스트했으며, Jepsen 테스트 라이브러리와 Java Kafka Client를 사용함.
  • 테스트는 다양한 결함을 주입하여 Bufstream의 안전성을 평가함.

  • Kafka의 데이터 모델에 맞춘 큐 작업 부하를 설계하여 Bufstream에서 사용함.
  • 각 논리적 프로세스는 프로듀서, 소비자, 관리자 클라이언트를 실행하며, 다양한 키에 대해 레코드를 전송함.

중단

  • 예상치 못한 결과를 바탕으로 트랜잭션을 중단하고 오프셋을 추적하는 작업 부하를 설계함.
  • 중단된 트랜잭션 후의 오프셋을 네 가지 범주로 분류함: 진행, 되감기, 더 되감기, 기타.

Bufstream 결과

멈춘 소비자 (#1)

  • 0.1.0부터 0.1.3-rc.8까지 consumer.poll() 호출이 즉시 반환되며 레코드를 반환하지 않는 문제가 발생함.
  • Bufstream은 0.1.3-rc.6에서 캐시를 새로 고침하여 문제를 해결함.

멈춘 프로듀서 및 소비자 (#2)

  • 0.1.3-rc.6에서도 InitProducerId 호출이 실패하거나 listOffsets 호출이 실패하는 문제가 발생함.
  • Bufstream은 추가 폴링 로직을 추가하여 문제를 해결함.

잘못된 0 오프셋 (#3)

  • 0.1.0부터 0.1.3-rc.2까지 잘못된 0 오프셋이 할당되는 문제가 발생함.
  • Bufstream은 0.1.3-rc.6에서 이 문제를 해결함.

트랜잭션 쓰기 손실 (#4)

  • 0.1.2에서 커밋된 트랜잭션의 레코드가 사라지는 문제가 발생함.
  • Bufstream은 0.1.3-rc2에서 문제를 해결함.

서버 측 필터링으로 인한 쓰기 손실 (#5)

  • 0.1.3-rc.8에서 경미한 결함에 반응하여 쓰기 손실이 발생함.
  • Bufstream은 0.1.3-rc.12에서 문제를 해결함.

Kafka 결과

오해의 소지가 있는 오류 메시지 (KIP-588)

  • ProducerFencedException이 트랜잭션 타임아웃에도 발생하는 문제가 있음.
  • Kafka 팀에 오류 메시지 변경을 권장함.

소비자 종료 시 무한 대기 가능성 (KAFKA-17734)

  • Consumer.close() 호출이 네트워크 IO에서 무한 대기하는 문제가 있음.
  • KAFKA-17734를 통해 문제를 추적함.

트랜잭션 실패 후 예측 불가능한 소비자 오프셋 (KAFKA-17582)

  • 트랜잭션 실패 시 소비자 오프셋의 의도된 동작에 대한 문서가 부족함.
  • 소비자가 중단된 트랜잭션 후 오프셋을 되감거나 계속 진행할 수 있음.
Hacker News 의견
  • Kafka에서 발생하는 문제를 조사하던 중, 보이지 않는 쓰기가 발견됨. 이는 지연된 Produce 메시지가 미래의 트랜잭션에 포함되어 트랜잭션 보장을 위반할 가능성을 제기함. Kafka Java Client가 요청 시간 초과 시 시퀀스 번호를 재사용할 수 있다는 의심도 있음. 더 많은 Kafka 테스트가 필요함

    • Jepsen이 Kafka에 대한 심층 조사를 다시 해야 할 것 같음. 마지막 조사는 2013년에 있었고, Kafka 자체에서 많은 문제를 발견할 가능성이 있음. "쓰기 확인 후 조용히 폐기" 같은 문제는 매우 심각해 보임
  • Bufstream의 제품 페이지를 보고 두 가지 진술이 어떻게 호환되는지 궁금함

    • Bufstream은 AWS 또는 GCP VPC 내에서 완전히 실행되어 데이터, 메타데이터 및 가동 시간을 완전히 제어할 수 있음. Bufstream은 절대 외부와 통신하지 않음
    • Bufstream의 가격은 단순함: 압축되지 않은 GiB당 $0.002 (약 $2 per TiB). 코어, 에이전트, 호출당 요금은 없음
    • 전체 사업을 신뢰 시스템에 기반하여 운영할 것 같지는 않음
  • Kafka의 auto-commit 기능에 대해 놀라움을 느낌

    • Kafka 소비자는 실제로 처리되었는지 여부와 관계없이 오프셋을 자동으로 커밋할 수 있음. 이는 소비자가 레코드를 폴링하고 커밋한 후 충돌하면 레코드가 손실될 수 있음을 의미함
    • 문서에 따르면, auto-commit이 활성화되면 poll 메서드가 호출될 때마다 반환된 메시지의 오프셋을 자동으로 커밋할 준비가 됨. 메시지 처리가 완료되지 않으면 충돌 시 메시지 진행이 손실될 위험이 있음
    • auto-commit 간격을 조정하면 중복 처리에 도움이 되지만 메시지 손실에는 도움이 되지 않음
  • Kafka 트랜잭션 프로토콜이 근본적으로 문제가 있으며 수정이 필요함

    • 훌륭한 조사 작업과 작성임
  • Kyle이 NATS Jetstream을 검토했는지 궁금함

  • bufstream의 GitHub 프로젝트를 찾지 못했음. 단서가 있는지 궁금함

  • 관련 블로그 게시물과 문서를 읽은 후, Kafka는 "정확히 한 번 전달"을 "읽기-처리-쓰기 작업"의 속성으로 정의함. 이는 트랜잭션으로 설명하는 것이 더 나을 것 같음

  • "트랜잭션은 일부 또는 전체를 관찰할 수 있음"이라는 문구는 "소비자는 일부 또는 전체를 관찰할 수 있음"으로 읽어야 할 것 같음

  • 이 소프트웨어는 무엇에 사용되는지 궁금함. 계측? 블랙박스?