1 ポイント 投稿者 GN⁺ 2024-11-14 | 1件のコメント | WhatsAppで共有

更新_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 で使用した。
  • 各論理プロセスはプロデューサー、コンシューマー、管理クライアントを実行し、さまざまなキーに対してレコードを送信する。

中断

  • 予想外の結果に基づき、トランザクションを中断しオフセットを追跡するワークロードを設計した。
  • 中断されたトランザクション後のオフセットを 4 つのカテゴリに分類した: 進行巻き戻しさらに巻き戻しその他

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)

  • トランザクション失敗時におけるコンシューマーオフセットの意図された動作について、文書が不足している。
  • コンシューマーは中断されたトランザクション後にオフセットを巻き戻すことも、そのまま進めることもある。

1件のコメント

 
GN⁺ 2024-11-14
Hacker News の意見
  • Kafkaで発生する問題を調査している中で、見えない書き込みが見つかった。これは、遅延した Produce メッセージが将来のトランザクションに含まれ、トランザクション保証に違反する可能性を示している。Kafka Java Client がリクエストのタイムアウト時にシーケンス番号を再利用できるのではないかという疑いもある。Kafka にはさらに多くのテストが必要だ

    • Jepsen は Kafka に対する詳細な調査を再び行うべきだと思う。前回の調査は2013年で、Kafka 自体に多くの問題が見つかる可能性がある。"書き込み確認後に静かに破棄"のような問題は非常に深刻に見える
  • Bufstream の製品ページを見て、次の2つの記述がどう両立するのか気になった

    • 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 は "exactly once delivery" を "read-process-write operation" の特性として定義している。これはトランザクションとして説明したほうがよさそうだ

  • "トランザクションは一部または全部を観測できる" という文言は、"コンシューマーは一部または全部を観測できる" と読むべきだと思う

  • このソフトウェアは何に使うものなのだろう。計測用? ブラックボックス?