Kafkaの古いバージョンのドキュメントを見ています - ここから現在のドキュメントを見てください。

ドキュメント

Kafka 2.0 ドキュメント

以前のリリース: 0.7.x, 0.8.0, 0.8.1.X, 0.8.2.X, 0.9.0.X, 0.10.0.X, 0.10.1.X, 0.10.2.X, 0.11.0.X, 1.0.X, 1.1.X
  • 2. APIs
  • 3. 設定
  • 4. 設計
  • 5. 実装
  • 6. 操作
  • 7. セキュリティ
  • 8. Kafka接続
  • 9. Kafka ストリーム
  • 1. 開始

    1.1はじめに

    . それは正確に何を意味するのか?

    ストリーミングプラットフォームは3つの主要な機能があります:

    • メッセージキューあるいはエンタープライズのメッセージングシステムに似て、レコードのストリームへ発行および購読します。
    • レコードのストリームを耐障害性のある方法で格納します。
    • 発生した順にレコードのストリームを処理します。

    Kafkaは一般的に2つのアプリケーションの大きなクラスのために使われます:

    • システムあるいはアプリケーション間でデータを信頼して取得できるリアルタイム ストリーミング データ パイプラインの構築
    • データのストリームの変換あるいは反応をするリアルタイム ストリーミング アプリケーションの構築

    Kafkaがどのようにこれらのことを行うのかを理解するために、試してみてKafkaの能力を上から下まで調査してみましょう。

    最初に2,3の概念:

    • Kafkaは複数のデータセンタに跨るかもしれない1つ以上のサーバ上でクラスタとして実行されます。
    • Kafkaのクラスタはトピックと呼ばれるカテゴリ内にレコードのストリームを格納します。
    • 各レコードはキー、値とタイムスタンプから成ります。

    Kafka には4つの主要なAPIがあります:

    • プロデューサ API によってアプリケーションはレコードのストリームを1つ以上のKafkaトピックに発行することができます。
    • コンシューマ API によってアプリケーションは1つ以上のトピックを購読し、生成されたレコードのストリームを処理することができます。
    • ストリーム API によってアプリケーションは ストリーム プロセッサとして振舞うことができます。1つ以上のトピックから入力ストリームを処理し、1つ以上の出力トピックにストリームへの出力ストリームを生成し、効果的に入力ストリームを出力ストリームに変換します。
    • コネクタ API によって既存のアプリケーションのデータストリームへKafkaトピックを接続する再利用可能なプロデューサとコンシューマを構築および実行することができます。例えば、リレーショナルデータベースへのコネクタはテーブルへの各変更を捕捉するかもしれません。

    Kafkaでは、クライアントとサーバ間の通信は、単純、高パフォーマンス、言語にとらわれないTCP プロトコル.によって行われます。このプロトコルはバージョン付けされ、古いバージョンとの後方互換性を維持します。KafkaについてはJavaクライアントを提供しますが、クライアントは多くの言語で利用可能です。

    トピックスとログ

    Kafkaがレコードのストリームのために提供する中核的な抽象に飛び込んでみましょう—the topic。

    トピックはレコードが発行される先のカテゴリあるいはフィード名です。Kafkaでのトピックは常に多数のサブスクライバです; つまり、トピックは書き込まれるデータを購読する0, 1 あるいは多くのコンシューマを持つことができます。

    各トピックについては、Kafkaクラスタが以下のように見えるパーティション化されたログを維持します:

    各パーティションは、構造化されたコミットログに絶え間なく追加される順番のある、不変のレコードの順列です。パーティション内のレコードはオフセット と呼ばれるパーティション内で各レコードを一意に識別する連続するid番号が割り当てられます。

    Kafka クラスタは設定可能な保有期間の間、それらが消費されたかどうかに関係なく、全ての発行されたレコードを永続的に持続します。例えば保持のポリシーが2日に設定された場合、レコードが発行されてから2日間は消費可能です。その後、スペースを解放するために削除されるでしょう。Kafkaのパフォーマンスはデータのサイズに対して事実上一定です。つまり多くのデータを保持する事は問題になりません。

    実際、ログにはコンシューマごとに保持されるメタデータはオフセットあるいはそのコンシューマの位置のみです。このオフセットはコンシューマによって制御されます: 通常コンシューマはレコードを読むに従って線形的にオフセットを進めるでしょうが、実際には、ポジションはコンシューマによって制御されるため、好きな順番でレコードを消費することができます。例えば、コンシューマは過去からのデータを再処理するために古いオフセットに再設定するか、最新のレコードへスキップして進めて"now"から消費を開始することができます。

    この機能の組み合わせは、Kafkaのコンシューマがとても手軽であることを意味します。それらはクラスタあるいは他のコンシューマに大きな影響無しに行き来することができます。例えば、既存のコンシューマによって消費されるものを変更せずに、任意のトピックの内容を"tail"するためにコマンドラインツールを使うことができます。

    ログ内のパーティションはいくつかの目的のために提供されます。まず、それらは一つのサーバに収まるサイズを超えてログをスケールすることができます。個々のパーティションはそれをホストするサーバに収まらなければなりませんが、トピックは多くのパーティションを持つことができるので、任意の量のデータを処理することができます。次に、それらは並行度の単位として振舞います - それよりは少し多くのことをします。

    分散

    ログのパーティションはKafkaクラスタのサーバ上で各サーバのデータ処理とパーティションの共有のリクエストを使って分散されます。各パーティションは耐障害性のための設定可能なサーバ数までリプリケートされます。

    各パーティションは"leader"として振る舞う1つのサーバと"followers"と振る舞う0個以上のサーバを持ちます。leaderはパーティションの全てのreadとwriteを処理し、followerは受動的にleaderをリプリケートします。leaderが故障すると、followerの一つが自動的に新しいleaderになるでしょう。各サーバは幾つかのパーティションに対してleaderとして振る舞い、followerは他のパーティションに対してそう振る舞います。つまり負荷はクラスタ内でよくバランスされています。

    Geoリプリケーション

    Kafka MirrorMaker はクラスタのためのgeoリプリケーションのサポートを提供します。MirrorMakerを使ってメッセージは複数のデータセンタあるいはクラウドリージョンを横断してリプリケートされます。これを、バックアップあるいは復元のために能動的/受動的に、あるいはデータをユーザの近くに配置するために能動的/受動的に、あるいはデータのローカル性の必要のサポートのために使うことができます。

    プロデューサ

    プロデューサはそれらが選択したトピックへデータを発行します。プロデューサはトピック内でどのレコードがどのパーティションへ割り当てられるかに責任があります。これは負荷をバランスするために単純にラウンドロビン形式で行うか、なんらかのセマンティックなパーティション形式(つまり、レコード内のなんらかのキーに基づいて)に従ってすることができます。パーティショニングの使い方についての詳細をすぐに!

    コンシューマ

    コンシューマは自身にコンシューマ グループ名のラベルを付け、トピックに発行された各レコードはそれぞれ購読しているコンシューマグループ内の1つのコンシューマインスタンスに配送されます。コンシューマーインスタンスは別個のプロセスの中あるいは別個のマシーン上にあるかも知れません。

    もし全てのコンシューマのインスタンスが同じコンシューマグループを持つ場合、レコードはコンシューマのインスタンス上に効率的にロードバランスされるでしょう。

    もし全てのコンシューマのインスタンスが異なるコンシューマグループを持つ場合、それぞれのレコードは全てのコンシューマのプロセスにブロードキャストされるでしょう。

    二つのコンシューマグループを持つ4つのパーティション (P0-P3) をホストしている2つのサーバのKafkaクラスタ。コンシューマグループ A は二つのコンシューマインスタンスを持ち、グループBは4つを持ちます。

    しかし、もっと一般的に、トピックはコンシューマグループより少ない数のトピックを持つことを知りました。各 "論理サブスクライバ"ごとに1つです。各グループはスケーラビリティと耐障害性のために多くのコンシューマインスタンスから成ります。これは、サブスクライバーが1つのプロセスの代わりにコンシューマのクラスタである、発行-購読セマンティクスに他なりません。

    Kafkaで実装されている消費の仕方は、各コンシューマのインスタンスが時間内のどの点においてもパーティションの "fair share" の排他的なコンシューマになるように、コンシューマのインスタンス上でログ内のパーティションが分割されるようにすることです。グループ内の会員数を維持するこのプロセスはKafkaプロトコルによって動的に処理されます。もし新しいインスタンスがグループに入ると、グループ内の他のメンバーからいくらかのパーティションを引き継ぎます; もしインスタンスが死ぬと、そのパーティションは他のインスタンスに分散されるでしょう。

    Kafkaはパーティションのレコード上の全体の順番のみを提供し、トピック内の異なるパーティション間では提供しません。キーによってデータを分割する機能との結合によるパーティションごとの順番付けは、ほとんどのアプリケーションで差し支えありません。しかし、もしレコード上の総順番が必要であれば、1つのパーティションだけをもつトピックを使って行うことができます。しかしこれはコンシューマグループごとに1つのコンシューマプロセスだけがあることを意味するでしょう。

    マルチ テナント

    Kafkaをマルチ テナントの解決法として配備することができます。マルチテナントはどのトピックがデータを生成あるいは消費できるかを設定することで有効にできます。定員のための操作のサポートもあります。管理者はクライアントによって使われるブローカーリソースを制御するためにリクエストに定員を定義および強制することができます。詳細な情報は、セキュリティのドキュメントを見てください。

    保証

    高レベルにおいて、Kafkaは以下の保証を与えます:

    • プロデューサによって特定のトピックに送信されたメッセージは送信された順に追加されるでしょう。つまり、もしレコード M1がレコード M2と同じ手順で送信された場合、M1がまず送信され、そしてM1はM2よりも低いオフセットを持ちログ内に早く現われるでしょう。
    • コンシューマインスタンスはログ内に格納された順番でレコードを見ます。
    • リプリケーション ファクターNを持つトピックについては、ログにコミットされた全てのレコードの損失無しに N-1のサーバ障害まで耐えることができるでしょう。

    これらの保証についての詳細はドキュメントの設計の章で見つけることができます。

    メッセージング システムとしてのKafka

    伝統的なエンタープライズ メッセージング システムに対してKafkaのストリームの概念はどのようなものか?

    メッセージングは伝統的に二つのモデルを持ちます: キューイング発行-購読。キュー内では、コンシュマーのプールはサーバから読み込むかもしれません。各レコードはそれらのうちの一つに行きます; 発行-購読の中で、レコードは全てのコンシューマにブロードキャストされます。これら2つのモデルのそれぞれは長所と短所を持ちます。キューイングの長所は複数のコンシューマのインスタンスにデータの処理を分割できることです。これにより、処理をスケールすることができます。残念ながら、キューは複数のサブスクライバではありません — 一度1つのプロセスがデータを読み込むと、それは消えます。発行-購読 により、複数のプロセスにデータをマルチキャストすることができますが、各メッセージが各サブスクライバに行くため処理のスケーリングをする方法はありません。

    Kafkaでのコンシューマグループの概念はこれらの2つの概念を一般化します。キューと同様にコンシューマグループは処理のコレクションに処理を分割することができます (コンシューマグループのメンバー)。発行-購読と同様に、Kafkaによってメッセージを複数のコンシューマグループにブロードキャストすることができます。

    Kafkaのモデルの長所は各トピックがこれらの両方のプロパティを持つことです — 処理をスケールし複数のサブスクライバーも — 1つあるいは他方を選択する必要はありません。

    Kafka は伝統的なメッセージングシステムよりも強力な順番の保証も持ちます。

    伝統的なキューはサーバ上で順番でレコードを保持し、もし複数のコンシューマがキューから消費すると、サーバは格納しているレコードを順番に分配します。しかし、サーバはレコードを順番に分配しますが、レコードは非同期でコンシューマに配送されます。そのためそれらは異なるコンシューマ上で順番がばらばらで到着するかも知れません。これは並行消費の前ではレコードの順番は事実上失われることを意味します。メッセージングシステムはしばしば1つのプロセスのみがキューから消費することができる"排他コンシューマー"という概念を持つことでこれに対処しますが、もちろんこれは処理中に並行度が無いことを意味します。

    Kafkaはそれをもうちょっとうまくやります。トピック内の並行度の概念 - パーティション - を持つことで、Kafkaは順番の保証とコンシューマのプロセスのプール上のロードバランシングの両方を提供することができます。これはトピック内のパーティションを、各パーティションがグループ内の確実に1つのコンシューマによって消費されるように、コンシューマグループ内のコンシューマに割り当てることで達成されます。こうすることで、コンシューマがパーティション内の唯一のreaderであることを確実にし、順番にデータを消費することを確実にします。多くのパーティションがあるので、これは多くのコンシューマのインスタンス上で負荷のバランスを取ります。しかし、コンシューマグループ内のコンシューマインスタンスはパーティションの数よりも大きくできないことに注意してください。

    ストレージ システムとしてのKafka

    発行されたメッセージを消費から分割することができるメッセージキューは効率的に実行中のメッセージのためのストレージシステムとして効率的に振る舞います。Kafkaの違いはとても良いストレージシステムだということです。

    Kafkaに書き込まれたデータはディスクに書き込まれ、耐障害性のためにリプリケートされます。書き込みが完全にリプリケートされ、失敗したと書き込まれたサーバでさえ一貫性を保証されるまで、書き込みが完了したと見なされないように、Kafkaを使ってプロデューサは通知を待つことができます。

    Kafkaが利用するディスクの構造は良くスケールします — Kafkaはサーバ上に50 KB あるいは 50 TB の永続データを持っていても同じ機能を果たすでしょう。

    ストレージを真面目に扱い、クライアントがそれらの読み込み位置を制御できるようにすることで、Kafkaを高パフォーマンス、低レンテンシのコミットログストレージ、レプリケーション、および伝搬専用の特別な目的の分散ファイルシステムのようなものと考えることができます。

    Kafkaのコミットログ ストレージおよびリプリケーション設計についての詳細は、この ページを読んでください。

    ストリーム処理のためのKafka

    単なる読み込み、書き込みおよびデータのストレージストリームでは十分では無く、目的はストリームのリアルタイム処理を可能にすることです。

    Kafkaではストリーム プロセッサーは入力トピックからデータの連続するストリームを受け取り、この入力上で何らかの処理を行い、出力トピックへのデータの連続するストリームを生成します。

    例えば、小売店のアプリケーションは売上と発送の入力ストリームを取り入れ、追加注文のストリームとこのデータから計算された価格の修正を出力するかもしれません。

    プロデューサおよびコンシューマAPIを使って直接簡単な処理を行うことができます。しかしもっと複雑な変換について、Kafkaは完全に統合されたストリーム APIを提供します。これによりストリームの集約を計算、あるいはストリームを統合する些細ではない処理をするようなアプリケーションをビルドすることができます。

    この機能はこの種類のアプリケーションが直面する難しい問題を解決するのに役立ちます: 乱雑なデータの処理、コードが変更されるに従って入力の再処理、ステートフルな計算の実施など。

    stream APIはKafkaが提供する主要なプリミティブを構築します: 入力のためにプロデューサとコンシューマを使い、ステートフルなストレージとしてKafkaを使い、ストリーム プロセッサのインスタンス間での耐障害性のために同じグループ機構を使います。

    要素を1つにする

    メッセージ、ストレージおよびストリーム処理のこの組み合わせは普通では無いように思えるかもしれませんが、それはストリーミング プラットフォームとしてKafkaの役割に重要です。

    HDFSのような分散ファイルシステムにより、バッチ処理のための静的なファイルを格納することができます。このようなシステムは効果的に過去からのhistoricalデータを格納および処理することができます。

    伝統的なエンタープライズ メッセージング システムは購読した後でやってくるだろう将来のメッセージを処理することができます。このやり方でビルドされたアプリケーションは将来のデータを到着したかのように処理します。

    Kafkaはこれらの能力を組み合わせます。組み合わせはストリーミングアプリケーションのためのプラットフォームとしてのKafkaの使い方とストリーミングデータパイプラインのための両方に重要です。

    ストレージと低レンテンシの購読の組み合わせにより、ストリーミングアプリケーションは過去と未来のデータを同じ方法で扱うことができます。つまり1つのアプリケーションは履歴データ、格納されたデータを処理できるが、最後のレコードに達した時に終了せずに将来のデータが到着しても処理を続けることができます。これはバッチ処理とメッセージ駆動のアプリケーションを含むストリーム処理の一般化された表記です。

    ストリーミング データのパイプラインと異なり、リアルタイムイベントへの購読の組み合わせはとてもレイテンシが低いパイプラインがKafkaを使うことを可能にします;しかしデータを信頼して格納できる機能により、データの配送が保証されなければならない重要なデータ、あるいは定期的にのみデータをロード、あるいはメンテナンスのために延長された時間の間ダウンするかもしれないオフラインシステムとの統合に使うことができます。ストリーミング処理の機能によりデータが到着した時に変換することができます。

    Kafkaが提供する保証、API および能力についての詳しい情報はドキュメントの残りを見てください。

    1.2ユースケース

    以下はApache Kafka®の人気のある使い方の2,3の説明です。これらの領域で活動中の多くの概要については、このブログの投稿を見てください。

    メッセージング

    Kafka は伝統的なメッセージブローカーの代替として良く動作します。メッセージブローカーは様々な理由で使われます (データプロデューサからの処理の切り離し、未処理メッセージのバッファ、など)。ほとんどのメッセージングシステムと比較してKafkaはより良いスループット、組み込みのパーティショニング、リプリケーション、および大規模メッセージ処理アプリケーションのための良い解決法となる耐障害性を持ちます。

    私たちの経験では、メッセージの使い方はしばしば比較的低スループットですが、低end-to-endレンテンシを必要とし、しばしばKafkaが提供する強い耐久性の保証に依存するかもしれません。

    この領域において、KafkaはActiveMQ あるいは RabbitMQのような伝統的なメッセージングシステムと互換性があります。

    Webサイト アクティビティ追跡

    Kafkaの元のユースケースはリアルタイム発行-購読フィードのセットとしてユーザのアクティビティトラッキング パイプラインを再構築できるようにすることです。これは、サイトアクティビティ(ページビュー、検索、あるいはユーザが取るかも知れない他のアクション)がアクティビティタイプごとに1つのトピックを持つ中核トピックへ発行されることを意味します。これらのフィードは、リアルタイム処理、リアルタイム監視、および オフライン処理やレポートのためにHadoopあるいはウェアハウス システムへのロードを含む様々な領域の使い方のために購読することができます。

    多くのアクティビティメッセージが各ユーザページビューに対して保証されるので、アクティビティトラッキングはしばしば大きなものになります。

    マトリックス

    Kafka はしばしば操作の監視データのために使われます。これはオペレーションデータの中央集権フィードを生成するために、分散型アプリケーションからの統計の集約を必要とします。

    ログの集約

    多くの人がKafkaをログ集約の解決法として使います。ログ集約は一般的に物理的なログファイルをサーバから離れて集め、それらを中核の場所(ファイルサーバあるいはHDFSおそらく)に処理のために配置します。Kafka はファイルの詳細を抽象化し、メッセージのストリームとしてログあるいはイベントデータのよりきれいな抽象を行います。これは低レンテンシの処理と、複数のデータソースと分散データの消費のより簡単なサポートを許容します。ScribeあるいはFlumeのようなログ中心のシステムに比べて、Kafkaは同等の良いパフォーマンス、リプリケーションによる強力な耐久性の保証、およびend-to-endのより低いレイテンシを提供します。

    ストリーム処理

    Kafkaの多くのユーザは多数のステージから成る処理パイプライン内のデータを処理します。生の入力データはKafkaのトピックから消費され、集約され、質を高められ、あるいは更なる消費または処理のフォローアップのために新しいトピックに変換されます。例えば、ニュースの文章のお勧めのためのパイプラインの処理は、RSSフィードから文章の内容をクロールし、それを "articles" トピックに発行するかもしれません; その先の処理はこの内容を正規化あるいは重複を取り除ききれいになった文章の内容を新しいトピックに発行するかもしれません; 最終的な処理のステージはこの内容をユーザにお勧めするかもしれません。そのような処理パイプラインは各トピックに基づいたリアルタイムデータフローのグラフを生成します。上で述べたようなデータ処理を行うためにApache Kafkaでは0.10.0.0からKafka Streamsと呼ばれる軽量だが強力なストリーム処理ライブラリが利用可能です。Kafkaストリームは別として、代替となるオープンソースストリーム処理ツールは Apache StormApache Samzaを含みます。

    イベント ソーシング

    イベント ソーシング は状態の変化がレコードの時間順のシーケンスとして記録されるアプリケーション設計の形式です。とても大きな格納ログデータのためのKafkaのサポートは、この形式で構築されたアプリケーションのための洗練されたバックエンドになります。

    コミットログ

    Kafkaは分散型システムのための外部コミットログの一種として提供することができます。ログはノード間のデータのリプリケートを助け、障害ノードがデータを復旧するための再同期の仕組みとして振る舞います。Kafkaのログ コンパクション 機能はこの使い方をサポートします。この使い方において、KafkaはApache BookKeeper プロジェクトに似ています。

    1.3クイックスタート

    bin/の代わりに、スクリプトの拡張子を.batに変更します。

    ステップ 1: コードのダウンロード

    {{fullDotVersion}} リリースをダウンロードし、それをun-tarします。
    > tar -xzf kafka_2.11-{{fullDotVersion}}.tgz
    > cd kafka_2.11-{{fullDotVersion}}
    

    ステップ 2: サーバの開始

    Kafka は ZooKeeperを使います。そのためまだZooKeeperが無い場合はそれを最初に開始する必要があります。quick-and-dirty single-node ZooKeeper インスタンスを取得するためにKafkaにパッケージ化されている便利なスクリプトを使うことができます。

    > bin/zookeeper-server-start.sh config/zookeeper.properties
    [2013-04-22 15:01:37,495] INFO Reading configuration from: config/zookeeper.properties (org.apache.zookeeper.server.quorum.QuorumPeerConfig)
    ...
    

    これでKafkaサーバを開始します:

    > bin/kafka-server-start.sh config/server.properties
    [2013-04-22 15:01:47,028] INFO Verifying properties (kafka.utils.VerifiableProperties)
    [2013-04-22 15:01:47,051] INFO Property socket.send.buffer.bytes is overridden to 1048576 (kafka.utils.VerifiableProperties)
    ...
    

    ステップ 3: トピックの作成

    1つのパーティションと1つのレプリカだけを持つ"test"という名前のトピックを作成しましょう:

    > bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
    

    これで list トピックコマンドを実行するとトピックを見ることができます:

    > bin/kafka-topics.sh --list --zookeeper localhost:2181
    test
    

    別のやり方として、手動でトピックを作成する代わりに、既存に無いトピックが発行された場合にブローカーがトピックを自動生成するように設定することもできます。

    ステップ 4: メッセージを送信

    Kafka はファイルあるいは標準入力から入力を受け取りそれをメッセージとしてKafkaクラスタに送信するコマンドライン クライアントが付属しています。デフォルトで各行は別個のメッセージとして送信されるでしょう。

    プロデューサを実行し、その後サーバに送信するために2,3のメッセージをコンソールに入力します。

    > bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
    This is a message
    This is another message
    

    ステップ 5: コンシューマの開始

    Kafka はメッセージを標準出力に出力するコマンドラインコンシューマも持ちます。

    > bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
    This is a message
    This is another message
    

    上のコマンドのそれぞれを異なるターミナル内で実行する場合、プロデューサターミナル内にメッセージを入力することができ、それらがコンシューマターミナル内に現れるのを見るでしょう。

    コマンドラインツールの全ては追加のオプションを持ちます; 引数無しのコマンドの実行は使い方のもっと詳しい説明を表示するでしょう。

    ステップ 6: 複数のブローカークラスタのセットアップ

    これまでのところ1つのブローカーを実行してきましたが、それは楽しくありません。Kafkaにとっては1つのブローカーはサイズが1のクラスタなので、ある程度のブローカーインスタンスを開始する以外の何も違いはありません。しかし、それを感じるために、クラスタを3つのノードに拡張してみましょう (まだ全てがローカルのマシーン上にあります)。

    まず、各ブローカーのための設定を作ります (Windows上では代わりにcopyコマンドを使います):

    > cp config/server.properties config/server-1.properties
    > cp config/server.properties config/server-2.properties
    

    今度はこれらの新しいファイルを編集し以下のプロパティを設定します:

    
    config/server-1.properties:
        broker.id=1
        listeners=PLAINTEXT://:9093
        log.dirs=/tmp/kafka-logs-1
    
    config/server-2.properties:
        broker.id=2
        listeners=PLAINTEXT://:9094
        log.dirs=/tmp/kafka-logs-2
    

    broker.id プロパティは、クラスタ内の各ノードのユニークで恒久的な名前です。同じマシーン上でこれら全てを実行していて、同じポート上に登録しようとする全てのブローカーを維持し、他のデータのそれぞれを上書きたいため、ポートとログディレクトリのみを上書く必要があります。

    すでにZookeeperがあり1つのノードを開始しているため、二つの新しいノードを開始する必要があります:

    > bin/kafka-server-start.sh config/server-1.properties &
    ...
    > bin/kafka-server-start.sh config/server-2.properties &
    ...
    

    今度は3つのリプリケーション ファクターを持つ新しいトピックを作成します:

    > bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic
    

    これで良いですが、今はクラスタがあるのでどうやってどのブローカーが何をしているのかを知ることができますか?それを見るには、"describe topics" コマンドを実行します:

    > bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
    Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
    	Topic: my-replicated-topic	Partition: 0	Leader: 1	Replicas: 1,2,0	Isr: 1,2,0
    

    ここからが出力の解説です。最初の行は全てのパーティションの概要を与え、各追加の行は1つのパーティションの情報を与えます。このトピックについて1つのパーティションのみを持つため、1つの行しかありません。

    • "header"は指定されたパーティションについて全ての読み書きに責任があるノードです。各ノードはランダムに選択されたパーティションの一部分についてのリーダーでしょう。
    • "replicas"はこのパーティションに関して、それらがリーダーかどうか、あるいは現在活動状態かどうかさえも関係なく、ログをリプリケートするノードのリストです。
    • "isr"は"in-sync"リプリカのセットです。これは現在活動中でリーダーに追いついてきているレプリカリストの部分集合です。

    例では、ノード1がトピックの唯一のパーティションのためのリーダーであることに注意してください。

    どこにあるかを見るために、生成した元のトピック上で同じコマンドを実行することができます:

    > bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
    Topic:test	PartitionCount:1	ReplicationFactor:1	Configs:
    	Topic: test	Partition: 0	Leader: 0	Replicas: 0	Isr: 0
    

    何も驚くことはありません — 元のトピックはレプリカを持たず、server 0、それを生成した時にはクラスタ内での唯一のサーバ、にあります。

    新しいトピックに2,3のメッセージを発行してみましょう:

    > bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic
    ...
    my test message 1
    my test message 2
    ^C
    

    今度はこれらのメッセージを消費してみましょう:

    > bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
    ...
    my test message 1
    my test message 2
    ^C
    

    今度は耐障害性を試してみましょう。ブローカー1はリーダーとして振る舞っていました。そういうわけでそれをkillしましょう:

    > ps aux | grep server-1.properties
    7564 ttys002    0:15.91 /System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java...
    > kill -9 7564
    
    Windowsでの使い方:
    > wmic process where "caption = 'java.exe' and commandline like '%server-1.properties%'" get processid
    ProcessId
    6016
    > taskkill /pid 6016 /f
    

    リーダーシップはスレーブの一つに切り替わり、ノード1はin-syncレプリカセットの中にはもういません:

    > bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
    Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
    	Topic: my-replicated-topic	Partition: 0	Leader: 2	Replicas: 1,2,0	Isr: 2,0
    

    しかし、もともと書き込んだリーダーがダウンしたにも関わらず、メッセージはまだ消費可能です:

    > bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
    ...
    my test message 1
    my test message 2
    ^C
    

    ステップ 7: データをインポート/エクスポートするためにKafka Connectを使用

    コンソールからデータを書き込み、コンソールに書き込み返すのは始めるのに具合が良いですが、おそらく他のソースからのデータを使うかKafkaから他のシステムへデータをエクスポートしたいでしょう。多くのシステムについて、データをインポートあるいはエクスポートするために独自の統合コードを書く代わりにKafka Connectを使うことができます。

    Kafka Connect はKafkaにデータをインポートあるいはエクスポートするKafkaに含まれているツールです。connectorsを実行する拡張ツールで、外部システムと相互作用するための独自のロジックを実装します。このクイックスタートの中で、ファイルからKafkaトピックへデータをインポートしKafkaトピックからファイルへデータをエクスポートする単純なコネクタを使ってKafka Connectを実行する方法を見ます。

    まず、テストするためのいくつの種のデータを作成することで始めます:

    > echo -e "foo\nbar" > test.txt
    
    あるいは Windows では:
    > echo foo> test.txt
    > echo bar>> test.txt
    

    次に、スタンドアローン モードで実行中の二つのコネクタを開始します。これは1つのローカルの専用のプロセス内で実行することを意味します。パラメータとして3つの設定ファイルを与えます。一番最初は常にKafkaコネクト処理のための設定で、Kafkaブローカーの接続先およびデータのシリアライズ形式のような一般的な設定を含みます。残りの設定ファイルはそれぞれ生成するコネクタを指定します。これらのファイルはユニークなコネクタ名、インスタンス化するコネクタクラス、およびコネクタによって必要とされるその他の設定を含みます。

    > bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties
    

    これらの例の設定ファイルは、Kafkaに含まれ、前に開始したデフォルトのローカルクラスタの設定を使用し、二つのコネクタを生成します: 1つ目のコネクタは入力ファイルから行を読み込むソースコネクタで、Kafkaトピックにそれぞれを生成します。二つ目のコネクタはKafkaトピックからメッセージを読み込み、出力ファイル中に行としてそれぞれを生成するシンクコネクタです。

    スタートアップの間に、コネクタがインスタンス化されたことを示す多くのログメッセージを見るでしょう。一度Kafkaコネクトの処理が開始されると、ソースのコネクタはtest.txt からの行の読み込みを開始し、それらをトピックconnect-testへ生成しなければなりません。シンクのコネクタはトピックconnect-testからメッセージの読み込みを開始し、それらをファイルtest.sink.txtに書き込まなければなりません。出力ファイルの内容を調べることでパイプライン全体を通して配送されるデータを検証することができます。

    > more test.sink.txt
    foo
    bar
    

    データはKafkaトピックconnect-test内に格納されることに注意してください。つまり、トピック内のデータを見るためにコンソールのコンシューマを実行することもできます (あるいはそれを処理するために独自のコンシューマコードを使います):

    > bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
    {"schema":{"type":"string","optional":false},"payload":"foo"}
    {"schema":{"type":"string","optional":false},"payload":"bar"}
    ...
    

    コネクタはデータを処理しつづけます。つまり、データをファイルに追加しパイプラインを使って移動するのを見ることができます:

    > echo Another line>> test.txt
    

    コンシューマ出力のコンソール内とシンクファイル内に行が現れるのが見えるはずです。

    ステップ 8: データを処理するためにKafkaストリームを使う

    Kafkaストリームはミッション クリティカルなリアルタイムアプリケーションとマイクロサービスのためのクライアントライブラリです。この時、入力および/あるいは出力データはKafkaクラスタに格納されます。Kafkaストリームは、これらのアプリケーションがスケーラブルが高く、柔軟で、耐障害性があり、分散されるなど、クライアント側でKafkaのサーバクラスタの技術の恩恵を受けながら標準的なJavaとScalaアプリケーションを書くことと配備することの平易化を兼ね備えます。これは ライブラリ内でコード化されたストリームアプリケーションを実行する方法を示すでしょう。

    1.4エコシステム

    メインの配布物の他にKafkaを使って統合する有り余るほどのツールがあります。エコシステムのページはこれらの多くをリスト化し、ストリーム処理システム、Hadoop統合、監視および開発ツールを含みます。

    1.5以前のバージョンからのアップグレード

    Kafka 2.0.0 はwireプロトコルの変更を導入します。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードの前に2.0.0 での注目すべき変更を見直してください。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。 0.11.0.x, 1.0.x あるいは 1.1.x からアップグレードし、メッセージ形式を上書きしていない場合は、内部のブローカープロトコルの形式を上書きする必要だけがあります。
      • inter.broker.protocol.version=CURRENT_KAFKA_VERSION (0.11.0, 1.0, 1.1).
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 2.0 に設定することでプロトコルのバージョンを上げることができます。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    5. 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 2.0 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは 0.11で導入された新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。

    アップグレードの追加の注意:

    1. ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
    2. プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
    3. Kafkaストリームコード内でJava8のメソッドのリファレンスを使っている場合は、メソッドの曖昧さを解決するためにコードを更新する必要があるかもしれません。jarファイルのホット スワップだけではうまく行かないかもしれません。
    4. クラスタ内の全てのブローカーが更新されるまで、ACLはプリフィックスされたリソース (KIP-290で追加されました)に追加されるべきではありません。

      注意: クラスタが完全にアップグレードされた後であっても、クラスタに追加されたプリフィックス付きのACLは、クラスタが再びダウングレードされた場合に無視されます。

    2.0.0 での主要な変更
    • KIP-186 デフォルトのオフセット維持期間を1日から7日に増やします。これにより頻繁にコミットするアプリケーション内のオフセットを"失われ"にくくします。それはオフセットのアクティブなセットも増やし、従ってブローカー上のメモリの使用率を増やすことができます。コンソールのコンシューマは現在のところデフォルトでオフセットのコミットを有効にしており、この変更は今では1ではなく7日間保持して多数のオフセットのソースに成り得ることに注意してください。ブローカー設定のoffsets.retention.minutes を 1440 に設定することで既存の挙動を維持することができます。
    • Java 7のサポートは無くなり、今ではJava 8が必要とされる最小のバージョンです。
    • ssl.endpoint.identification.algorithmのデフォルトの値は httpsに変更されました。これはホスト名の検証を行います (そうでなければ中間者攻撃が可能です)。以前の挙動を復活されるには ssl.endpoint.identification.algorithm に空の文字を設定してください。
    • KAFKA-5674max.connections.per.ip minimumの下限間隔を0に拡張し、従って入ってくる接続のIPベースのフィルタリングができます。
    • KIP-272 は API バージョンタグをメトリックkafka.network:type=RequestMetrics,name=RequestsPerSec,request={Produce|FetchConsumer|FetchFollower|...}に追加しました。このメトリックは今では kafka.network:type=RequestMetrics,name=RequestsPerSec,request={Produce|FetchConsumer|FetchFollower|...},version={0|1|2|3|...} になります。これは自動的に集約しないJMX監視ツールに影響があるでしょう。特定のリクエスト型についての総数を取得するには、ツールが異なるバージョンを横断して集約できるように更新される必要があります。
    • KIP-225 トピックおよびパーティションのためのタグを使うためにメトリック "records.lag" を変更しました。名前形式 "{topic}-{partition}.records-lag" を持つ元のバージョンが削除されました。
    • 0.11.0.0から非推奨になった Scala コンシューマが削除されました。Java コンシューマは今ではgracefullyにシャットダウンします。1.1.0 (より古い)Scalaコンシューマは、ブローカーが2.0.0にアップグレードされたとしても動作し続けるでしょう。
    • 0.10.0.0から非推奨になった Scalaプロデューサは削除されました。Java プロデューサは0.9.0.0からお勧めのオプションになっています。Javaプロデューサのデフォルトのパーティショナーの挙動はScalaプロデューサのデフォルトのパーティショナーと異なることに注意してください。移設するユーザは以前の挙動を維持する独自のパーティショナーを設定することを考慮するべきです。1.1.0 (より古い)Scalaプロデューサは、ブローカーが2.0.0にアップグレードされたとしても動作し続けるでしょう。
    • MirrorMaker と ConsoleConsumer はScalaコンシューマをもうサポートしません。それらは常にJavaコンシューマを使います。
    • ConsoleProducer はScalaプロデューサをもうサポートしません。それは常にJavaプロデューサを使います。
    • Scalaクライアントに依存する多くの非推奨のツールが削除されました: ReplayLogProducer, SimpleConsumerPerformance, SimpleConsumerShell, ExportZkOffsets, ImportZkOffsets, UpdateOffsetsInZK, VerifyConsumerRebalance。
    • 非推奨の kafka.tools.ProducerPerformance が削除されました。org.apache.kafka.tools.ProducerPerformance を使ってください。
    • 古いバージョンからのローリング バウンス アップグレードが可能な新しいKafkaストリーム設定パラメータupgrade.from が追加されました。
    • KIP-284 はデフォルトの値から Long.MAX_VALUE に設定することでKafkaストリームのパーティショントピックの維持期間を変更しました。
    • 状態ストアをプロセッサ トポロジに登録するためのKafkaストリームの ProcessorStateManager APIを更新しました。詳細はストリームの更新ガイドを読んでください。
    • 早期リリースでは、コネクタのワーカーの設定は internal.key.converterinternal.value.converter プロパティを必要としました。2.0では、もう必要とされず、デフォルトはJSONコンバータになります。これらのプロパティをコネクト スタンドアローンおよび分散されたワーカー設定から削除することができます:
      internal.key.converter=org.apache.kafka.connect.json.JsonConverter internal.key.converter.schemas.enable=false internal.value.converter=org.apache.kafka.connect.json.JsonConverter internal.value.converter.schemas.enable=false
    • KIP-266はブロックするかもしれないKafkaConsumerAPIのために使われるデフォルトのタイムアウトを指定するために新しいコンシューマ設定 default.api.timeout.msを追加します。そのKIPはdefault.api.timeout.msによって設定されるデフォルトのタイムアウトを使用する代わりに、それらのそれぞれについて使う特定のタイムアウトの指定をサポートするためにそのようなブロッキングAPIに負荷も掛けます。特に、動的なパーティションの割り当てのためにブロックしない新しい poll(Duration) API が追加されました。古い poll(long) は非推奨になり、将来のバージョンで削除されるでしょう。Overloads have also been added for other KafkaConsumer methods like partitionsFor, listTopics, offsetsForTimes, beginningOffsets, endOffsets and close that take in a Duration.
    • KIP-266 の一部として、request.timeout.msのデフォルトの値が30秒に変更されました。以前の値はリバランスに掛かるだろう最大時間を考慮するために5分より少し高い値でした。今では特別な場合としてリバランスジのJoinGroupリクエストを扱い、リクエストのタイムアウトとしてmax.poll.interval.ms から派生した値を使います。他の全てのリクエストの型はrequest.timeout.msで定義されたタイムアウトを使います。
    • 内部メソッドkafka.admin.AdminClient.deleteRecordsBefore が削除されました。org.apache.kafka.clients.admin.AdminClient.deleteRecordsに移動することをお勧めします。
    • AclCommand ツール --producerの便利なオプションは指定されたトピック上でよりKIP-277のより細かいACLを使います。
    • KIP-176 は全てのコンシューマベースのツールについて --new-consumer オプションを削除します。このオプションは--bootstrap-server が定義された場合に新しいコンシューマが自動的に使われるため冗長です。
    • KIP-290 は例えば'foo'から始まるトピックのようなプリフィックス付きのリソース上でのACLを定義する機能を追加します。
    • KIP-283 はKafkaブローカーでのメッセージのダウン変換の処理を改善します。これは一般的にメモリに集中的な操作です。KIPは、一度にパーティションデータのチャンクをダウンコンバートすることで、メモリ消費量の上限に役立つように、メモリ集中が少なくなる仕組みを追加します。この改善により、ブローカーが無効なオフセットを使って特大のメッセージバッチを応答の最後に送信できるように FetchResponse プロトコルの挙動の変更があります。そのような特大のメッセージはKafkaConsumerによって行われるように、コンシューマクライアントによって無視されるべきです。

      KIP-283はダウンコンバートが有効かどうかを制御するために新しいトピックとブローカーの設定、それぞれmessage.downconversion.enablelog.message.downconversion.enable も追加します。無向な場合、ブローカーはダウンコンバージョンを行わず、代わりにクライアントにUNSUPPORTED_VERSIONエラーを送信します。

    • 動的なブローカー設定オプションはブローカーが開始される前に kafka-configs.sh を使ってZooKeeperに格納することができます。このオプションは全てのパスワードがZooKeeperに暗号化して格納されるように、server.propertiesの中で平文のパスワードで格納されることを避けるために使うことができます。
    • 接続の試行が失敗した場合、ZooKeeperのホストは今では再解決されます。しかしもしZooKeeperのホスト名が複数のアドレスに解決され、それらの幾つかが到達可能では無い場合、接続タイムアウトzookeeper.connection.timeout.msを増やす必要があるかもしれません。
    新しいプロトコルのバージョン
    • KIP-279: OffsetsForLeaderEpochResponse v1 はパーティションレベル leader_epoch フィールドを導入します。
    • KIP-219: クォータ違反で絞られた非クラスタ アクション リクエストと応答のプロトコルバージョンを上げます。
    • KIP-290: ACL create, descrbe および delete リクエストと応答のプロトコルバージョンを上げます。
    1.1 Kafkaストリーム アプリケーションのアップグレード
    • ストリームアプリケーションの 1.1 から 2.0 のアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 2.0 アプリケーションは 2.0, 1.1, 1.0, 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することができません)。
    • 2.0では、1.0より前で非推奨になったpublic API を削除したことに注意してください; それらの非推奨のAPIのユーザの利用は適宜コードの変更が必要です。詳細は2.0.0でのストリーム APIの変更を見てください。

    0.8.x, 0.9.x, 0.10.0.x, 0.10.1.x, 0.10.2.x, 0.11.0.x あるいは 1.0.x から 1.1.x へのアップグレード

    Kafka 1.1.0 はwireプロトコルの変更を導入します。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードの前に1.1.0 での注目すべき変更を見直してください。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。 0.11.0.x あるいは 1.0.x からアップグレードし、メッセージ形式を上書きしていない場合は、内部のブローカープロトコルの形式を上書きする必要だけがあります。
      • inter.broker.protocol.version=CURRENT_KAFKA_VERSION (0.11.0 あるいは 1.0)。
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 1.1 に設定することでプロトコルのバージョンを上げることができます。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    5. 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 1.1 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは 0.11で導入された新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。

    アップグレードの追加の注意:

    1. ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
    2. プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
    3. Kafkaストリームコード内でJava8のメソッドのリファレンスを使っている場合は、メソッドの曖昧さを解決するためにコードを更新する必要があるかもしれません。jarファイルのホット スワップだけではうまく行かないかもしれません。
    1.1.1 での主要な変更
    • バージョン 0.10.0.x からのローリング バウンス アップグレードが可能な新しいKafkaストリーム設定パラメータ upgrade.fromが追加されました
    • この新しい設定についての詳細は Kafka ストリーム アップグレード ガイド を見てください。
    1.1.0での主要な変更
    • Mavenでのkafkaのアーティファクトは log4j あるいは slf4j-log4j12 にもう依存しません。kafkaクライアントのアーティファクトと同様に、今ではユーザは適切な slf4j モジュール (slf4j-log4j12, logback など)を含めることでログのバックエンドを選択することができます。リリースのtarballはまだ log4j と slf4j-log4j12 を含みます。
    • KIP-225 トピックおよびパーティションのためのタグを使うためにメトリック "records.lag" を変更しました。名前形式 "{topic}-{partition}.records-lag" を持つ元のバージョンは非推奨になり、2.0.0で削除されるでしょう。
    • Kafkaストリームはブローカーの通信エラーに対してより丈夫になりました。fatal例外でKafkaストリーム クライアントを停止する代わりに、Kafkaストリームは自己回復しクラスタへ再接続しようとします。新しいAdminClientを使用すると、Kafkaストリームがどれだけ再試行するかをより良く制御し、(古いバージョンのようにハードコードされた再試行の代わりに)細かいタイムアウトを設定することができます。
    • Kafkaストリームのリバランス時間が更に削減され、Kafkaストリームのレスポンスが構造しました。
    • 今ではKafkaコネクトはシンクとソースコネクタの両方でメッセージヘッダをサポートし、単純なメッセージ変換を使って操作できるようになりました。コネクタは明示的にそれらを使うように変更されなければなりません。ヘッダがどのように(デ)シリアライズ化されるかを制御するために新しいHeaderConverterが導入され、値の文字列表現を使うためにデフォルトで新しい "SimpleHeaderConverter" が使われます。
    • もしprint-data-logがデコーダのような他のオプションのために明示的あるいは暗黙的に有効な場合、kafka.tools.DumpLogSegmentsは今では自動的にdeep-iterationオプションを設定します。
    新しいプロトコルのバージョン
    • KIP-226で DescribeConfigs Request/Response v1 を導入しました。
    • KIP-227でフェッチ リクエスト/応答 v7 を導入しました。
    1.0 Kafkaストリームアプリケーションのアップグレード
    • ストリームアプリケーションの 1.0 から 1.1 のアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 1.1 アプリケーションは 1.0, 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することはできません)。
    • 詳細は1.1.0でのストリームAPIの変更 を見てください。

    0.8.x, 0.9.x, 0.10.0.x, 0.10.1.x, 0.10.2.x あるいは 0.11.0.x から 1.0.0 へのアップグレード

    Kafka 1.0.0 はwireプロトコルの変更を導入します。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードの前に1.0.0 での注目すべき変更を見直してください。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。 0.11.0.xからアップグレードしメッセージ形式を上書きしていない場合は、メッセージ形式のバージョンと内部ブローカーのプロトコルのバージョンの両方を 0.11.0 に設定する必要があります。
      • inter.broker.protocol.version=0.11.0
      • log.message.format.version=0.11.0
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 1.0 に設定することでプロトコルのバージョンを上げることができます。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    5. 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 1.0 に変更し、それらを1つずつ再起動します。0.11.0 からアップグレードし log.ssage.format.version が 0.11.0 に設定されている場合、設定を更新し、ローリング再起動をスキップすることができます。古いScalaのコンシューマは 0.11で導入された新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。

    アップグレードの追加の注意:

    1. ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
    2. プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
    1.0.2 での主要な変更
    • バージョン 0.10.0.x からのローリング バウンス アップグレードが可能な新しいKafkaストリーム設定パラメータ upgrade.fromが追加されました
    • この新しい設定についての詳細は Kafka ストリーム アップグレード ガイド を見てください。
    1.0.1 での主要な変更
    • 0.11.0.x のAdminClientのオプションクラス (例えば、 CreateTopicsOptions, DeleteTopicsOptions など)のバイナリ互換性が復活されました。(ソースではなく)バイナリの互換性は 1.0.0 で不注意で壊れていました。
    1.0.0 での主要な変更
    • トピックの削除が今では安定したため、今はその機能がデフォルトで有効です。以前の挙動を保持したいユーザはブローカーの設定delete.topic.enablefalseに設定してください。トピックの削除はデータを削除しオペレーションが可逆ではないことに注意してください (つまり、"undelete" オペレーションはありません)
    • パーティションについてオフセットが見つからない場合はタイムスタンプの検索がサポートされます。そのパーティションは今はnullオフセット値を使って検索結果に含まれます。以前は、パーティションはマップ内に含まれませんでした。この変更は検索の挙動がタイムスタンプ検索をサポートしないトピックの場合と一貫性を持つように行われました。
    • inter.broker.protocol.version が 1.0以上の場合、ブローカーはオフラインのログディレクトリがあるとしてもライブ ログディレクトリ上でレプリカを提供するためにオンラインで有り続けるでしょう。ログディレクトリはハードウェアの障害による IOException のためにオフラインになるかもしれません。ユーザはオフラインログディレクトリがあるかどうかを調べるためにブローカーごとのメトリックofflineLogDirectoryCount を監視する必要があります。
    • 回復可能な例外である KafkaStorageException が追加されました。クライアントの FetchRequest あるいは ProducerRequest のバージョンが KafkaStorageException をサポートしない場合、KafkaStorageException は 応答の中で NotLeaderForPartitionException に変換されるでしょう。
    • -XX:+DisableExplicitGC はデフォルトのJVM設定の中で -XX:+ExplicitGCInvokesConcurrent に置き換えられました。これはある状況下で直接のバッファによるネイティブなメモリの割り当ての間に、メモリ不足例外を避けるのに役立ちます。
    • 上書きされた handleError メソッドの実装は、kafka.api package: FetchRequest, GroupCoordinatorRequest, OffsetCommitRequest, OffsetFetchRequest, OffsetRequest, ProducerRequest および TopicMetadataRequest の中の以下の非推奨のクラスから削除されました。これはブローカー上での使用だけを目的としていましたが、もう使われておらず、実装はメンテナンスされていませんでした。スタブ 実装はバイナリ互換性のために維持されています。
    • Java クライアントとツールは、今では cient-id としてどのような文字も受け付けます。
    • 非推奨のツール kafka-consumer-offset-checker.sh が削除されました。コンシューマ グループの詳細を取得するには、kafka-consumer-groups.sh を使ってください。
    • SimpleAclAuthorizer は今ではデフォルトでオーソライザへのアクセス拒否を記録します。
    • 認証の失敗は今ではAuthenticationException のサブクラスの1つとしてクライアントに報告されます。クライアント接続が認証を失敗した場合はリトライはされないでしょう。
    • 独自の SaslServer 実装は、クライアントに認証エラーを示すエラーメッセージを返すために SaslAuthenticationException を投げるかもしれません。実装者は認証されなかったクライアントへ漏らすべきでは無いセキュリティに重要な情報を例外メッセージの中に含めないように注意しなければなりません。
    • バージョンおよびコミットidを提供するためにJMXに登録されたapp-info mbean は非推奨になり、これらの属性を提供するメトリクスに置き換えられるでしょう。
    • Kafka のメトリクスは今では非数値の値を含むかもしれません。org.apache.kafka.common.Metric#value() は非推奨になり、各クライアントのメトリックの値を読み込むユーザを壊す可能性を最小限にするために0.0 を返すでしょう (MetricsReporter 実装経由またはmetrics()メソッドの呼び出し)。org.apache.kafka.common.Metric#metricValue() は数字あるいは非数字のメトリック値を扱うために使うことができます。
    • 各Kafkaのレートのメトリックはダウンストリームの処理を簡単にするために今ではサフィックス-totalを使って対応する累積カウントメトリックを持ちます。例えば、records-consumed-raterecords-consumed-totalという名前の対応するメトリックを持ちます。
    • Mx4j はシステム プロパティ kafka_mx4jenabletrue に設定された場合にのみ有効にされるでしょう。論理の反転バグにより、以前はデフォルトで有効で、もしkafka_mx4jenabletrue に設定された場合には無効でした。
    • クライアントのjar のパッケージorg.apache.kafka.common.security.auth は公開され、javadocsに追加されました。以前にこのパッケージに配置されていた内部クラスは他の場所に移動されました。
    • オーソライザーを使っており、ユーザがトピックに必要な権限を持たない場合、ブローカーはブローカー上のトピックの存在に関係ないリクエストに TOPIC_AUTHORIZATION_FAILED エラーを返すでしょう。もしユーザが必要なパーミッションを持ち、トピックが存在しない場合は、UNKNOWN_TOPIC_OR_PARTITION エラーコードが返されるでしょう。
    • 新しいコンシューマの設定プロパティを使うために、config/consumer.properties ファイルが更新されます。
    新しいプロトコルのバージョン
    • KIP-112: LeaderAndIsrRequest v1 でパーティションレベル is_new フィールドが導入されます。
    • KIP-112: UpdateMetadataRequest v4 でパーティションレベル offline_replicas フィールドが導入されます。
    • KIP-112: MetadataResponse v5 でパーティションレベル offline_replicas フィールドが導入されます。
    • KIP-112: ProduceResponse v4 で KafkaStorageException のためのエラーコードが導入されます。
    • KIP-112: FetchResponse v6 で KafkaStorageException のためのエラーコードが導入されます。
    • KIP-152: SaslAuthenticate リクエスト が認証の失敗の報告を有効にするために追加されました。このリクエストはもし SaslHandshake リクエストのバージョンが 0より大きい場合に使われるでしょう。
    0.11.0 Kafkaストリーム アプリケーションの更新
    • ストリームアプリケーションを0.11.0から1.0へ更新するにはブローカーの更新を必要としません。Kafkaストリーム 1.0 アプリケーションは 0.11.0, 0.10.2 および 0.10.1 ブローカーと接続することができます (しかし 0.10.0ブローカーへ接続することはできません)。しかし、Kafkaストリーム 1.0 は 0.10以上のメッセージ形式を必要とし、古いメッセージ形式とは動作しません。
    • メトリクスのセンサー構造が変更されたため、ストリームのメトリクスを監視している場合は、レポート内と監視コード内のメトリクス名にいくつか変更をする必要があるでしょう。
    • ProcessorContext#schedule(), Processor#punctuate() を含む少しのpublic APIがあり、KStreamBuilder, TopologyBuilder は新しいAPIによって非推奨になりました。対応するコードの変更を行うことをお勧めします。新しいAPIはとてもよく似ているため、アップグレードするには大したことはないでしょう。
    • 詳細はStreams API changes in 1.0.0 を見てください。
    0.10.2のKafkaストリームアプリケーションをアップグレード
    • ストリームアプリケーションを0.10.2から1.0へ更新するにはブローカーの更新を必要としません。Kafka ストリーム 1.0 アプリケーションは 1.0, 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することはできません)。
    • メトリクスのセンサー構造が変更されたため、ストリームのメトリクスを監視している場合は、レポート内と監視コード内のメトリクス名にいくつか変更をする必要があるでしょう。
    • ProcessorContext#schedule(), Processor#punctuate() を含む少しのpublic APIがあり、KStreamBuilder, TopologyBuilder は新しいAPIによって非推奨になりました。対応するコードの変更を行うことをお勧めします。新しいAPIはとてもよく似ているため、アップグレードするには大したことはないでしょう。
    • 設定内で 独自のkey.serde, value.serde および timestamp.extractor を指定する場合は、これらの設定が非推奨のため、それらの置き換えられた設定パラメータを使うことをお勧めします。
    • 詳細はStreams API changes in 0.11.0 を見てください。
    0.10.1のKafkaストリームアプリケーションをアップグレード
    • ストリームアプリケーションを 1.10.1 から 1.0 へ更新するにはブローカーの更新を必要としません。Kafka ストリーム 1.0 アプリケーションは 1.0, 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することはできません)。
    • コードを再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • メトリクスのセンサー構造が変更されたため、ストリームのメトリクスを監視している場合は、レポート内と監視コード内のメトリクス名にいくつか変更をする必要があるでしょう。
    • ProcessorContext#schedule(), Processor#punctuate() を含む少しのpublic APIがあり、KStreamBuilder, TopologyBuilder は新しいAPIによって非推奨になりました。対応するコードの変更を行うことをお勧めします。新しいAPIはとてもよく似ているため、アップグレードするには大したことはないでしょう。
    • 設定内で 独自のkey.serde, value.serde および timestamp.extractor を指定する場合は、これらの設定が非推奨のため、それらの置き換えられた設定パラメータを使うことをお勧めします。
    • TimestampExtractor インタフェースが変更されたため、独自の(つまりユーザ実装の)タイムスタンプ エクストラクタを使う場合は、このコードを更新する必要があるでしょう。
    • StreamsMetric インタフェースが変更されたため、独自のメトリクスを登録する場合、このコードを変更する必要があるでしょう。
    • 詳細は1.0.0でのストリームAPIの変更, 0.11.0でのストリームAPIの変更 および 0.10.2でのストリームAPIの変更を見てください。
    0.10.0のKafkaストリームアプリケーションをアップグレード
    • Kafkaストリーム 1.0 アプリケーションは 0.1, 0.11.0, 0.10.2 あるいは 0.10.1 ブローカーへのみ接続することができるため、ストリームアプリケーションの 0.10.0 から 1.0 へのアップグレードはブローカーのアップグレードを必要とします。
    • 2,3のAPIの変更があります。後方互換性はありません(参照詳細は1.0.0でのストリームAPIの変更, 0.11.0でのストリームAPIの変更, 0.10.2でのストリームAPIの変更 および 0.10.1でのストリームAPIの変更 を見てください。このように、コードを更新し再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • 0.10.0.xから1.0.2への更新は、最初の更新フェーズについて設定upgrade.from="0.10.0"セットを伴う2回のローリング バウンスを必要とします (参照KIP-268)。別のやり方として、オフラインの更新も可能です。
      • ローリングバウンスのためのアプリケーションインスタンスを準備し、新しいバージョン 0.11.0.3 のために設定upgrade.from"0.10.0" に設定するようにしてください。
      • アプリケーションの各インスタンスを一度バウンスします
      • 2回目のローリングバウンスのために新しく配備された 1.0.2 アプリケーションインスタンスを準備します; 設定upgrade.modeのための値を削除するようにしてください
      • アップグレードを完了するためにもう一度各アプリケーションのインスタンスをバウンスします
    • 0.10.0.x から 1.0.0 あるいは 1.0.1 へのアップグレードはオフライン アップグレードを必要とします (ローリング バウンス アップグレードはサポートされません)
      • 全ての古い (0.10.0.x) アプリケーションのインスタンスを停止します
      • コードを更新し、古いコードとjarファイルを新しいコードと新しいjarファイルと交換します
      • 全ての新しい (1.0.0 あるいは 1.0.1) アプリケーションのインスタンスを再起動します

    0.8.x, 0.9.x, 0.10.0.x, 0.10.1.x あるいは 0.10.2.x から 0.11.0.0 へのアップグレード

    Kafka 0.11.0.0 は新しいメッセージフォーマットのバージョンとwireプロトコルの変更を導入します。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードの前に0.11.0.0 での注目すべき変更を見直してください。

    バージョン 0.10.2から、Javaクライアント (プロデューサとコンシューマ)は古いブローカーと通信することができるようになりました。バージョン 0.11.0 のクライアントはバージョン 0.10.0 あるいはそれより新しいブローカーと話すことができます。しかし、ブローカーが 0.10.0 より古い場合は、クライアントをアップグレードする前にKafkaクラスタ内の全てのブローカーをアップグレードしなければなりません。バージョン 0.11.0 のブローカーは 0.8.x とそれより新しいクライアントをサポートします。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は現在使用している現在のメッセージフォーマットを参照します。以前にメッセージフォーマットを上書きしていない場合は、CURRENT_MESSAGE_FORMAT_VERSION は CURRENT_KAFKA_VERSION に一致しなければなりません。
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.versionを編集し 0.10.0.0 に設定します。しかしまだ log.message.format.versionを変更してはいけません。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    5. 一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 0.11.0 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。

    アップグレードの追加の注意:

    1. ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
    2. プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
    3. グローバル設定log.message.format.versionを更新する前に、トピック管理ツール(bin/kafka-topics.sh) を使って個々のトピック上で 0.11.0 メッセージフォーマットを有効にすることも可能です。
    4. 0.10.0より前のバージョンからアップグレードしている場合は、0.11.0 に切り替える前に最初にメッセージフォーマットを 0.10.0 に更新する必要はありません。
    0.10.2のKafkaストリームアプリケーションをアップグレード
    • ストリームアプリケーションの 0.10.2 から 0.11.0 へのアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 0.11.0 アプリケーションは 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することはできません)。
    • 設定内で 独自のkey.serde, value.serde および timestamp.extractor を指定する場合は、これらの設定が非推奨のため、それらの置き換えられた設定パラメータを使うことをお勧めします。
    • 詳細はStreams API changes in 0.11.0 を見てください。
    0.10.1のKafkaストリームアプリケーションをアップグレード
    • ストリームアプリケーションの 0.10.1 から 0.11.0 へのアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 0.11.0 アプリケーションは 0.11.0, 0.10.2 および 0.10.1 ブローカーへ接続することができます (ですが、0.10.0 ブローカーに接続することはできません)。
    • コードを再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • 設定内で 独自のkey.serde, value.serde および timestamp.extractor を指定する場合は、これらの設定が非推奨のため、それらの置き換えられた設定パラメータを使うことをお勧めします。
    • TimestampExtractor インタフェースが変更されたため、独自の(つまりユーザ実装の)タイムスタンプ エクストラクタを使う場合は、このコードを更新する必要があるでしょう。
    • StreamsMetric インタフェースが変更されたため、独自のメトリクスを登録する場合、このコードを変更する必要があるでしょう。
    • 詳細は0.11.0でのストリームAPIの変更, 0.10.2でのストリームAPIの変更 を見てください。
    0.10.0のKafkaストリームアプリケーションをアップグレード
    • Kafkaストリーム 0.11.0 アプリケーションは 0.11.0, 0.10.2 あるいは 0.10.1 ブローカーへのみ接続することができるため、ストリームアプリケーションの 0.10.0 から 0.11.0 へのアップグレードはブローカーのアップグレードを必要とします。
    • 2,3のAPIの変更があります。後方互換性はありません(参照詳細は0.11.0 でのストリームAPIの変更, 0.10.2でのストリームAPIの変更 および 0.10.1 でのストリームAPIの変更を見てください)。このように、コードを更新し再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • 0.10.0.xから0.11.0.3への更新は、最初の更新フェーズについて設定upgrade.from="0.10.0"セットを伴う2回のローリング バウンスを必要とします (参照KIP-268)。別のやり方として、オフラインの更新も可能です。
      • ローリングバウンスのためのアプリケーションインスタンスを準備し、新しいバージョン 0.11.0.3 のために設定upgrade.from"0.10.0" に設定するようにしてください。
      • アプリケーションの各インスタンスを一度バウンスします
      • 2回目のローリングバウンスのために新しく配備された 0.11.0.3 アプリケーションインスタンスを準備します; 設定upgrade.modeのための値を削除するようにしてください
      • アップグレードを完了するためにもう一度各アプリケーションのインスタンスをバウンスします
    • 0.10.0.x から 0.11.0.0, 0.11.0.1 あるいは 0.11.0.2 へのアップグレードはオフライン アップグレードを必要とします (ローリング バウンス アップグレードはサポートされません)
      • 全ての古い (0.10.0.x) アプリケーションのインスタンスを停止します
      • コードを更新し、古いコードとjarファイルを新しいコードと新しいjarファイルと交換します
      • 全ての新しい (0.11.0.0 , 0.11.0.1 あるいは 0.11.0.2) アプリケーションのインスタンスを再起動します
    0.11.0.3 での主要な変更
    • バージョン 0.10.0.x からのローリング バウンス アップグレードが可能な新しいKafkaストリーム設定パラメータ upgrade.fromが追加されました
    • この新しい設定についての詳細は Kafka ストリーム アップグレード ガイド を見てください。
    0.11.0.0 での主要な変更
    • 不透明なリーダー選出は今はデフォルトで無効です。新しいデフォルトは可用性よりも耐久性を好みます。以前の挙動を保持したいユーザはブローカーの設定unclean.leader.election.enabletrueに設定してください。
    • プロデューサの設定block.on.buffer.full, metadata.fetch.timeout.ms および timeout.ms は削除されました。それらはKafka 0.9.0.0 で最初に非推奨になりました。
    • offsets.topic.replication.factor ブローカー設定は、今では自動トピック設定を強制されます。クラスタのサイズがこのリプリケーション要素の要請に合うまで、内部的な自動トピックの生成は GROUP_COORDINATOR_NOT_AVAILABLE エラーで失敗するでしょう。
    • snappyを使ってデータを圧縮する場合、プロデューサとブローカーは圧縮レートを改善するために1KBの代わりに圧縮のスキーマのデフォルトのブロックサイズ (2 x 32 KB) を使うでしょう。大きなブロックサイズで圧縮される場合、小さなブロックサイズで圧縮されたデータより50%大きくなるという報告があります。snappyの場合については、5000のパーティションを持つプロデューサは更に 315 MB の JVM ヒープを必要とするでしょう。
    • 同様に、gzipでデータを圧縮する場合は、プロデューサとブローカーはバッファサイズとして1 KBではなく 8 KBを使うでしょう。gzipのデフォルトは過度に低いです (512 バイト)。
    • ブローカーの設定 max.message.bytes は今はメッセージのバッチの総サイズに適用されます。以前は、設定は圧縮されたメッセージあるいは非圧縮のメッセージに即座に適用されていました。メッセージのバッチは1つのメッセージからのみ成るかもしれません。つまりほとんどの場合において個々のメッセージのサイズの制限はバッチのフォーマットのオーバーヘッドによってのみ削減されます。しかし、フォーマットの交換はわずかな意味があります (詳細は以下 を見てください)。以前はブローカーは(総およびパーティションレベルの取り出しサイズに関係なく)少なくとも1つのメッセージが各取り込みリクエストで返されることが保証されていましたが、同じ挙動が今では1つのメッセージバッチに適用されることにも注意してください。
    • GC ログのローテーションがデフォルトで有効です。詳細は KAFKA-3754 を見てください。
    • 非推奨の RecordMetadata, MetricName および Cluster クラスのコンストラクタが削除されました。
    • ユーザヘッダの読み込みと書き込みアクセスを提供する新しいヘッダインタフェースを使ってユーザヘッダのサポートが追加されました。
    • ProducerRecord と ConsumerRecord はHeaders headers()メソッド呼び出しを使って新しいヘッダを公開します。
    • ExtendedSerializer と ExtendedDeserializer インタフェースがヘッダのシリアライズ化とデシリアライズ化をサポートするために導入されました。設定されたシリアライザおよびデシリアライザが上のクラスではない場合、ヘッダは無視されるでしょう。
    • 新しい設定 group.initial.rebalance.delay.ms が導入されました。この設定は、GroupCoordinator が初期のコンシューマのリバランスで待つ時間をミリ秒で指定します。リバランスは新しいメンバーがグループに加わった時にgroup.initial.rebalance.delay.msの値だけ更に遅延し、max.poll.interval.msの最大まで遅延するでしょう。これのデフォルトの値は3秒です。開発及びテスト時には、テスト実行の時間を遅らせないために、これを0に設定することが望ましいかもしれません。
    • org.apache.kafka.common.Cluster#partitionsForTopic, partitionsForNode および availablePartitionsForTopic メソッドは、必要とされるトピックのメタデータが存在しない場合、null の代わりに空のリストを返すでしょう (これは悪い慣習と見なされます) 。
    • ストリーム API 設定 パラメータ timestamp.extractor, key.serde および value.serde は非推奨で、それぞれ default.timestamp.extractor, default.key.serde および default.value.serde に置き換えられました。
    • Java コンシューマの commitAsync API 内のオフセット コミットの失敗については、RetriableCommitFailedExceptionのインスタンスがコミットのコールバックに返される時にもう潜在的な原因を公開しません。詳細はKAFKA-5052 を見てください。
    新しいプロトコルのバージョン
    • KIP-107: FetchRequest v5 はパーティションレベルの log_start_offset フィールドを導入します。
    • KIP-107: FetchResponse v5 はパーティションレベルの log_start_offset フィールドを導入します。
    • KIP-82: ProduceRequest v3 はkey フィールドと value フィールドを含むメッセージプロトコル内のheaderの配列を導入します。
    • KIP-82: FetchResponse v3 はkey フィールドと value フィールドを含むメッセージプロトコル内のheaderの配列を導入します。
    確実に1回のセマンティクスについての注意

    Kafka 0.11.0 はプロデューサ内の等冪とトランザクションの機能のためサポートを含みます。等冪の配送は1つのプロデューサの寿命の間にメッセージが確実に1回だけ特定のトピックのパーティションに配送されることを保証します。トランザクション的な配送により、プロデューサはデータを複数のパーティションに送信することができ、全てのメッセージの配送が成功するかあるいはどのメッセージも配送されません。これらの機能が合わさって、Kafkaでの"確実に1回のセマンティクス"を有効にします。これらの機能の詳細はユーザガイド内で利用可能ですが、以下にアップグレードされたクラスタ内でそれらを有効にする際の2,3の具体的な注意を追加します:EoSを有効にする必要はなく、使わない場合はブローカーの挙動には影響がないことに注意してください。

    1. 新しいJavaプロデューサとコンシューマのみが確実に1回のセマンティクスをサポートします。
    2. これらの機能は 0.11.0 メッセージ フォーマットに決定的に依存します。古いフォーマットでそれらを使おうとすると、サポートされないバージョンのエラーになるでしょう。
    3. トランザクションの状態は新しい内部的なトピック __transaction_state に格納されます。個のトピックは最初にトランザクション的なリクエストAPIを使おうとするまで生成されません。コンシューマのオフセット トピックに似て、トピックの設定を制御する幾つかの設定があります。例えば、transaction.state.log.min.isr はこのトピックのための最小のISRを制御します。オプションの完全なリストについてはユーザガイド内の設定の章を見てください。
    4. 安全なクラスタのために、トランザクション的なAPIは bin/kafka-acls.shを使って有効にすることができる新しいACLを必要とします。tool.
    5. KafkaでのEoSは新しいAPIを導入し、いくつかの既存のものを修正します。完全な詳細はKIP-98 を見てください。
    0.11.0での新しいメッセージフォーマットの注意

    0.11.0 メッセージフォーマットはプロデューサのためにより良い配送のセマンティクスをサポートするために幾つかの大きな拡張(KIP-98を見てください)と、改善されたリプリケーションの耐障害性(KIP-101を見てください)を含みます。新しいフォーマットはこれらの改善を可能にするためにより多くの情報を含みますが、バッチ形式をもっと効率的にしました。バッチごとのメッセージの数が2以上である限り、全体のオーバーヘッドが低くなることを期待することができます。しかし、より小さなバッチについては小さなパフォーマンスの影響があるかもしれません。新しいメッセージフォーマットの初期のパフォーマンスの解析結果については、ここを見てください。KIP-98 の提案の中でメッセージフォーマットのより詳細について見つけることもできます。

    新しいメッセージでの注目すべき違いの一つは、圧縮されていないメッセージでさえも1つのバッチとして一緒に格納されることです。これはブローカーの設定 max.message.bytes に関して少しの意味合いを持ちます。これは1つのバッチのサイズを制限します。最初に、もし古いクライアントが古いフォーマットを使っているトピックのパーティションにメッセージを生成し、メッセージが個々に max.message.bytesより小さい場合、上位変換の処理中にメッセージが1つのバッチにマージされた後でブローカーはまだ拒否するかもしれません。一般的に、個々のメッセージの集約サイズが max.message.bytes より大きい場合にこれが起きるでしょう。新しいフォーマットからダウン-コンバートされたメッセージを読み込む古いコンシューマにとって似たような効果があります: もし取得サイズが少なくともmax.message.bytesと同じ大きさに設定されていない場合、もし個々の圧縮されていないメッセージが設定された取得サイズよりも小さい場合にコンシューマは進めることができないかもしれません。Java クライアント 0.10.1.0 以上に関しては取得サイズを超えても少なくとも1回のメッセージを返すことが保証される更新された取得プロトコルを使うため、この挙動は影響ありません。これらの問題を避けるために、1) プロデューサのバッチサイズが max.message.bytesより大きく設定されていないこと、2) コンシューマの取得サイズが少なくともmax.message.bytesと同じ大きさに設定されていることを確実にする必要があります。

    0.10.0 メッセージ フォーマットへのアップグレードのパフォーマンスへの影響のほとんどの議論は 0.11.0 のアップグレードに関係しています。そのような場合に"zero-copy" 転送がすでに可能ではないために、TLSを使って安全にされていないクラスタに主に影響します。ダウン-コンバージョンのコストを避けるために、コンシューマアプリケーションが最新の0.11.0クライアントにアップグレードされることを確実にする必要があります。古いコンシューマが0.11.0.0で非推奨になったために、新しいメッセージ形式をサポートしません。ダウン-コンバージョンのコスト無しで新しいメッセージ形式を使う新しいコンシューマを使うためにアップグレードする必要があります。0.11.0コンシューマは0.10.0以上のブローカーとの後方互換性をサポートするため、ブローカーの前に最初にクライアントをアップグレードすることができることに注意してください。

    0.8.x, 0.9.x, 0.10.0.x あるいは 0.10.1.x to 0.10.2.0 からのアップグレード

    0.10.2.0 にはwireプロトコルの変更があります。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードの前に0.11.2.0 での注目すべき変更を見直してください。

    バージョン 0.10.2から、Javaクライアント (プロデューサとコンシューマ)は古いブローカーと通信することができるようになりました。バージョン 0.10.2 のクライアントはバージョン 0.10.0 あるいはそれより新しいブローカーと話すことができます。しかし、ブローカーが 0.10.0 より古い場合は、クライアントをアップグレードする前にKafkaクラスタ内の全てのブローカーをアップグレードしなければなりません。バージョン 0.10.2 のブローカーは 0.8.x とそれより新しいクライアントをサポートします。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.2 に設定することでプロトコルのバージョンを上げることができます。
    4. 以前のメッセージフォーマットが 0.10.0 の場合、log.message.format.version を 0.10.2 に変更します (メッセージ形式が 0.10.0, 0.10.1 と 0.10.2 で同じなため、これは操作不要です)。以前のメッセージフォーマットのバージョンが 0.10.0 より低い場合、まだ log.message.format.version を変更しないでください - このパラメータは全てのコンシューマが 0.10.0.0 以降に変更された後で変更されるべきです。
    5. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    6. もし log.message.format.version がこの時点でまだ 0.10.0 より低い場合は、全てのコンシューマが 0.10.0 以降にアップグレードするまで待ち、各ブローカー上で log.message.format.version を 0.10.2 に変更し、それらを1つずつ再起動します。

    注意: ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それら全てを開始します。それらはデフォルトで新しいプロトコルを使って開始するでしょう。

    注意: プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。

    0.10.1のKafkaストリームアプリケーションをアップグレード
    • ストリームアプリケーションの 0.10.1 から 0.10.2 へのアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 0.10.2 アプリケーションは 0.10.2 と 0.10.1 のブローカーにアクセスすることができます (しかし 0.10.0 ブローカーへ接続することはできません)。
    • コードを再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • TimestampExtractor インタフェースが変更されたため、独自の(つまりユーザ実装の)タイムスタンプ エクストラクタを使う場合は、このコードを更新する必要があるでしょう。
    • StreamsMetric インタフェースが変更されたため、独自のメトリクスを登録する場合、このコードを変更する必要があるでしょう。
    • 詳細は 0.10.2でのストリーム APIの変更 を見てください
    0.10.0のKafkaストリームアプリケーションをアップグレード
    • Kafkaストリーム 0.10.2 アプリケーションは 0.10.2 あるいは 0.10.1 ブローカーへのみ接続することができるため、ストリームアプリケーションの 0.10.0 から 0.10.2 へのアップグレードはブローカーのアップグレードを必要とします。
    • 2,3のAPIの変更があります。後方互換性はありません(参照詳細は0.10.2 でのストリーム APIの変更)。このように、コードを更新し再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • 0.10.0.xから0.10.2.2 への更新は、最初の更新フェーズについて設定upgrade.from="0.10.0"セットを伴う2回のローリング バウンスを必要とします (参照KIP-268)。別のやり方として、オフラインの更新も可能です。
      • ローリングバウンスのためのアプリケーションインスタンスを準備し、新しいバージョン 0.10.2.2 のために設定upgrade.from"0.10.0" に設定するようにしてください。
      • アプリケーションの各インスタンスを一度バウンスします
      • 2回目のローリングバウンスのために新しく配備された 0.10.2.2 アプリケーションインスタンスを準備します; 設定upgrade.modeのための値を削除するようにしてください
      • アップグレードを完了するためにもう一度各アプリケーションのインスタンスをバウンスします
    • 0.10.0.x から 0.10.2.0 あるいは 0.10.2.1 へのアップグレードはオフライン アップグレードを必要とします (ローリング バウンス アップグレードはサポートされません)
      • 全ての古い (0.10.0.x) アプリケーションのインスタンスを停止します
      • コードを更新し、古いコードとjarファイルを新しいコードと新しいjarファイルと交換します
      • 全ての新しい (0.10.2.0 , 0.10.2.1) アプリケーションのインスタンスを再起動します
    0.10.2.2 での主要な変更
    • バージョン 0.10.0.x からのローリング バウンス アップグレードが可能な新しい設定パラメータ upgrade.fromが追加されました
    0.10.2.1 での主要な変更
    • StreamConfigクラスの2つの設定のデフォルト値はKafkaストリームアプリケーションの resiliency を改善するために変更されました。内部的なKafkaストリームのプロデューサのretriesのデフォルト値は0から10に変更されました。内部的なKafkaストリームのコンシューマのmax.poll.interval.ms のデフォルト値は 300000 から Integer.MAX_VALUE に変更されました。
    0.10.2.0 での主要な変更
    • Javaクライアント(プロデューサとコンシューマ)は古いブローカーと通信することができるようになりました。バージョン 0.10.2 のクライアントはバージョン 0.10.0 あるいはそれより新しいブローカーと話すことができます。古いブローカーが使われた時に、幾つかの機能は利用不可あるいは制限されることに注意してください。
    • Javaコンシューマの幾つかのメソッドは、呼び出し中のスレッドが中断された時に今ではInterruptExceptionを投げます。この変更の掘り下げた説明については、KafkaConsumer Javadoc を参照してください。
    • Java コンシューマは今ではgracefullyにシャットダウンします。デフォルトでは、コンシューマは延期しているリクエストを完了するために30秒まで待ちます。タイムアウトを持つ新しいclose APIが最大待ち時間を制御するためにKafkaConsumerに追加されました。
    • --whitelist オプションを使って新しいJavaコンシューマを持つMirrorMakerへ、カンマで分割された複数の正規表現を渡すことができます。これにより古いScalaコンシューマが使われた時にMirrorMakerと一貫性を持つ挙動をします。
    • ストリームアプリケーションの 0.10.1 から 0.10.2 へのアップグレードはブローカーのアップグレードを必要としません。Kafka ストリーム 0.10.2 アプリケーションは 0.10.2 と 0.10.1 のブローカーにアクセスすることができます (しかし 0.10.0 ブローカーへ接続することはできません)。
    • Stream APIからZookeeperの依存が削除されました。ストリームAPIは内部的なトピックを管理するために今ではZookeeperを直接修正せずにKafkaプロトコルを使います。これによりZookeeperに直接アクセスする権限が必要無くなり、もうストリームのアプリケーションの中で "StreamsConfig.ZOOKEEPER_CONFIG" を設定する必要がありません。Kafkaクラスタが安全な場合、ストリームアプリケーションは新しいトピックを作成するためのセキュリティ権限を持つ必要があります。
    • "security.protocol", "connections.max.idle.ms", "retry.backoff.ms", "reconnect.backoff.ms" および "request.timeout.ms" を含む幾つかの新しいフィールドがStreamsConfig クラスに追加されました。ユーザはそれらのデフォルトの値に注意を払い、必要に応じて設定する必要があります。詳細については、3.5 Kafka ストリームの設定を参照してください。
    新しいプロトコルのバージョン
    • KIP-88: topics 配列が nullに設定された場合、OffsetFetchRequest v2 は全てのトピックについてのオフセットの扱いをサポートします。
    • KIP-88: OffsetFetchResponse v2 は トップレベルの error_code フィールドを導入します。
    • KIP-103: UpdateMetadataRequest v3 はend_points配列の要素への listener_name フィールドを導入します。
    • KIP-108: CreateTopicsRequest v1 はvalidate_onlyフィールドを導入します。
    • KIP-108: CreateTopicsResponse v1 はtopic_errors配列の要素へのerror_message フィールドを導入します。

    0.8.x, 0.9.x あるいは 0.10.0.X から 0.10.1.0 へのアップグレード

    0.10.1.0 にはwireプロトコルの変更があります。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中のダウンタイムが無いことを保証します。しかし、アップグレードする前に0.10.1.0 での潜在的な破壊的な変更に注意してください。
    注意: 新しいプロトコルが導入されたため、クライアントをアップグレードする前にKafkaクラスタをアップグレードすることが重要です (つまり、0.10.1.xクライアントは 0.10.1.x以降のブローカーをサポートし、一方で 0.10.1.x ブローカーも古いクライアントをサポートします)。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
    2. 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.1.0 に設定することでプロトコルのバージョンを上げることができます。
    4. 以前のメッセージフォーマットが 0.10.0 の場合、log.message.format.version を 0.10.1 に変更します (メッセージ形式が 0.10.0 と 0.10.1 で同じなため、これは操作不要です)。以前のメッセージフォーマットのバージョンが 0.10.0 より低い場合、まだ log.message.format.version を変更しないでください - このパラメータは全てのコンシューマが 0.10.0.0 以降に変更された後で変更されるべきです。
    5. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    6. もし log.message.format.version がこの時点でまだ 0.10.0 より低い場合は、全てのコンシューマが 0.10.0 以降にアップグレードするまで待ち、各ブローカー上で log.message.format.version を 0.10.1 に変更し、それらを1つずつ再起動します。

    注意: ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それら全てを開始します。それらはデフォルトで新しいプロトコルを使って開始するでしょう。

    注意: プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。

    0.10.1.0での破壊的な変更の可能性
    • ログの保持期間がもうログセグメントの最終更新時間に基づかなくなりました。その代わりにログセグメント内のメッセージの一番大きいタイムスタンプに基づくでしょう。
    • ログのrolling時間がもうログセグメントの生成時間に依存しなくなりました。その代わりに今ではメッセージ内のタイムスタンプに基づきます。もっと具体的に。セグメント内の最初のメッセージのタイムスタンプが T の時、新しいメッセージが T + log.roll.ms より大きいか等しいタイムスタンプを持つ時にログはロールアウトされるでしょう。
    • 0.10.0 のオープン ファイル ハンドラは各セグメントごとの追加の時間インデックスファイルのために ~33%だけ増加するでしょう。
    • 時間インデックスとオフセットインデックスは同じインデックスサイズ設定を共有します。それぞれの時間インデックスのエントリはオフセットのインデックスエントリのサイズの1.5x だからです。潜在的なログのローリングを避けるために、ユーザは log.index.size.max.bytes を増やす必要があるかもしれません。
    • 大きなログセグメント (例えば、>15K)を持つブローカーでは、インデックスファイル数の増加のために、ブローカーの起動時のログのロードプロセスが長くなるかもしれません。私たちの実験によると、num.recovery.threads.per.data.dir を1に設定するとログのロード時間が減るかもしれません。
    0.10.0のKafkaストリームアプリケーションをアップグレード
    • Kafkaストリーム 0.10.1 アプリケーションは 0.10.1 ブローカーへのみ接続することができるため、ストリームアプリケーションの 0.10.0 から 0.10.1 へのアップグレードはブローカーのアップグレードを必要としません。
    • 2,3のAPIの変更があります。後方互換性はありません(参照詳細は 0.10.1でのストリーム APIの変更 を見てくださいこのように、コードを更新し再コンパイルする必要があります。単にKafkaストリームライブラリの jar ファイルを入れ替えるだけでは動作せず、アプリケーションが壊れるでしょう。
    • 0.10.0.xから0.10.1.2 への更新は、最初の更新フェーズについて設定upgrade.from="0.10.0"セットを伴う2回のローリング バウンスを必要とします (参照KIP-268)。別のやり方として、オフラインの更新も可能です。
      • ローリングバウンスのためのアプリケーションインスタンスを準備し、新しいバージョン 0.10.1.2 のために設定upgrade.from"0.10.0" に設定するようにしてください。
      • アプリケーションの各インスタンスを一度バウンスします
      • 2回目のローリングバウンスのために新しく配備された 0.10.1.2 アプリケーションインスタンスを準備します; 設定upgrade.modeのための値を削除するようにしてください
      • アップグレードを完了するためにもう一度各アプリケーションのインスタンスをバウンスします
    • 0.10.0.x から 0.10.1.0 あるいは 0.10.1.1 へのアップグレードはオフライン アップグレードを必要とします (ローリング バウンス アップグレードはサポートされません)
      • 全ての古い (0.10.0.x) アプリケーションのインスタンスを停止します
      • コードを更新し、古いコードとjarファイルを新しいコードと新しいjarファイルと交換します
      • 全ての新しい (0.10.1.0 , 0.10.1.1) アプリケーションのインスタンスを再起動します
    0.10.1.0 での主要な変更
    • 新しいJavaコンシューマはもうベータではありません。全ての新しい開発でそれをお勧めします。古いScalaコンシューマはまだサポートされますが、それらは次のリリースで非推奨になり、将来の大きなリリースで削除されるでしょう。
    • --new-consumer/--new.consumer スイッチはもうMirrorMakerのようなツールと新しいコンシューマを使うコンソール コンシューマを使う必要はありません; one simply needs to pass a Kafka broker to connect to instead of the ZooKeeper ensemble. 更に、古いコンシューマを持つコンソール コンシューマの使用は非推奨になり、将来の大きなリリースで削除されるでしょう。
    • Kafka クラスタは今ではクラスタidによって一意に識別することができます。それはブローカーが 0.10.1.0 にアップグレードされる時に自動的に生成されます。クラスタidは kafka.server:type=KafkaServer,name=ClusterId メトリックを使って利用可能で、メタデータの応答の一部です。シリアライザ、クライアント インタセプタ およびメトリック レポータは ClusterResourceListener インタフェースを実装することでクラスタidを受け取ることができます。
    • BrokerState "RunningAsController" (value 4) が削除されました。バグにより、ブローカーはそれから遷移する前にほんの少しだけこの状態になるでしょう。従って削除の影響は最小限に違いありません。指定されたブローカーがコントローラかどうかを検知するお勧めの方法は、kafka.controller:type=KafkaController,name=ActiveControllerCount メトリックを使うことです。
    • 新しいJavaコンシューマにより今ではユーザはパーティション上のタイムスタンプを使ってオフセットを検索することができます。
    • 今では新しいJavaコンシューマはバックグランドのスレッドからのハートビートをサポートします。コンシューマがグループから積極的に離れる前のpollの起動間の最大時間を制御する新しい設定max.poll.interval.msがあります (デフォルトでは5分です)。設定 request.timeout.ms の値は常に max.poll.interval.ms より大きくなければなりません。なぜなら、これはコンシューマがリバランスする間に JoinGroup リクエストがサーバ上でブロックすることができる最大時間だからです。そのためそのデフォルトの値をちょうど5分を超えるように変更しました。結果的に、session.timeout.ms のデフォルト値は10秒に調整され、max.poll.records のデフォルト値は 500 に変更されました。
    • Authorizer を使用し、ユーザがトピック上に Describe authorization を持たない場合、ブローカーはトピック名を取り零すため、ブローカーはもうTOPIC_AUTHORIZATION_FAILED エラーを返さないでしょう。代わりに、UNKNOWN_TOPIC_OR_PARTITION エラーコードが返されるでしょう。Kafkaクライアントは一般的に自動的に不明なトピックエラーを再試行するため、プロデューサとコンシューマを使う時にこれは予期しないタイムアウトあるいは遅延を起こすかもしれません。これが起きたかも知れないと疑う場合は、クライアントログを調査すべきです。
    • 取得応答はデフォルトでサイズの制限があります (コンシューマについては 50MB、リプリケーションについては 10MB)。既存のパーティションあたりの制限も適用されます (コンシューマとリプリケーションについて 1MB)。次の項目で説明されるようにこれらの制限のどちらも絶対的な最大ではないことに注意してください。
    • 応答/パーティションサイズの制限より大きいメッセージが見つかった場合は、コンシューマとレプリカは先に進むかもしれません。もっと具体的には、もし取得の最初の空では無いパーティション内の最初のメッセージがどちらかあるいは両方の制限より大きい場合、メッセージはまだ返されるでしょう。
    • 呼び出し元がパーティションの順番を指定できるように、上書きされたコンストラクタがkafka.api.FetchRequestkafka.javaapi.FetchRequest に追加されました (v3では順番が重要なため)。以前の既存のコンストラクタは非推奨で、枯渇問題を避けるためにリクエストが送信される前にパーティションがシャッフルされます。
    新しいプロトコルのバージョン
    • ListOffsetRequest v1 はタイムスタンプに基づいた正確なオフセットの検索をサポートします。
    • MetadataResponse v2 は新しいフィールドを導入します: "cluster_id".
    • FetchRequest v3 は(既存のパーティションごとの制限に加えて)応答サイズの制限をサポートします。もし進める必要があり、リクエスト内のパーティションの順番が重要であれば、制限より大きいメッセージを返します。
    • JoinGroup v1 は新しいフィールドを導入します: "rebalance_timeout"。

    0.8.x あるいは 0.9.x から 0.10.0.0 へのアップグレード

    0.10.0.0 は 潜在的に破壊的な変更 (アップグレードする前に再調査してください)があり、アップグレードに伴うパフォーマンスの問題があるかもしれません。以下で推奨されるrollingアップグレード計画に従うことで、アップグレード中およびそれに伴うダウンタイムとパフォーマンスの問題が無いことを保証します。
    注意: 新しいプロトコルが導入されたため、クライアントをアップグレードする前にKafkaクラスタをアップグレードすることが重要です。

    バージョン 0.9.0.0 のクライアントの注意: 0.9.0.0 で導入されたバグにより、ZooKeeperに依存するクライアント (古いScalaのハイレベルのコンシューマとMirrorMakerが古いコンシューマと一緒に使われた場合)は 0.10.0.x のブローカーと連携しないでしょう。従って 0.9.0.0 クライアントはブローカーが 0.10.0.x にアップグレードされる前に 0.9.0.1 にアップグレードされる必要があります。このステップは、0.8.X あるいは 0.9.0.1 クライアントの場合には必要ありません。

    ローリングアップグレードに関して:

    1. 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
    2. ブローカーのアップグレード。単純にブローカーをダウンし、コードを更新し、再起動することで一度に行うことができます。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.0.0 に設定することでプロトコルのバージョンを上げることができます。注意: まだ log.message.format.version に触れるべきではありません - このパラメータはいったん全てのコンシューマが 0.10.0.0 にアップグレードされてからのみ変更されるべきです。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
    5. 一度全てのコンシューマが 0.10.0 にアップグレードされると、各ブローカー上で log.message.format.version を 0.11.0 に変更し、それらを1つずつ再起動します。

    注意: ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それら全てを開始します。それらはデフォルトで新しいプロトコルを使って開始するでしょう。

    注意: プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。

    0.10.0.0 へのアップグレードに伴いパフォーマンスの影響の可能性があります。

    0.10.0 でのメッセージフォーマットは新しいタイムスタンプのフィールドを含み、圧縮されたメッセージのための相対的なオフセットを使います。ディスク上のメッセージフォーマットは server.properties ファイル内の log.message.format.version を使って設定することができます。デフォルトのディスク上のメッセージフォーマットは 0.10.0 です。0.10.0.0より前のコンシューマクライアントがいる場合は、0.10.0より前のメッセージフォーマットのみを理解します。この場合、ブローカーは古いバージョン上のコンシューマへメッセージを送信する前に、メッセージを0.10.0のフォーマットから以前のフォーマットに変換することができます。しかし、ブローカーはこの場合 ゼロコピー転送を使うことができません。パフォーマンス問題についてのKafkaコミュニティからの報告ではCPUの利用率がアップグレードの後で以前の20%から100%になることを示しています。これはパフォーマンスを通常に戻すために全てのクライアントの即座のアップグレードを強制します。コンシューマが0.10.0.0にアップグレードされる前にそのようなメッセージの変換を避けるために、ブローカーを0.10.0.0にアップグレードする時にlog.message.format.versionを0.8.0あるいは0.9.0に設定することができます。このようにブローカーはデータを古いコンシューマに送信するためにまだzero-copyを使うことができます。コンシューマがアップグレードされると、ブローカー上でメッセージフォーマットを0.10.0に変更し、新しいタイムスタンプと改善された圧縮を含む新しいメッセージ形式を楽しむことができます。互換性を保証するために変換がサポートされ、まだ新しいクライアントに更新されていない2,3のアプリケーションをサポートするのに便利かもしれませんが、過剰なクラスタ上でさえ全てのコンシューマの通信量をサポートすることは現実性がありません。従って、ブローカーがアップグレードされたがクライアントの大半がまだの場合は、できるだけメッセージの変換を避けることが重要です。

    0.10.0.0にアップグレードされたクライアントについては、パフォーマンスの影響はありません。

    注意: メッセージフォーマットのバージョンを設定することで、既存の全てのメッセージはそのメッセージフォーマットのバージョン以下であると保証します。そうでなければ、0.10.0.0より前のコンシューマが壊れるかも知れません。特に、メッセージフォーマットが0.10.0に設定された後で、0.10.0.0より前のバージョンのコンシューマを壊すかも知れないので以前のフォーマットに戻す変更をするべきではありません。

    注意: 各メッセージ内に導入された追加のタイムスタンプによって、小さなメッセージを送信しているプロデューサはオーバーヘッドの増加によりメッセージのスループットの減少を経験するかもしれません。さらに、リプリケーションは今度はメッセージごとに追加の8バイトを転送します。もしクラスタのネットワーク許容量すれすれで実行している場合は、ネットワークカードを圧倒し過負荷による障害とパフォーマンスの問題に遭遇するでしょう。

    注意: もしプロデューサ上で圧縮を有効にすると、場合によってはプロデューサのスループットの減少とブローカー上の圧縮レートの低下に気づくかもしれません。圧縮されたメッセージを受け取る場合、0.10.0ブローカーはメッセージの圧縮を避けます。この事は一般的にレイテンシーを下げ、スループットを改善します。しかし、特定の場合において、これはプロデューサ上のバッチのサイズを削減するかも知れません。このことはスループットの改悪につながるかも知れません。これが起きた場合は、ユーザはより良いスループットのためにプロデューサのlinger.msとbatch.sizeを調整することができます。さらに、snappyを使ってメッセージを圧縮するために使われるプロデューサのバッファは、ブローカーによって使われるものよりも小さくなります。これはディスク上のメッセージの圧縮レートへの負の衝撃を持つかも知れません。将来のKafkaリリースではこれを設定可能にするつもりです。

    0.10.0.0での破壊的な変更の可能性
    • Kafka 0.10.0.0から、KafkaでのメッセージフォーマットのバージョンはKafkaのバージョンとして表されています。例えば、メッセージフォーマット 0.9.0 はKafka 0.9.0 によってサポートされるもっとも高いメッセージのバージョンを参照します。
    • メッセージフォーマット 0.10.0 が導入され、デフォルトで使われています。メッセージ内にタイムスタンプのフィールドが含まれ、圧縮されたメッセージのために相対的なオフセットが使われます。
    • ProduceRequest/Response v2 が導入され、デフォルトでメッセージフォーマット 0.10.0 をサポートするために使われます。
    • FetchRequest/Response v2 が導入され、デフォルトでメッセージフォーマット 0.10.0 をサポートするために使われます。
    • MessageFormatter インタフェースがdef writeTo(key: Array[Byte], value: Array[Byte], output: PrintStream) から def writeTo(consumerRecord: ConsumerRecord[Array[Byte], Array[Byte]], output: PrintStream)に変更されました。
    • MessageReader インタフェースがdef readMessage(): KeyedMessage[Array[Byte], Array[Byte]] から def readMessage(): ProducerRecord[Array[Byte], Array[Byte]]に変更されました。
    • MessageFormatter のパッケージはkafka.tools からkafka.commonに変更されました。
    • MessageReaderのパッケージがkafka.tools からkafka.commonに変更されました。
    • handle(record: MessageAndMetadata[Array[Byte], Array[Byte]])は呼ばれないため、MirrorMakerMessageHandler はもうそれを公開しません。
    • 0.7 KafkaMigrationTool はもうKafkaと一緒にパッケージされません。0.7 から 0.10.0 に移設する場合は、最初に 0.8 に移設し、それから説明されるアップグレード手順に従って 0.8 から 0.10.0 にアップグレードしてください。
    • 新しいコンシューマはAPIをメソッドパラメータのための型の連続としてjava.util.Collectionを受け付けるように標準化しました。既存のコードは0.10.0クライアントライブラリと連携するように更新しなければならないかも知れません。
    • LZ4-compressed メッセージ処理は共同利用できる構成仕様(LZ4f v1.5.1)を使うように変更されました。古いクライアントと互換性を維持するために、この変更はメッセージフォーマット 0.10.0 以降にのみ適用されます。v0/v1 (メッセージフォーマット 0.9.0)を使って LZ4-compressed メッセージを生成/取得するクライアントは、0.9.0 の構成実装を使い続ける必要があります。プロトコル v2 以降を生成/取得するクライアントは、共同利用できる LZ4f 構成を使う必要があります。共同利用できる LZ4 ライブラリのリストは http://www.lz4.org/ で利用可能です。
    0.10.0.0 での主要な変更
    • Kafka 0.10.0.0 から、Kafka Streamsという名前の新しいクライアントライブラリがKafkaトピックの中で格納されるデータ上でストリーミング処理をするために利用可能です。この新しいクライアントライブラリは上で述べたメッセージフォーマットの変更のために0.10.x以上のバージョンのブローカーとのみ連携します。詳しい情報はストリーム ドキュメントを読んでください。
    • 設定パラメータreceive.buffer.bytes のデフォルト値は、新しいコンシューマのために今では 64K です。
    • 新しいコンシューマは内部トピックが正規表現の申し込み内で偶然含まれることを避けるために新しいパラメータ exclude.internal.topics を公開します。デフォルトで有効です。
    • 古いScalaプロデューサは非推奨になりました。ユーザはそれらのコードをできる限りKafka-client JARの中に含まれるJavaプロデューサに移設するべきです。
    • 新しいコンシューマAPIは安定版として印が付けられました。

    0.8.0, 0.8.1.X あるいは 0.8.2.X から 0.9.0.0 へのアップグレード

    0.9.0.0 は破壊的な変更の可能性 (アップグレードする前に精査してください)があり、以前のバージョンからのブローカー間のプロトコルの変更があります。このことはアップグレードされたブローカーとクライアントは古いバージョンと互換性が無いかも知れないことを意味します。クライアントをアップグレードする前にKafkaクラスタをアップグレードすることが重要です。MirrorMaker ダウンストリームを使っている場合は、クラスタも同様に最初にアップグレードされるべきです。

    ローリングアップグレードに関して:

    1. 全てのブローカー上の server.properties ファイルを更新し、以下のプロパティを追加します : inter.broker.protocol.version=0.8.2.X
    2. ブローカーのアップグレード。単純にブローカーをダウンし、コードを更新し、再起動することで一度に行うことができます。
    3. クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.9.0.0 に設定することでプロトコルのバージョンを上げることができます。
    4. 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。

    注意: ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それら全てを開始します。それらはデフォルトで新しいプロトコルを使って開始するでしょう。

    注意: プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。

    0.9.0.0での破壊的な変更の可能性
    • Java 1.6 はもうサポートされません。
    • Scala 2.9 はもうサポートされません。
    • 1000以上のブローカー ID はデフォルトで自動的にブローカーIDに割り当てられるように予約されています。その閾値より大きな既存のブローカーIDを持つクラスタの場合、reserved.broker.max.id ブローカー設定プロパティを適宜増加するようにしてください。
    • 設定パラメータ replica.lag.max.messages は削除されました。パーティション リーダーはどのレプリカを同期するかを決める時に遅れたメッセージの数をもう考慮しません。
    • 設定パラメータ replica.lag.time.max.ms はレプリカからの最後の取得リクエストからの経過時間を参照するだけでなく、レプリカが最後に追いついてからの時間も参照します。リーダーからメッセージを取得しているが replica.lag.time.max.ms 内の最新のメッセージに追いついていないレプリカは同期していないと見なされるでしょう。
    • コンパクト化されたトピックはキー無しのメッセージをもう受け付けず、それが試みられた場合はプロデューサによって例外が投げられます。0.8.xでは、キーを持たないメッセージはコンパクションスレッドが結果的に文句を言い終了(そして全てのコンパクト化されたトピックのコンパクト化を停止)するでしょう。
    • MirrorMaker は複数のターゲットクラスタをもうサポートしません。結果として、1つの --consumer.config パラメータのみを受け付けるでしょう。複数のソースクラスタをミラーするためには、ソースクラスタあたり少なくとも1つのMirrorMakerを必要とするでしょう。それぞれは独自のコンシューマ設定を持ちます。
    • org.apache.kafka.clients.tools.*の下にパッケージ化されたツールはorg.apache.kafka.tools.*に移動されました。含まれていた全てのスクリプトはまだ通常通り動作し、これらのクラスを直接インポートしている独自のコードのみ影響を受けるでしょう。
    • デフォルトのKafka JVMパフォーマンス オプション (KAFKA_JVM_PERFORMANCE_OPTS) は kafka-run-class.sh の中で変更されました。
    • kafka-topics.sh スクリプト (kafka.admin.TopicCommand) は、今は障害時に非ゼロの終了コードで終了します。
    • kafka-topics.sh スクリプト (kafka.admin.TopicCommand) は今ではトピック名の '.' あるいは '_' 使用によってトピック名がメトリックの衝突を起こす危険がある時に警告を出力し、実際の衝突の場合にはエラーを出力するでしょう。
    • kafka-console-producer.sh スクリプト (kafka.tools.ConsoleProducer) は古いScalaプロデューサをデフォルトとする代わりにJavaプロデューサを使うでしょう。ユーザは古いプロデューサを使うためには 'old-producer' を指定する必要があります。
    • デフォルトで全てのコマンドラインツールは全てのログメッセージをstdoutの代わりにstderrに出力するでしょう。
    0.9.0.1 での主要な変更
    • 新しいブローカーidの生成機能は broker.id.generation.enable を false に設定することで無効にすることができます。
    • 設定パラメータ log.cleaner.enable は今はデフォルトでtrueです。このことは cleanup.policy=compact のトピックが今ではデフォルトで圧縮されず、ヒープの128 MBが log.cleaner.dedupe.buffer.size を使ってクリナープロセスに割り当てられるだろうことを意味します。log.cleaner.dedupe.buffer.size と他の log.cleaner 設定値を圧縮されたトピックの使用に基づいて再調査したいかもしれません。
    • 新しいコンシューマのための 設定パラメータ fetch.min.bytes は今ではデフォルトで 1です。
    0.9.0.0 での非推奨
    • kafka-topics.sh スクリプト (kafka.admin.TopicCommand) からのトピックの設定の変更は非推奨になりました。進めるには、この機能のために kafka-configs.sh スクリプト (kafka.admin.ConfigCommand) を使ってください。
    • kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) は非推奨になりました。進めるには、この機能のために kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) を使ってください。
    • kafka.tools.ProducerPerformance クラスは非推奨になりました。進めるには、この機能のために org.apache.kafka.tools.ProducerPerformance を使ってください (kafka-producer-perf-test.sh も新しいクラスを使うように変更されるでしょう)。
    • プロデューサ設定 block.on.buffer.full は非推奨になり、将来のリリースでは削除されるでしょう。現在のところ、デフォルト値はfalseに変更されました。KafkaProducer はもう BufferExhaustedException を投げないでしょうが、代わりにブロックするために max.block.ms 値を使うでしょう。それは後で TimeoutException を投げます。block.on.buffer.full プロパティが明示的に true に設定された場合、max.block.ms が Long.MAX_VALUE に設定され、metadata.fetch.timeout.ms は設定されないでしょう。

    0.8.1 から 0.8.2 へのアップグレード

    0.8.2 は 0.8.1 と完全に互換性があります。単純に1つのブローカーをダウンし、コードを更新し、再起動することで一度にアップグレードを行うことができます。

    0.8.0 から 0.8.1 へのアップグレード

    0.8.1 は 0.8 と完全に互換性があります。単純に1つのブローカーをダウンし、コードを更新し、再起動することで一度にアップグレードを行うことができます。

    0.7からのアップグレード

    リリース 0.7 は新しいリリースと互換性がありません。主要な変更はAPI, ZooKeeper データ構造およびプロトコルに行われ、リプリケーションを追加するために設定に行われました (これは 0.7で無くなりました)。0.7から最新のバージョンへのアップグレードは移行のために 特別なツール を必要とします。この移行はダウンタイム無しで行うことができます。

    2. APIs

    APIを使ってアプリケーションはデータのストリームをKafkaクラスタのトピックに送信することができます。
  • Consumer API を使ってアプリケーションはKafkaクラスタ内のトピックからデータのストリームを読み込むことができます。
  • Streams API は入力トピックから出力トピックへのデータのストリームを変換することができます。
  • Connect APIは、頻繁になんらかのソースシステムあるいはアプリケーションからKafkaへpull、もしくはKafkaから何らかのシンクシステムあるいはアプリケーションへpushするコネクタの実装ができます。
  • AdminClient API を使ってトピック、ブローカーと他のKafkaオブジェクトを管理および調査することができます。
  • Kafka は多くのプログラミング言語で利用可能なクライアントを持つ言語に依存しないプロトコル越しにその全ての機能を公開します。しかしJavaクライアントだけはメインのKafkaプロジェクトとして整備されます。そのほかは独立したオープンソースプロジェクトとして利用可能です。非Javaクライアントのリストはここで利用可能です。

    2.1プロデューサ API

    プロデューサ API によってアプリケーションはKafkaクラスタ内のトピックからデータのストリームを送信することができます。

    プロデューサをどう使うかを示す例がjavadocsにあります。

    プロデューサを使うために、以下のmaven依存を使うことができます:

    		<dependency>
    			<groupId>org.apache.kafka</groupId>
    			<artifactId>kafka-clients</artifactId>
    			<version>{{fullDotVersion}}</version>
    		</dependency>
    	

    2.2コンシューマ API

    Consumer API によってアプリケーションはKafkaクラスタ内のトピックからデータのストリームを読み込むことができます。

    コンシューマをどう使うかを示す例がjavadocsにあります。

    コンシューマを使うために、以下のmaven依存を使うことができます:

    		<dependency>
    			<groupId>org.apache.kafka</groupId>
    			<artifactId>kafka-clients</artifactId>
    			<version>{{fullDotVersion}}</version>
    		</dependency>
    	

    2.3ストリーム API

    Streams API は入力トピックから出力トピックへのデータのストリームを変換することができます。

    このライブラリをどう使うかを示す例がjavadocsにあります。

    ストリームAPIを使う時の追加のドキュメントがここで利用可能です。

    Kafkaストリームを使うために、以下のmaven依存を使うことができます:

    		<dependency>
    			<groupId>org.apache.kafka</groupId>
    			<artifactId>kafka-streams</artifactId>
    			<version>{{fullDotVersion}}</version>
    		</dependency>
    	

    Scalaを使う場合、任意でkafka-streams-scala ライブラリをインクルードすることができます。ScalaのためのKafkaストリームDSLを使うための追加のドキュメントが開発者ガイドで利用可能です。

    Scala 2.11についての ScalaのためのKafkaストリームDSLを使うために、以下のmaven依存を使うことができます:

    		<dependency>
    			<groupId>org.apache.kafka</groupId>
    			<artifactId>kafka-streams-scala_2.11</artifactId>
    			<version>{{fullDotVersion}}</version>
    		</dependency>
    	

    2.4接続 API

    Connect APIは、頻繁になんらかのソースデータシステムからKafkaへpull、もしくはKafkaから何らかのシンクデータシステムへpushするコネクタの実装ができます。

    Connectの多くのユーザこのAPIを直接使う必要は無いでしょうが、それらはコードを書く必要なく組み込みのコネクタを使うことができます。Connectを使う時の更なる情報はここで利用可能です。

    独自のコネクタを実装したい人はjavadocを見ることができます。

    2.5 AdminClient API

    AdminClient API はトピック、ブローカー、acl と他のKafkaオブジェクトを管理および調査することができます。

    AdminClient API を使うには、以下のMaven依存性を追加します:

    		<dependency>
    			<groupId>org.apache.kafka</groupId>
    			<artifactId>kafka-clients</artifactId>
    			<version>{{fullDotVersion}}</version>
    		</dependency>
    	
    AdminClient APIについての詳細は、javadocを見てください。

    2.6レガシー API

    より制限されたレガシーのプロデューサとコンシューマ api もKafkaに含まれています。これらの古いScala APIは非推奨で、互換性の目的のためにまだ利用可能です。それらの情報はここで見つけることができます。

    3. 設定

    設定。これらの値はファイルまたはプログラムのどちらかで提供することができます。

    3.1ブロッカーの設定

    重要な設定は以下の通りです:
    • broker.id
    • log.dirs
    • zookeeper.connect
    トピックレベルの設定とデフォルトは以下でもっと詳細に議論されます。
    名前 説明 種類 デフォルト 有効な値 重要性 動的更新モード
    zookeeper.connectZookeeper ホスト文字列文字列highread-only
    advertised.host.name非推奨: `advertised.listeners` または `listeners` が設定されていない場合にのみ使われます。代わりに `advertised.listeners`を使ってください。クライアントが使うためにZooKeeperに公開されるホスト名。IaaS 環境では、これはブローカーがバインドするインタフェースとは異なる必要があるかも知れません。これが設定されない場合、設定されていれば`host.name` の値が使われるでしょう。そうでなければ、java.net.InetAddress.getCanonicalHostName() から返される値を使うでしょう。文字列nullhighread-only
    advertised.listeners`リスナー`設定プロパティと異なる場合、クライアントが使用するZooKeeperに公開されるリスナー。IaaS 環境では、これはブローカーがバインドするインタフェースとは異なる必要があるかも知れません。これが設定されない場合は、`listeners`の値が使われるでしょう。`listeners` と異なり、それは 0.0.0.0 メタ-アドレスを通知するのは正しくありません。文字列nullhighper-broker
    advertised.port非推奨: `advertised.listeners` または `listeners` が設定されていない場合にのみ使われます。代わりに `advertised.listeners`を使ってください。クライアントが使用するZooKeeperへ公開されるポート。IaaS 環境では、これはブローカーがバインドするポートとは異なる必要があるかも知れません。設定されない場合は、ブローカーがバインドする同じポートを公開するでしょう。intnullhighread-only
    auto.create.topics.enableサーバ上でのトピックの自動生成を有効booleantruehighread-only
    auto.leader.rebalance.enable自動リーダーバランシングを有効にする。通常の間隔でもし必要であれば、バックグランドスレッドはリーダーのバランスをチェックし起動します。booleantruehighread-only
    background.threads様々なバックグラウンド処理タスクが使うスレッドの数int10[1,...]highcluster-wide
    broker.idこのサーバのためのブローカーid。設定しない場合はユニークなブローカーidが生成されるでしょう。zookeeperが生成したブローカーidとユーザ定義のブローカーidが衝突することを避けるために、生成されるブローカーidは reserved.broker.max.id + 1 から始まります。int-1highread-only
    compression.type指定されたトピックのための最終的な圧縮タイプを指定する。この設定は標準的な圧縮コーディック('gzip', 'snappy', 'lz4')を受け付けます。更に、非圧縮に相当する 'uncompressed'; プロデューサによって設定された元の圧縮コーディックを保持することを意味する'producer' を受け付けます。文字列producerhighcluster-wide
    delete.topic.enableトピックの削除を有効にする。この設定が切られている場合は管理ツールを使ったトピックの削除は何も効果が無いでしょう。booleantruehighread-only
    host.name非推奨: `listeners` が設定されていない場合にのみ使われます。代わりに `listeners` を使ってください。ブローカーのホスト名。これが設定されている場合は、このアドレスへのみバインドするでしょう。これが設定されていない場合は、全てのインタフェースにバインドするでしょう。文字列""highread-only
    leader.imbalance.check.interval.secondsコントローラによって起動されるパーティションのリバランスの調査の頻度long300highread-only
    leader.imbalance.per.broker.percentageブローカーあたりに許可されるリーダーの非バランスの割合。ブローカー毎にこの値を超えた場合は、コントローラーはリーダーのバランスを開始するでしょう。値はパーセンテージで指定されます。int10highread-only
    リスナーリスナーのリスト - listenするURIのカンマ区切りのリストとリスナー名。リスナー名が安全なプロトコルでは無い場合、listener.security.protocol.map も設定されるべきです。全てのインタフェースにバインドするためには 0.0.0.0 としてホスト名を指定してください。デフォルトのインタフェースにバインドするには、ホスト名を空にします。一般的なリスナーのリストの例: PLAINTEXT://myhost:9092,SSL://:9091 CLIENT://0.0.0.0:9092,REPLICATION://localhost:9093 文字列nullhighper-broker
    log.dirログデータが保持されるディレクトリ (log.dirs プロパティの補足)文字列/tmp/kafka-logshighread-only
    log.dirsログデータが保持されるディレクトリ。設定しない場合は、log.dirの値が使われます文字列nullhighread-only
    log.flush.interval.messagesメッセージがディスクにフラッシュされる前にログパーティション上で集約されるメッセージの数 long9223372036854775807[1,...]highcluster-wide
    log.flush.interval.msメモリ内に保持されたメッセージがディスクにフラッシュされるまでの最大ms。設定されていない場合は、log.flush.scheduler.interval.ms の値が使われます。longnullhighcluster-wide
    log.flush.offset.checkpoint.interval.msログの回復ポイントとして振舞う最後のフラッシュの永続レコードを更新する頻度int60000[0,...]highread-only
    log.flush.scheduler.interval.msログがディスクにフラッシュされる必要があるかどうかをログのフラッシャーがチェックする頻度long9223372036854775807highread-only
    log.flush.start.offset.checkpoint.interval.msログの開始オフセットの永続レコードを更新する頻度int60000[0,...]highread-only
    log.retention.bytesログが削除されるまでの最大サイズ。long-1highcluster-wide
    log.retention.hoursログを削除するまで保持する時間の数(時間単位)、log.retention.ms プロパティの3つめのパラメータint168highread-only
    log.retention.minutesログを削除するまで保持する分の数(分単位)、log.retention.ms プロパティの2つめのパラメータ設定しない場合は、log.retention.hours の値が使われます。intnullhighread-only
    log.retention.msログファイルが削除されるまでに保持されるミリ秒数。設定されない場合は、log.retention.minutes の値が使われます。longnullhighcluster-wide
    log.roll.hours新しいログのセグメントがロールアウトされるまでの最大時間(時間単位)、log.roll.ms プロパティの2つ目のパラメータint168[1,...]highread-only
    log.roll.jitter.hourslogRollTimeMillis から差し引く最大のジッター (時間単位)、log.roll.jitter.ms プロパティの2つ目のパラメータint0[0,...]highread-only
    log.roll.jitter.mslogRollTimeMillis から差し引く最大のジッター (ミリ秒)。設定しない場合は、log.roll.jitter.hours の値が使われますlongnullhighcluster-wide
    log.roll.ms新しいログの断片がロールアウトされるまでの最大時間(ミリ秒)。設定しない場合は、log.roll.hours の値が使われますlongnullhighcluster-wide
    log.segment.bytes1つのログファイルの最大サイズint1073741824[14,...]highcluster-wide
    log.segment.delete.delay.msファイルシステムからファイルを削除するまでの総待ち時間long60000[0,...]highcluster-wide
    message.max.bytes

    Kafkaで可能な最も大きなレコードのバッチサイズ。これが増え、0.10.2より古いコンシューマがある場合、コンシューマがこの大きさのレコードバッチを取得できるようにコンシューマの取得サイズも増やす必要があります。

    最新のメッセージフォーマットのバージョンでは、効率化のためにレコードは常にバッチにグループ化されます。以前のメッセージフォーマットのバージョンでは、圧縮されていないレコードはバッチにグループ化されず、この制限は1つのレコードにのみ適用されます。

    トピックごとにトピックレベルの max.message.bytes 設定を使って設定することができます。

    int1000012[0,...]highcluster-wide
    min.insync.replicasプロデューサがackを "all" (あるいは "-1") に設定する場合、min.insync.replicasは書き込みが成功したと見なされるように書き込みを知らせる必要があるレプリカの最小数を指定します。この最小限に一致しない場合、プロデューサは例外(NotEnoughReplicas あるいは NotEnoughReplicasAfterAppendのどちらか)を上げるでしょう。
    一緒に使った場合、min.insync.replicas と acks は素晴らしい耐久性の保証を強化することができます。典型的なシナリオは、3つのレプリケーション ファクターを持つトピックを生成し、min.insync.replicas を 2 に設定し、"all" のackを使って生成します。これは、もしレプリカの過半数が書き込みを受け取らなかった場合にプロデューサが例外を上げることを保証するでしょう。
    int1[1,...]highcluster-wide
    num.io.threadsサーバがリクエストの処理のために使用するスレッド数。ディスク I/Oが含まれるかもしれません。int8[1,...]highcluster-wide
    num.network.threadsサーバがネットワークからリクエストを受け取り、応答をネットワークに送信するために使われるスレッドの数。int3[1,...]highcluster-wide
    num.recovery.threads.per.data.dir起動時のログの回復とシャットダウン時にフラッシュするために使われるデータディレクトリあたりのスレッドの数。int1[1,...]highcluster-wide
    num.replica.alter.log.dirs.threadsレプリカをログディレクトリ間で移動できるスレッド数。ディスク I/Oが含まれるかもしれません。intnullhighread-only
    num.replica.fetchersソースブローカーからメッセージをリプリケートするために使われるフェッチスレッドの数。この値を増加することで追随するブローカーのI/O並行度の度合いを増やすことができます。int1highcluster-wide
    offset.metadata.max.bytesオフセット コミットに関連するメタデータ エントリのための最大サイズ。int4096highread-only
    offsets.commit.required.acksコミットが受け付けられるまでに必要とされるack。通常はデフォルト(-1)を上書くべきではありませんshort-1highread-only
    offsets.commit.timeout.msオフセット トピックのための全てのレプリカがコミットを受け取るか、このタイムアウトに達するまで、オフセットコミットは遅延するでしょう。これはプロデューサのリクエストタイムアウトに似ています。int5000[1,...]highread-only
    offsets.load.buffer.sizeオフセットをキャッシュにロードする時にオフセット セグメントから読み込むためのバッチサイズ。int5242880[1,...]highread-only
    offsets.retention.check.interval.msstale オフセットをチェックする頻度long600000[1,...]highread-only
    offsets.retention.minutesこの保持期間より古いオフセットは捨てられるでしょう。int10080[1,...]highread-only
    offsets.topic.compression.codecオフセットトピックのための圧縮コーディック - 圧縮は "atomic" コミットを実現するために使われるかも知れませんint0highread-only
    offsets.topic.num.partitionsオフセット コミット トピックのためのパーティション数 (配備の後で変更すべきではありません)int50[1,...]highread-only
    offsets.topic.replication.factorオフセット トピックのためのリプリケーション要素 (可用性を保証するするために高く設定します)。クラスタのサイズがこのリプリケーション要素の要請に合うまで、内部的な自動トピックの生成は失敗するでしょう。short3[1,...]highread-only
    offsets.topic.segment.bytesログの圧縮とキャッシュのロードを速くし易いように、オフセットトピックのセグメントのバイトは比較的小さくすべきです。int104857600[1,...]highread-only
    port非推奨: `listeners` が設定されていない場合にのみ使われます。代わりに `listeners` を使ってください。接続をlistenし、そして受け付けるポートint9092highread-only
    queued.max.requestsネットワークスレッドをブロックするまでに許容されるリクエストのキューの数int500[1,...]highread-only
    quota.consumer.default非推奨: 動的なデフォルトのクォートがZookeeprのためにあるいは その中で設定されていない時のみ使われます。クライアントid/コンシューマグループによって区別される全てのコンシューマは、秒間あたりのこの値より多くのバイトを取得する場合に絞られるでしょう。long9223372036854775807[1,...]highread-only
    quota.producer.default非推奨: 動的なデフォルトのクォートがZookeeprのためにあるいは その中で設定されていない時のみ使われます。クライアントid/コンシューマグループによって区別される全てのプロデューサは、秒間あたりのこの値より多くのバイトを生成する場合に絞られるでしょう。long9223372036854775807[1,...]highread-only
    replica.fetch.min.bytes各フェッチ応答に期待される最小バイト。十分なバイト数でなければ、replicaMaxWaitTimeMs まで待機しますint1highread-only
    replica.fetch.wait.max.ms随行するレプリカによって発行された各フェッチリクエストの最大待ち時間。この値は低いスループットのトピックについてISRの縮小を避けるために常にreplica.lag.time.max.ms より少ない必要があります。int500highread-only
    replica.high.watermark.checkpoint.interval.ms高いウォーターマークがディスクに保存される頻度long5000highread-only
    replica.lag.time.max.msもしフォロワーが何も取得リクエストを送信していないか、少なくともこの時までリーダーログの終了オフセットまで消費をしていない場合、リーダーはisrからフォロワーを削除するでしょう。long10000highread-only
    replica.socket.receive.buffer.bytesネットワークリクエストのためのソケット受信バッファint65536highread-only
    replica.socket.timeout.msネットワークリクエストのためのソケットタイムアウト。値は少なくとも replica.fetch.wait.max.ms でなければなりません。int30000highread-only
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。int30000highread-only
    socket.receive.buffer.bytesソケットサーバのソケットの SO_RCVBUF バッファ値が -1 であれば、OSのデフォルトが使われるでしょう。int102400highread-only
    socket.request.max.bytesソケットリクエスト内の最大バイト数int104857600[1,...]highread-only
    socket.send.buffer.bytesソケットサーバのソケットの SO_SNDBUF バッファ値が -1 であれば、OSのデフォルトが使われるでしょう。int102400highread-only
    transaction.max.timeout.msトランザクションに許されるタイムアウトの最大。クライアントがリクエストしたトランザクション時間がこれを超えると、ブローkーアは InitProducerIdRequest 内でエラーを返すでしょう。これによりクライアントはあまりに大きいタイムアウトを避けることができます。これはトランザクションに含まれるトピックからのコンシューマの読み込みを立ち往生させるかもしれません。int900000[1,...]highread-only
    transaction.state.log.load.buffer.sizeプロデューサidとトランザクションをキャッシュにロードする時のトランザクションログ セグメントから読み込むバッチサイズ。int5242880[1,...]highread-only
    transaction.state.log.min.isrトランザクション トピックのための min.insync.replicas 設定を上書きします。int2[1,...]highread-only
    transaction.state.log.num.partitionsトランザクション トピックのためのパーティション数 (配備の後で変更すべきではありません)int50[1,...]highread-only
    transaction.state.log.replication.factorトランザクション トピックのためのリプリケーション要素 (可用性を保証するするために高く設定します)。クラスタのサイズがこのリプリケーション要素の要請に合うまで、内部的な自動トピックの生成は失敗するでしょう。short3[1,...]highread-only
    transaction.state.log.segment.bytesログの圧縮とキャッシュのロードを速くし易いように、トランザクション トピックのセグメントのバイトは比較的小さくすべきです。int104857600[1,...]highread-only
    transactional.id.expiration.msトランザクションのコーディネーターがトランザクションの状態の更新を受け取ることなく積極的にプロデューサのトランザクションidを待つms単位での最大総時間。int604800000[1,...]highread-only
    unclean.leader.election.enableデータの喪失に繋がるとしても、最後の手段としてリーダーとして選出されるように設定されたISRに無いレプリカを有効にするかどうかを示す。booleanfalsehighcluster-wide
    zookeeper.connection.timeout.msクライアントがzookeeperに接続を確立するまで待つ最大時間。設定しない場合は、zookeeper.session.timeout.ms の値が使われますintnullhighread-only
    zookeeper.max.in.flight.requestsクライアントがブロックの前にZookeeperに送信するだろう返事の無いリクエストの最大数。int10[1,...]highread-only
    zookeeper.session.timeout.msZookeeper セッション タイムアウトint6000highread-only
    zookeeper.set.aclクライアントにsecure ACLを使うように設定しますbooleanfalsehighread-only
    broker.id.generation.enableサーバ上で自動ブローカーid生成を有効にする有効にされた場合、reserved.broker.max.id に設定された値は再調査されるべきです。booleantruemediumread-only
    broker.rackブローカーのラック。これはラックを気にするリプリケーションアサインメントで耐障害性のために使われます。例: `RACK1`, `us-east-1d`文字列nullmediumread-only
    connections.max.idle.msアイドル接続タイムアウト: サーバソケットプロセッサ スレッドはこれより多いアイドルの接続を閉じますlong600000mediumread-only
    controlled.shutdown.enableサーバの制御されたシャットダウンを有効にするbooleantruemediumread-only
    controlled.shutdown.max.retries制御されたシャットダウンは複数の理由で失敗するかも知れません。これはそのような障害が起きた時の再試行の数を決定しますint3mediumread-only
    controlled.shutdown.retry.backoff.ms各再試行の前に、システムは以前の障害(コントローラのフェイルオーバー、ログのリプリカ)を起こす状態から回復するための時間が必要です。この設定は再試行の前に待つ総時間を決定します。long5000mediumread-only
    controller.socket.timeout.msコントローラ-ブローカー チャンネルのためのソケットタイムアウトint30000mediumread-only
    default.replication.factor自動的に生成されたトピックのためのデフォルトのリプリケーション要素int1mediumread-only
    delegation.token.expiry.time.msトークンが新しくされる必要があるまでのトークンの有効時間の秒数。デフォルトの値は1日です。long86400000[1,...]mediumread-only
    delegation.token.master.key移譲トークンを生成および検証するためのマスター/秘密キー。全てのブローカーに渡って同じキーが設定されなければなりません。もしキーが設定されていないか空の文字列に設定される場合、ブローカーは移譲トークンのサポートを無効にするでしょう。passwordnullmediumread-only
    delegation.token.max.lifetime.msトークンがもう新しくされることが無いような最大の生存期間を持ちます。デフォルトの値は7日です。long604800000[1,...]mediumread-only
    delete.records.purgatory.purge.interval.requestsレコード削除のリクエストのパージの間隔(リクエストの数)int1mediumread-only
    fetch.purgatory.purge.interval.requests取得リクエストのパージ間隔(リクエストの数)int1000mediumread-only
    group.initial.rebalance.delay.msグループコーディネーターが最初のリバランスを実施する前にもっと多くのコンシューマが新しいグループに入るのを待つ総時間。より大きな遅延は潜在的にリバランスが少ないことを意味しますが、処理が始まるまでの時間が増加します。int3000mediumread-only
    group.max.session.timeout.ms登録されたカスタマのための最大許可セッションタイムアウト。タイムアウトを長くすることでコンシューマは障害の検知までの長い時間を代償にハートビート間のメッセージの処理時間を長くします。int300000mediumread-only
    group.min.session.timeout.ms登録されたカスタマのための最小許可セッションタイムアウト。タイムアウトを短くするとコンシューマーのハートビートの高頻度という代償を払って障害の検知が速くなります。これはブローカーのリソースを圧倒するかもしれません。int6000mediumread-only
    inter.broker.listener.nameブローカー間の通信に使われるリスナー名。これが設定されない場合、リスナー名は security.inter.broker.protocol によって定義されます。これを設定して同時に security.inter.broker.protocol プロパティを設定するのは間違いです。文字列nullmediumread-only
    inter.broker.protocol.versionどのバージョンの内部ブローカープロトコルが使われるかを指定します。これは一般的に全てのブローカーが新しいバージョンにアップグレードした後で取り消されます。有効ないくつかの値の例: 0.8.0, 0.8.1, 0.8.1.1, 0.8.2, 0.8.2.0, 0.8.2.1, 0.9.0.0, 0.9.0.1 完全なリストについては ApiVersion を調べてください。文字列2.0-IV1mediumread-only
    log.cleaner.backoff.ms掃除するログが無い場合にスリープする総時間long15000[0,...]mediumcluster-wide
    log.cleaner.dedupe.buffer.size全てのクリーナースレッドを通じてログのデュプリケーションに使われる総メモリlong134217728mediumcluster-wide
    log.cleaner.delete.retention.msどれだけの期間削除されたレコードを保持するか?long86400000mediumcluster-wide
    log.cleaner.enableログクリーナープロセスをサーバ上で実行することを有効にする。内部オフセットトピックを含む cleanup.policy=compact を使ってトピックを使う場合は有効にしなければなりません。無効にするとそれらのトピックはコンパクト化されずサイズが増加し続けるでしょう。booleantruemediumread-only
    log.cleaner.io.buffer.load.factorLog cleaner dedupe buffer load factor. The percentage full the dedupe buffer can become. 値を高くすると一度にもっと多くのログを掃除することができますが、もっと多くのハッシュの衝突に繋がるでしょう。double0.9mediumcluster-wide
    log.cleaner.io.buffer.size全てのクリーナースレッドを通じてログ クリーナーのI/Oバッファに使われる総メモリint524288[0,...]mediumcluster-wide
    log.cleaner.io.max.bytes.per.secondログのクリーナーは読み込みおよび書き込みi/oがこの値より平均で小さくなるように絞るでしょう。double1.7976931348623157E308mediumcluster-wide
    log.cleaner.min.cleanable.ratioログが掃除されるようになる総ログに対するダーティログの最小割合double0.5mediumcluster-wide
    log.cleaner.min.compaction.lag.msメッセージがログ内で圧縮されずにいる最小時間。圧縮されているログについてのみ適用可能です。long0mediumcluster-wide
    log.cleaner.threadsログの掃除に使われるバックグラウンドスレッドの数int1[0,...]mediumcluster-wide
    log.cleanup.policy保持ウィンドウを超えたセグメントのデフォルトの掃除ポリシー有効なポリシーのカンマ区切りのリスト。有効なポリシーは : "delete" および "compact"listdelete[compact, delete]mediumcluster-wide
    log.index.interval.bytesオフセット インデックスにエントリを追加する間隔int4096[0,...]mediumcluster-wide
    log.index.size.max.bytesオフセット インデックスの最大バイト数int10485760[4,...]mediumcluster-wide
    log.message.format.versionブローカーがログにメッセージを追加する時に使うメッセージフォーマットを指定します。値は有効なApiVersionでなければなりません。いくつかの例: 0.8.2, 0.9.0.0, 0.10.0, 詳細はApiVersionを調べてください。特定のメッセージフォーマットバージョンを指定することで、ユーザはディスク上の既存の全てのメッセージが指定のバージョン以下であることを保証します。この値を間違って設定すると、古いバージョンのコンシューマが理解できないフォーマットを使ってメッセージを受信するため、それらは壊してしまうでしょう。文字列2.0-IV1mediumread-only
    log.message.timestamp.difference.max.msブローカーがメッセージを付け取った時のタイムスタンプと、その中で指定されたタイムスタンプとの間で許される最大の差異。log.message.timestamp.type=CreateTime であれば、タイムスタンプの違いがこの閾値を超えた場合にメッセージは却下されるでしょう。もし log.message.timestamp.type=LogAppendTime であればこの設定は無視されます。不必要な頻度のログのローリングを避けるために、許される最大のタイムスタンプの差異は log.retention.ms より小さくなければなりません。long9223372036854775807mediumcluster-wide
    log.message.timestamp.typeメッセージ内のタイムスタンプが、メッセージが生成された時間か、ログが追加された時間かどうかを定義します。値は `CreateTime` あるいは `LogAppendTime` のどちらかでなければなりません。文字列CreateTime[CreateTime, LogAppendTime]mediumcluster-wide
    log.preallocate新しいセグメントを作る場合にあらかじめファイルを割り当てるべきか?Windows上でKafkaを使う場合は、たぶんtrueに設定する必要があります。booleanfalsemediumcluster-wide
    log.retention.check.interval.msログクリーナーがいずれかのログが削除される対象かどうかをチェックする頻度のミリ秒long300000[1,...]mediumread-only
    max.connections.per.ip各ipアドレスから接続可能な最大数。max.connections.per.ip.overrides プロパティを使って設定された上書きがある場合、これは0に設定することができますint2147483647[0,...]mediumread-only
    max.connections.per.ip.overrides接続のデフォルトの最大数を上書きする ip またはホスト名ごとのカンマ区切りのリスト。値の例は "hostName:100,127.0.0.1:200" です文字列""mediumread-only
    max.incremental.fetch.session.cache.slots私たちが維持するだろう逐次取得セッションの最大数。int1000[0,...]mediumread-only
    num.partitionsトピック毎のログパーティションのデフォルトの数int1[1,...]mediumread-only
    password.encoder.old.secret設定されたパスワードを動的に符号化するために使われた古いsecret。これはsecretが更新される時にのみ必要です。もし指定された場合、全ての動的に符号化されたパスワードはこの古いsecretを使って使って複合化され、ブローカーが起動する時に password.encoder.secret を使って再符号化されます。passwordnullmediumread-only
    password.encoder.secretこのブローカーについて設定されたパスワードを動的に符号化するために使われるsecret。passwordnullmediumread-only
    principal.builder.classKafkaPrincipalBuilder インタフェースを実装するクラスの完全修飾名。これは認証の間に使われる KafkaPrincipal オブジェクトを構築するために使われます。この設定は以前にSSL上でクライアントの認証のために使われていた非推奨のPrincipalBuilderインタフェースもサポートします。principal ビルダーが定義されない場合、デフォルトの挙動は使用するセキュリティ プロトコルに依存します。SSL認証については、principal名が提供されない場合はクライアントの証明書から識別された名前が使われるでしょう; そうでなければ、クライアント認証が必要では無い場合、principal名はANONYMOUSになるでしょう。SASL 認証については、principalはGSSAPIが使われている場合はsasl.kerberos.principal.to.local.rulesで定義されるルールを使って取り出され、他の機構についてはSASL認証IDが使われるでしょう。PLAINTEXT については、principalは ANONYMOUS になるでしょう。クラスnullmediumper-broker
    producer.purgatory.purge.interval.requestsプロデューサのリクエストのパージ間隔(リクエストの数)int1000mediumread-only
    queued.max.request.bytesリクエストがもう読まれなくなるまでに許可されるキューのバイト数long-1mediumread-only
    replica.fetch.backoff.ms取得パーティションエラーが起きた時の総sleep時間。int1000[0,...]mediumread-only
    replica.fetch.max.bytes各パーティションについてフェッチしようとするメッセージのバイト数。これは絶対的な最大ではありません。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、進めることができるようにレコードのバッチはまだ返されるでしょう。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。int1048576[0,...]mediumread-only
    replica.fetch.response.max.bytesフェッチ応答全体に期待される最大バイト。レコードはバッチ内で取得されます。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、進めることができるようにレコードのバッチはまだ返されるでしょう。このように、これは絶対的な最大ではありません。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。int10485760[0,...]mediumread-only
    reserved.broker.max.idbroker.idのために使うことができる最大の数int1000[0,...]mediumread-only
    sasl.client.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。クラスnullmediumread-only
    sasl.enabled.mechanismsKafkaサーバ内で利用可能なSASL機構のリスト。リストにはセキュリティプロバイダが利用可能な任意の機構が含まれるかも知れません。デフォルトではGSSAPIだけが有効です。listGSSAPImediumper-broker
    sasl.jaas.configJAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*;'。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です;passwordnullmediumper-broker
    sasl.kerberos.kinit.cmdKerberos kinit コマンドライン パス。文字列/usr/bin/kinitmediumper-broker
    sasl.kerberos.min.time.before.reloginリフレッシュ試行間のログインスレッドのスリープ時間。long60000mediumper-broker
    sasl.kerberos.principal.to.local.rulesプリンシパル名からショート名(一般的にオペレーティングシステムのユーザ名)へのマッピングのルールのリスト。ルールは順番に評価され、プリンシパル名に合致する最初のルールがショート名にマップするために使われます。リスト内の後のどのようなルールも無視されます。デフォルトでは、{username}/{hostname}@{REALM} の形式のプリンシパル名は {username} にマップされます。形式についての詳細は、 セキュリティ認証とaclを見てください。KafkaPrincipalBuilderの拡張がprincipal.builder.class 設定によって提供されない場合、この設定は無視されることに注意してください。listデフォルト:mediumper-broker
    sasl.kerberos.service.nameKafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。文字列nullmediumper-broker
    sasl.kerberos.ticket.renew.jitter更新時間に追加されるランダムなジッターのパーセンテージ。double0.05mediumper-broker
    sasl.kerberos.ticket.renew.window.factor最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。double0.8mediumper-broker
    sasl.login.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandlerクラスnullmediumread-only
    sasl.login.classLoginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLoginクラスnullmediumread-only
    sasl.login.refresh.buffer.seconds証明書をリフレッシュする時に証明書の有効期限を維持するバッファ時間の秒数。If a refresh would otherwise occur closer to expiration than the number of buffer seconds then the refresh will be moved up to maintain as much of the buffer time as possible. 有効な値は0から3600(1時間); 値が指定されない場合はデフォルトの値 300 (5分)が使われます。この値と sasl.login.refresh.min.period.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short300mediumper-broker
    sasl.login.refresh.min.period.seconds証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short60mediumper-broker
    sasl.login.refresh.window.factorログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.8mediumper-broker
    sasl.login.refresh.window.jitterログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.05mediumper-broker
    sasl.mechanism.inter.broker.protocol内部ブローカー通信に使われるSASL機構。デフォルトは GSSAPI です。文字列GSSAPImediumper-broker
    sasl.server.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL サーバ コールバック ハンドラ クラスの完全修飾名。サーバのコールバックハンドラはlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.plain.sasl.server.callback.handler.class=com.example.CustomPlainCallbackHandler。クラスnullmediumread-only
    security.inter.broker.protocolブローカー間で通信するために使われるセキュリティプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。これを設定して同時に inter.broker.listener.name プロパティを設定するのは間違いです。文字列PLAINTEXTmediumread-only
    ssl.cipher.suitescipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。list""mediumper-broker
    ssl.client.authクライアント認証をリクエストするためのKafkaブローカーを設定します。以下の設定が一般的です:
    • ssl.client.auth=required required に設定された場合、クライアント認証が必要です。
    • ssl.client.auth=requested これはクライアント認証が任意であることを意味します。requestedと異なり、もしこのオプションが設定された場合、クライアントは自身について認証情報を提供しない事を選択できます。
    • ssl.client.auth=none これはクライアント認証が必要では無いことを意味します。
    文字列none[required, requested, none]mediumper-broker
    ssl.enabled.protocolsSSL接続のために有効にされるプロトコルのリスト。listTLSv1.2,TLSv1.1,TLSv1mediumper-broker
    ssl.key.passwordキーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。passwordnullmediumper-broker
    ssl.keymanager.algorithmSSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。文字列SunX509mediumper-broker
    ssl.keystore.locationキーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。文字列nullmediumper-broker
    ssl.keystore.passwordキーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 passwordnullmediumper-broker
    ssl.keystore.typeキーストアファイルのファイル形式。これはクライアントについては任意です。文字列JKSmediumper-broker
    ssl.protocolSSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。文字列TLSmediumper-broker
    ssl.providerSSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。文字列nullmediumper-broker
    ssl.trustmanager.algorithmSSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。文字列PKIXmediumper-broker
    ssl.truststore.locationトラストストアーファイルの場所。 文字列nullmediumper-broker
    ssl.truststore.passwordトラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。passwordnullmediumper-broker
    ssl.truststore.typeトラストストアファイルのファイル形式。文字列JKSmediumper-broker
    alter.config.policy.class.name検証のために使われるべき代替の設定ポリシークラス。クラスはorg.apache.kafka.server.policy.AlterConfigPolicy インタフェースを実装しなければなりません。クラスnulllowread-only
    alter.log.dirs.replication.quota.window.num別のログディレクトリのリプリケーションのクォートのためのメモリ内に保持する標本の数int11[1,...]lowread-only
    alter.log.dirs.replication.quota.window.size.seconds別のログディレクトリのリプリケーションのクォートのための各標本内の時間間隔int1[1,...]lowread-only
    authorizer.class.name認証のために使われるべき認証クラス文字列""lowread-only
    client.quota.callback.classClientQuotaCallback インタフェースを実装するクラスの完全修飾名。これはクライアントのリクエストに適用されるクォータ制限を決定するために使われます。デフォルトでは、, または ZooKeeperに格納されているクォータが適用されます。任意の要求に対して、セッションのユーザ プリンシパルとリクエストのクライアントにもっとも合致するクォータが適用されます。クラスnulllowread-only
    create.topic.policy.class.name検証に使われる必要がある トピック生成ポリシークラス。クラスは org.apache.kafka.server.policy.CreateTopicPolicy インタフェースを実装しなければなりません。クラスnulllowread-only
    delegation.token.expiry.check.interval.ms期限切れの移譲トークンを削除するための走査間隔。long3600000[1,...]lowread-only
    listener.security.protocol.mapリスナー名とセキュリティプロトコル間のマッピング。同じセキュリティプロトコルが1つ以上のポートあるいはIPで使われるように、これが定義されなければなりません。例えば、もしSSLが内部的および外部的なトラフィックの両方で必要とされる場合でも、それらを分離することができます。具体的には、INTERNAL および EXTERNAL という名前のリスナーを定義することができ、このプロパティは以下のようなものです: `INTERNAL:SSL,EXTERNAL:SSL`。このように、キーと値はコロンで区切られ、カンマによってエントリが分割されます。各リスナー名はマップ内で1度だけ現れなければなりません。正規化されたプリフィックス(リスナー名は小文字です)を設定名に追加することで各リスナーは異なるセキュリティ(SSLおよびSASL)設定を設定することができます。例えば、INTERNAL リスナーのために異なるキーストアを設定するために、`listener.name.internal.ssl.keystore.location`という名前の設定が設定されるでしょう。リスナー名のための設定が設定されない場合、設定は一般的な設定に代替されるでしょう (つまり`ssl.keystore.location`)。 文字列PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSLlowper-broker
    log.message.downconversion.enableこの設定はコンシューマのリクエストを満たすためにメッセージ形式のダウン-コンバージョンが有効にされるかどうかを制御します。falseに設定された場合、ブローカーは古いメッセージ形式を期待するコンシューマのためのダウン-コンバージョンを行わないでしょう。そのような古いクライアントからのコンシューマリクエストについては、ブローカーはUNSUPPORTED_VERSION エラーで応答します。この設定はフォロワーへのレプリケーションに必要とされるかもしれないメッセージ形式の変換に適用されません。booleantruelowcluster-wide
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""lowcluster-wide
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]lowread-only
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFOlowread-only
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[1,...]lowread-only
    password.encoder.cipher.algorithm設定されたパスワードを動的に符号化するために使われたCipherアルゴリズム。文字列AES/CBC/PKCS5Paddinglowread-only
    password.encoder.iterations設定されたパスワードを動的に符号化するために使われた繰り返しカウント。int4096[1024,...]lowread-only
    password.encoder.key.length設定されたパスワードを動的に符号化するために使われたキーの長さ。int128[8,...]lowread-only
    password.encoder.keyfactory.algorithm設定されたパスワードを動的に符号化するために使われたSecretKeyFactoryアルゴリズム。デフォルトは利用可能であれば PBKDF2WithHmacSHA512、そうでなければ PBKDF2WithHmacSHA1。文字列nulllowread-only
    quota.window.numクライアントのクォートのためのメモリ内に保持する標本の数int11[1,...]lowread-only
    quota.window.size.secondsクライアントのクォートのための各標本内の時間間隔int1[1,...]lowread-only
    replication.quota.window.numリプリケーションのクォートのためのメモリ内に保持する標本の数int11[1,...]lowread-only
    replication.quota.window.size.secondsリプリケーションのクォートのための各標本内の時間間隔int1[1,...]lowread-only
    ssl.endpoint.identification.algorithmサーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 文字列httpslowper-broker
    ssl.secure.random.implementationSSL暗号化操作のために使われる SecureRandom PRNG 実装。 文字列nulllowper-broker
    transaction.abort.timed.out.transaction.cleanup.interval.msタイムアウトしたトランザクションをロールバックする間隔int60000[1,...]lowread-only
    transaction.remove.expired.transaction.cleanup.interval.mstransactional.id.expiration.msが経過したことにより期限切れになったトランザクションを削除する間隔int3600000[1,...]lowread-only
    zookeeper.sync.time.msZKリーダーからどれだけZKフォロワーが遅れることができるかint2000lowread-only

    ブローカー設定についての詳細はscalaクラスkafka.server.KafkaConfigの中で見つけることができます。

    3.1.1ブローカー設定の更新

    Kafka バージョン 1.1 から、ブローカーの設定の幾つかがブローカーの再起動無しに更新することができます。各ブローカーの設定の更新モードについては、ブローカー設定動的更新モードのカラムを見てください。
    • read-only: 更新のためにブローカーの再起動を必要とします
    • per-broker: 各ブローカーについて動的に更新することができます
    • cluster-wide: クラスタ全体のデフォルトとして動的に更新することができます。テストのためにブローカー毎の値として更新することもできます。
    ブローカーid 0 の現在のブローカーの設定(例えば、ログ クリーナーのスレッド数)を変更するには:
      > bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --alter --add-config log.cleaner.threads=2
      
    ブローカーid 0 の現在の動的なブローカーの設定を記述するには:
      > bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --describe
      
    ブローカーid 0 の設定の上書きを削除し、静的に設定されたあるいはデフォルトの値に戻すには (例えば、ログ クリーナーのスレッド数):
      > bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-name 0 --alter --delete-config log.cleaner.threads
      
    幾つかの設定はクラスタ全体を通して一貫した値を維持するためにクラスタ全体のデフォルトとして設定されるかもしれません。クラスタ内の全てのブローカーはクラスタのデフォルトの更新を処理するでしょう。例えば、全てのブローカー上のログ クリーナーのスレッドを更新するには:
      > bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-default --alter --add-config log.cleaner.threads=2
      
    現在の設定された動的なクラスタ全体のデフォルトの設定を表示するには:
      > bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type brokers --entity-default --describe
      
    クラスタレベルで設定可能な全ての設定はブローカー毎のレベルでも設定されるかもしれませんん(例えば、テストのため)。もし設定値が異なるレベルで定義される場合、以下の優先度の順番が使われます:
    • ZooKeeperに格納された動的なブローカー毎の設定
    • ZooKeeperに格納された動的なクラスタ全体のデフォルト設定
    • server.propertiesからの静的なブローカー設定
    • Kafkaのデフォルトは、ブローカーの設定を見てください
    動的にパスワードの設定を更新

    動的に更新されたパスワードの設定値はZooKeeperに格納される前に暗号化されます。ブローカーの設定 password.encoder.secret はパスワード設定の動的な更新を有効にするためにserver.propertiesの中で設定されなければなりません。secret は異なるブローカーでは異なるかもしれません。

    パスワードの符号化に使われるsecretはブローカーのローリング再起動と共にローテートされるかもしれません。ZooKeeper内の現在のところパスワードの符号化に使われた古いsecretは静的なブローカーの設定password.encoder.old.secret内で提供され、新しいsecretはpassword.encoder.secret内で提供されなければなりません。ZooKeeper内に格納されている全ての動的なパスワードの設定はブローカーが起動する時に新しいsecretを使って再符号化されるでしょう。

    Kafka 1.1.xでは、パスワード設定が変更されていない場合でさえも、kafka-configs.sh を使って設定を更新した時に、各変更リクエストの中で全ての動的に更新されるパスワードの設定は提供されなければなりません。この制約は将来のリリースで削除されるでしょう。

    ブローカーの開始前にZooKeeper内のパスワード設定を更新する
    Kafka 2.0.0以降、kafka-configs.shはブローカーをブートストラップする前にZooKeeperを使って動的なブローカーの設定の更新を有効にします。これにより全てのパスワード設定が暗号化された形式で格納されるため、server.properties内のパスワードを平文にする必要はありません。変更コマンド内にパスワード設定が含まれる場合、ブローカーの設定password.encoder.secretも指定されなければなりません。追加の暗号化パラメータも指定されるかもしれません。パスワードのエンコーダの設定はZooKeeper内に残らないでしょう。例えば、ブローカー 0 上のリスナーINTERNALのための SSLキーパスワードを格納するには:
      > bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type brokers --entity-name 0 --alter --add-config
        'listener.name.internal.ssl.key.password=key-password,password.encoder.secret=secret,password.encoder.iterations=8192'
      
    設定 listener.name.internal.ssl.key.password は指定されたエンコーダの設定を使って暗号化された形式でZooKeeper内に保持されるでしょう。エンコーダの秘密鍵と繰り返しはZooKeeper内に保持されません。
    既存のlistenerのSSL キーストアの更新
    ブローカーは危殆化証明書の危険を減らすために短い有効期間のSSLキーストアを使って設定されるかもしれません。キーストアはブローカーの再起動無しに動的に更新されるかもしれません。設定名は特定のlistenerのキーストア設定だけが更新されるようにlistenerのプリフィックスlistener.name.{listenerName}.を使って前置されなければなりません。以下の設定はブローカー毎のレベルで1つの更新リクエストの中で更新されるかもしれません:
    • ssl.keystore.type
    • ssl.keystore.location
    • ssl.keystore.password
    • ssl.key.password
    listenerが内部ブローカー listenerである場合、更新は新しいキーストアがlistenerについて設定されたtruststoreによって信頼される場合のみ許可されます。他のlistenerについては、ブローカーによってキーストア上で信頼の検証が行われません。証明書はクライアント認証の失敗を避けるために古い証明書によって署名された同じ認証局によって署名されなければなりません。
    既存のlistenerのSSL トラストストアの更新
    ブローカーのトラストストアは証明書の追加あるいは削除のためのブローカーの再起動無しに動的に更新することができます。更新されたトラストストアは新しいクライアント接続を認証するために使われるでしょう。設定名は特定のlistenerのトラストストア設定だけが更新されるようにlistenerのプリフィックスlistener.name.{listenerName}.を使って前置されなければなりません。以下の設定はブローカー毎のレベルで1つの更新リクエストの中で更新されるかもしれません:
    • ssl.truststore.type
    • ssl.truststore.location
    • ssl.truststore.password
    もしリスナーがブローカー間のリスナーの場合、そのリスナーの既存のキーストアが新しいトラスト ストアによって信頼される場合のみ、更新が許可されます。他のリスナーについては、更新の前にブローカーによる信頼の検証は行われません。新しいトラスト ストアからのクライアントの証明書の署名に使われるCA証明書の削除は、クライアントの認証の失敗に繋がるかもしれません。
    デフォルトのトピックの設定の更新
    ブローカーによって使われるデフォルトのトピックの設定オプションはブローカーの再起動無しに更新されるかもしれません。設定はトピック毎の設定と同等のトピックの設定の上書き無しに適用されます。1つ以上のそれらの設定は全てのブローカーによって使われるクラスタのデフォルトレベルで上書きされるかもしれません。
    • log.segment.bytes
    • log.roll.ms
    • log.roll.hours
    • log.roll.jitter.ms
    • log.roll.jitter.hours
    • log.index.size.max.bytes
    • log.flush.interval.messages
    • log.flush.interval.ms
    • log.retention.bytes
    • log.retention.ms
    • log.retention.minutes
    • log.retention.hours
    • log.index.interval.bytes
    • log.cleaner.delete.retention.ms
    • log.cleaner.min.compaction.lag.ms
    • log.cleaner.min.cleanable.ratio
    • log.cleanup.policy
    • log.segment.delete.delay.ms
    • unclean.leader.election.enable
    • min.insync.replicas
    • max.message.bytes
    • compression.type
    • log.preallocate
    • log.message.timestamp.type
    • log.message.timestamp.difference.max.ms
    Kafkaバージョン 2.0.0以降は、設定 unclean.leader.election.enableが動的に更新された時にコントローラによって曖昧なリーダー選択が自動的に有効にされます。Kafka バージョン 1.1.x では、unclean.leader.election.enable への変更は新しいコントローラが選出される時のみ効果があります。コントローラの再選出は実行によって強制されるかもしれません:
      > bin/zookeeper-shell.sh localhost
      rmr /controller
      
    ログ クリーナーの設定の更新
    ログ クリーナーの設定は全てのブローカーによって使われるクラスタのデフォルトレベルで動的に更新されるかもしれません。設定はログのクリーニングの次の繰り返しで効果があります。以下の1つ以上のこれらの設定が更新されるかもしれません:
    • log.cleaner.threads
    • log.cleaner.io.max.bytes.per.second
    • log.cleaner.dedupe.buffer.size
    • log.cleaner.io.buffer.size
    • log.cleaner.io.buffer.load.factor
    • log.cleaner.backoff.ms
    スレッド設定の更新
    ブローカーによって使われる様々なスレッドプールのサイズは全てのブローカーによって使われるクラスターのデフォルトレベルで動的に更新されるかもしれません。設定の更新が緩やかに処理されるように更新は範囲 currentSize / 2 から currentSize * 2 に制限されます。
    • num.network.threads
    • num.io.threads
    • num.replica.fetchers
    • num.recovery.threads.per.data.dir
    • log.cleaner.threads
    • background.threads
    listenerの追加と削除

    listener は動的に追加あるいは削除されるかもしれません。新しいlistenerを追加する時、listenerのセキュリティ設定がlistenerプリフィックスlistener.name.{listenerName}.を使ってlistener設定として提供されなければなりません。もし新しいlistenerがSASLを使う場合、listenerのJAAS設定がlistenerと仕組みのプリフィックスを持つJAAS設定プロパティsasl.jaas.configを使って提供されなければなりません。詳細はKafkaブローカーのためのJAAS 設定 を見てください。

    Kafka バージョン 1.1.x では、内部ブローカー listenerによって使われるlistenerは動的に更新されないかもしれません。新しいlistenerへの内部ブローカーlistenerを更新するために、新しいlistenerがブローカーの再起動無しに全てのブローカー上で追加されるかもしれません。inter.broker.listener.nameを更新するためにローリング再起動が必要とされます。

    新しいlistenerの全てのセキュリティ設定に加えて、以下の設定がブローカー毎のレベルで動的に更新されるかもしれません:
    • リスナー
    • advertised.listeners
    • listener.security.protocol.map
    内部ブローカー listenerは静的なブローカー設定 inter.broker.listener.name あるいは inter.broker.security.protocol を使って設定されなければなりません。

    3.2トピックレベルの設定

    トピックに関係がある設定はサーバのデフォルトとトピック毎に上書かれる任意の両方を持ちます。トピック毎の設定が与えられない場合は、サーバのデフォルトが使われます。この上書きはトピックの作成時に1つ以上の--config オプションを与えることで設定することができます。この例は独自の最大メッセージサイズとフラッシュレートを持つmy-topicという名前のトピックを生成します:
      > bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic my-topic --partitions 1
          --replication-factor 1 --config max.message.bytes=64000 --config flush.messages=1
      
    上書きは、他の設定コマンドを使って変更あるいは後で設定することもできます。この例は my-topicのための最大メッセージサイズを更新します:
      > bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic
          --alter --add-config max.message.bytes=128000
      
    トピック上に設定された上書きを調べるために、以下を実行することができます
      > bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --describe
      
    上書きを削除するために、以下のようにすることができます
      > bin/kafka-configs.sh --zookeeper localhost:2181  --entity-type topics --entity-name my-topic
          --alter --delete-config max.message.bytes
      
    以下はトピックレベルの設定です。このプロパティのためのサーバのデフォルトの設定は Server Default Property の頭書きのもとで与えられます。明示的なトピックの設定の上書きが無い場合は、指定されたサーバのデフォルト設定値のみがトピックに適用されます。
    名前 説明 種類 デフォルト 有効な値 サーバのデフォルトのプロパティ 重要性
    cleanup.policy"delete" または "compact" のどちらかの文字列。この文字列は古いログセグメント上で使用する保持ポリシーを指定します。デフォルトのポリシー ("delete") は保持期間あるいはサイズの制限に到達した時に古いセグメントを破棄するでしょう。"compact" 設定はトピックでのlog のコンパクション を有効にするでしょう。listdelete[compact, delete]log.cleanup.policymedium
    compression.type指定されたトピックのための最終的な圧縮タイプを指定する。この設定は標準的な圧縮コーディック('gzip', 'snappy', 'lz4')を受け付けます。更に、非圧縮に相当する 'uncompressed'; プロデューサによって設定された元の圧縮コーディックを保持することを意味する'producer' を受け付けます。文字列producer[uncompressed, snappy, lz4, gzip, producer]compression.typemedium
    delete.retention.mslog compacted トピックのための削除の墓石の目印を維持するための総時間。もし最終のステージの有効なスナップショットを取得するためにオフセット0から始める場合は、この設定はコンシューマが読み込みを完了させる時間の境界も与えます (そうでなければ、削除の墓石はそれらが走査を完了する前に集められるかもしれません)。long86400000[0,...]log.cleaner.delete.retention.msmedium
    file.delete.delay.msファイルシステムからファイルを削除するまでの待ち時間long60000[0,...]log.segment.delete.delay.msmedium
    flush.messagesこの設定はログに書かれるデータのfsyncを強制する間隔を指定することができます。例えば、もしこれが1に設定された場合、各メッセージの後にfsyncされるでしょう; もし5であれば各5メッセージ毎にfsyncするでしょう。一般的には、これを使わずに、耐久性のためにリプリケーションを使い、オペレーティングシステムのバックグラウンドフラッシュ機能のほうがもっと効率的なためそれにさせることをお勧めします。この設定はトピック毎ベースで上書きすることができます(トピック毎の設定の章を見てください)。long9223372036854775807[0,...]log.flush.interval.messagesmedium
    flush.msこの設定はログに書かれるデータのfsyncを強制する時間を指定することができます。例えば、これが1000に設定された場合、1000ms過ぎた後でfsyncするでしょう。一般的には、これを使わずに、耐久性のためにリプリケーションを使い、オペレーティングシステムのバックグラウンドフラッシュ機能のほうがもっと効率的なためそれにさせることをお勧めします。long9223372036854775807[0,...]log.flush.interval.msmedium
    follower.replication.throttled.replicasログのリプリケーションがフォロワー側で絞られなければならないレプリカのリスト。リストは [PartitionId]:[BrokerId],[PartitionId]:[BrokerId]:... の形式のレプリカのセットを表さなければなりません。あるいはこのトピックについての全てのレプリカを絞るためにワイルドカード '*' を使うことができます。list""[partitionId],[brokerId]:[partitionId],[brokerId]:...follower.replication.throttled.replicasmedium
    index.interval.bytesこの設定はKafkaがオフセットインデックスにエントリを追加する頻度を制御します。デフォルトの設定はおおよそ各4096バイトごとにメッセージをインデックスすることを保証します。もっとインデックスを増やすことでログの正確な場所の近くに読み込みをジャンプすることができますが、インデックスが大きくなります。おそらくこれを変更する必要はないでしょう。int4096[0,...]log.index.interval.bytesmedium
    leader.replication.throttled.replicasログのリプリケーションがリーダー側で絞られなければならないレプリカのリスト。リストは [PartitionId]:[BrokerId],[PartitionId]:[BrokerId]:... の形式のレプリカのセットを表さなければなりません。あるいはこのトピックについての全てのレプリカを絞るためにワイルドカード '*' を使うことができます。list""[partitionId],[brokerId]:[partitionId],[brokerId]:...leader.replication.throttled.replicasmedium
    max.message.bytes

    Kafkaで可能な最も大きなレコードのバッチサイズ。これが増え、0.10.2より古いコンシューマがある場合、コンシューマがこの大きさのレコードバッチを取得できるようにコンシューマの取得サイズも増やす必要があります。

    最新のメッセージフォーマットのバージョンでは、効率化のためにレコードは常にバッチにグループ化されます。以前のメッセージフォーマットのバージョンでは、圧縮されていないレコードはバッチにグループ化されず、この制限は1つのレコードにのみ適用されます。

    int1000012[0,...]message.max.bytesmedium
    message.format.versionブローカーがログにメッセージを追加する時に使うメッセージフォーマットを指定します。値は有効なApiVersionでなければなりません。いくつかの例: 0.8.2, 0.9.0.0, 0.10.0, 詳細はApiVersionを調べてください。特定のメッセージフォーマットバージョンを指定することで、ユーザはディスク上の既存の全てのメッセージが指定のバージョン以下であることを保証します。この値を間違って設定すると、古いバージョンのコンシューマが理解できないフォーマットを使ってメッセージを受信するため、それらは壊してしまうでしょう。文字列2.0-IV1log.message.format.versionmedium
    message.timestamp.difference.max.msブローカーがメッセージを付け取った時のタイムスタンプと、その中で指定されたタイムスタンプとの間で許される最大の差異。message.timestamp.type=CreateTime であれば、タイムスタンプの違いがこの閾値を超えた場合にメッセージは却下されるでしょう。もし message.timestamp.type=LogAppendTime であれば、この設定は無視されます。long9223372036854775807[0,...]log.message.timestamp.difference.max.msmedium
    message.timestamp.typeメッセージ内のタイムスタンプが、メッセージが生成された時間か、ログが追加された時間かどうかを定義します。値は `CreateTime` あるいは `LogAppendTime` のどちらかでなければなりません。文字列CreateTime[CreateTime, LogAppendTime]log.message.timestamp.typemedium
    min.cleanable.dirty.ratioこの設定はログの圧縮機がログを掃除しようとする頻度を制御します(log compaction が有効であると仮定)。デフォルトでは、ログの50%以上がコンパクト化された場所にあるログを掃除することを避けるでしょう。この率はデュープリケートによってログ内で消費される領域の最大を制限します(50%ではログの最大50%がデュープリケートされるかも知れません)。率を高くすることは、より少なく、より効率的な掃除を意味しますが、ログ内のより多くの消費される領域を意味するでしょう。double0.5[0,...,1]log.cleaner.min.cleanable.ratiomedium
    min.compaction.lag.msメッセージがログ内で圧縮されずにいる最小時間。圧縮されているログについてのみ適用可能です。long0[0,...]log.cleaner.min.compaction.lag.msmedium
    min.insync.replicasプロデューサがackを "all" (あるいは "-1") に設定する場合、この設定は書き込みが成功したと見なされるように書き込みを知らせる必要があるレプリカの最小数を指定します。この最小限に一致しない場合、プロデューサは例外(NotEnoughReplicas あるいは NotEnoughReplicasAfterAppendのどちらか)を上げるでしょう。
    一緒に使った場合、min.insync.replicas と acks は素晴らしい耐久性の保証を強化することができます。典型的なシナリオは、3つのレプリケーション ファクターを持つトピックを生成し、min.insync.replicas を 2 に設定し、"all" のackを使って生成します。これは、もしレプリカの過半数が書き込みを受け取らなかった場合にプロデューサが例外を上げることを保証するでしょう。
    int1[1,...]min.insync.replicasmedium
    preallocate新しいログのセグメントを生成する時にディスク上にファイルをあらかじめ割り当てる必要がある場合はTrue。booleanfalselog.preallocatemedium
    retention.bytesこの設定は、"delete" 維持ポリシーを使う場合は空間を解放するために古いログのセグメントを削除する前までのパーティション(ログのセグメントからなります)が成長する最大のサイズを制御します。デフォルトでは時間の制限だけでサイズの制限はありません。この制限はパーティションレベルで強制されるため、トピックの維持をバイトで計算するにはそれにパーティションの数を掛けてください。long-1log.retention.bytesmedium
    retention.msこの設定は、"delete" 維持ポリシーを使う場合は空間を解放するために古いログのセグメントを削除する前にログを保持するだろう最大の時間を制御します。これはコンシューマがデータをどれだけ早く読まなければならないかのSLAを表します。-1に設定される場合、時間の制限無しが適用されます。long604800000log.retention.msmedium
    segment.bytesこの設定はログのためのセグメントファイルサイズを制御します。維持と掃除は常にファイルに一度に行われます。つまり、大きなセグメントサイズは少ないファイルを意味しますが、維持の制御の粒度が小さくなります。int1073741824[14,...]log.segment.bytesmedium
    segment.index.bytesこの設定はオフセットをファイルの場所にマップするインデックスのサイズを制御します。このインデックスファイルはあらかじめ割り当てられていて、ログがロールした後でのみ縮小されます。通常この設定を変更する必要はありません。int10485760[0,...]log.index.size.max.bytesmedium
    segment.jitter.ms立て続けのセグメントのローリングを避けるためにスケジュールされたセグメントロール時間から引かれるランダムなズレの最大long0[0,...]log.roll.jitter.msmedium
    segment.msこの設定は、保持の仕組みが古いデータを削除あるいは圧縮できるように、セグメントファイルが一杯では無い場合でもKafkaがログをロールするまでの時間を制御します。long604800000[1,...]log.roll.msmedium
    unclean.leader.election.enableデータの喪失に繋がるとしても、最後の手段としてリーダーとして選出されるように設定されたISRに無いレプリカを有効にするかどうかを示す。booleanfalseunclean.leader.election.enablemedium
    message.downconversion.enableこの設定はコンシューマのリクエストを満たすためにメッセージ形式のダウン-コンバージョンが有効にされるかどうかを制御します。falseに設定された場合、ブローカーは古いメッセージ形式を期待するコンシューマのためのダウン-コンバージョンを行わないでしょう。そのような古いクライアントからのコンシューマリクエストについては、ブローカーはUNSUPPORTED_VERSION エラーで応答します。この設定はフォロワーへのレプリケーションに必要とされるかもしれないメッセージ形式の変換に適用されません。booleantruelog.message.downconversion.enablelow

    3.3プロデューサの設定

    以下はJavaプロデューサの設定です:
    名前 説明 種類 デフォルト 有効な値 重要性
    key.serializerorg.apache.kafka.common.serialization.Serializer インタフェースを実装するキーのためのシリアライザ クラス。クラスhigh
    value.serializerorg.apache.kafka.common.serialization.Serializer インタフェースを実装する値のためのシリアライザ クラス。クラスhigh
    acksリクエストが完了したと見なす前にリーダーが受け取ることをプロデューサが要求する通知の数。これは送信されたレコードの持続性を制御します。以下の設定が可能です:
    • acks=0 0に設定されるとプロデューサはサーバからの承認を全く待たないでしょう。レコードはすぐにソケットバッファに追加され、送信されたものと見なされます。この場合サーバがレコードを受け取ったかどうかの保証はできません。そしてretries 設定は効果が無いでしょう (クライアントは一般的に障害を知らないため)。各レコードについて返されるオフセットは常に -1 に設定されるでしょう。
    • acks=1 これは、リーダーはレコードをローカルログに書き込むが、すべてのフォロワーからの完全な応答を待たずに応答するでしょう。この場合、リーダは通知の直後でフォロワーがリプリケートする前に失敗すべきで、その後レコードが喪失するでしょう。
    • acks=all これは、リーダーはレコードに応答するためにin-syncレプリカの完全なセットを待つだろうことを意味します。これは、少なくとも1つのin-syncレプリカが生きている限りレコードは失われないだろうことを保証します。これはもっとも強力な利用可能な保証です。これは acks=-1 設定と同じです。
    文字列1[all, -1, 0, 1]high
    bootstrap.serversKafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,...の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@7cd62f43high
    buffer.memoryプロデューサがサーバに送られるのを待っているレコードをバッファするために使うことができるメモリの総バイト数。サーバに配送することができるより早くレコードが送信された場合、プロデューサは例外を投げた後で max.block.ms の間ブロックするでしょう。

    この設定は大まかにプロデューサが利用しようとする総メモリに対応しますが、プロデューサが使用する全てのメモリがバッファリングに使われるわけではないためハードバウンドではありません。いくつかの追加のメモリが圧縮(圧縮が有効な場合)と、やってきているリクエストを保持するために使われるでしょう。

    long33554432[0,...]high
    compression.typeプロデューサによって生成された全てのデータのための圧縮タイプ。デフォルトは none (つまり、非圧縮)。有効な値は、none, gzip, snappy あるいは lz4 です。圧縮はデータの完全なバッチです。つまりバッチの効果は圧縮率にも影響するでしょう (多くのバッチ化はより良い圧縮を意味します)。文字列nonehigh
    retries0より大きい値を設定すると、クライアントは一時的なエラーによる障害による送信の全てのレコードを再送信するでしょう。この再試行はクライアントがエラーを受け取る時にレコードを再送するのと変わらないことに注意してください。max.in.flight.requests.per.connection を1に設定せずに再試行を許すと、もし2つのバッチが1つのパーティションに送信され、最初が失敗して2つ目が成功したが再試行し、2つ目のバッチのレコードが最初に現れるかもしれないため、レコードの順番が変わるかもしれません。int0[0,...,2147483647]high
    ssl.key.passwordキーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。passwordnullhigh
    ssl.keystore.locationキーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。文字列nullhigh
    ssl.keystore.passwordキーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 passwordnullhigh
    ssl.truststore.locationトラストストアーファイルの場所。 文字列nullhigh
    ssl.truststore.passwordトラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。passwordnullhigh
    batch.size多数のレコードが同じパーティションに送信される時はいつもプロデューサはバッチのレコードをより少ないリクエストにまとめようとするでしょう。これはクライアントとサーバの両方でパフォーマンスを助けます。この設定はデフォルトのバッチサイズをバイトで制御します。

    このサイズより大きいバッチレコードには何も試行されないでしょう。

    ブローカーに送信されるリクエストは複数のバッチを含むでしょう。各パーティションについて1つの送信することが可能なデータを持つバッチです。

    小さなバッチサイズはバッチ化を一般的でなくし、スループットを下げるかもしれません(バッチサイズ 0はバッチ化を完全に無効にするでしょう)。大きなバッチサイズは追加のレコードに備えて指定されたバッチサイズのバッチを常に割り当てるため、メモリを幾分贅沢に使うかもしれません。

    int16384[0,...]medium
    client.idリクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。文字列""medium
    connections.max.idle.msこの設定によって指定されるミリ秒後にアイドルの接続を閉じます。long540000medium
    linger.msプロデューサグループはリクエストの転送間に到着した全てのレコードを1つのバッチリクエストにまとめます。通常、これはレコードが送信できるように早く到着した時に負荷を受けてのみ起こります。しかし、ある状況では、クライアントは控えめな負荷の場合でもリクエストの数を減らしたいと思うかも知れません。この設定は少しの人為的な遅延によってこれを成し遂げます - つまり、すぐにレコードを送信するのではなく、プロデューサは一緒にバッチ化されることができるように他のレコードが送信されるように指定された遅延まで待つでしょう。これはTCPでのNagleアルゴリズムへの相似として考えることができます。この設定ではバッチ処理の遅延の上限が与えられます: パーティションについて一旦batch.size分のレコードを取得すると、それはこの設定に関係なく即座に送信されるでしょう。しかしもしこのパーティションについて集約されたバイトがこれより少ない場合、より多くのレコードが現れるまで指定された時間だけ'残る'でしょう。この設定のデフォルトは 0 です (つまり、遅延はありません)。例えば、linger.ms=5に設定すると、送信されるリクエストの数を減らす効果がありますが、負荷が無い時にレコードの送信に5msのレイテンシを追加するでしょう。long0[0,...]medium
    max.block.ms設定はどれだけ長くKafkaProducer.send()KafkaProducer.partitionsFor() がブロックするかを制御します。これらのメソッドはバッファがいっぱいあるいはメタデータを利用できないことのどちらかでブロックされるかもしれません。ユーザが指定したシリアライザあるいはパーティショナーの中でのブロックはこのタイムアウトに対してカウントされないでしょう。long60000[0,...]medium
    max.request.sizeリクエストの最大バイトサイズ。この設定は大きなリクエストを送信することを避けるためにプロデューサが1つのリクエスト内で送信するレコードのバッチの数を制限するでしょう。これは最大レコードバッチサイズの効果的なキャップでもあります。サーバはこれとは異なるかも知れないレコードバッチサイズ上の独自のキャップを持つことに注意してください。int1048576[0,...]medium
    partitioner.classorg.apache.kafka.clients.producer.Partitioner インタフェースを実装するパーティショナークラス。クラスorg.apache.kafka.clients.producer.internals.DefaultPartitionermedium
    receive.buffer.bytesデータを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int32768[-1,...]medium
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。不必要なプロデューサの再試行によるメッセージの重複の可能性を減らすために、これは replica.lag.time.max.ms (ブローカーの設定) より大きくなければなりません。int30000[0,...]medium
    sasl.client.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。クラスnullmedium
    sasl.jaas.configJAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*;'。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です;passwordnullmedium
    sasl.kerberos.service.nameKafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。文字列nullmedium
    sasl.login.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandlerクラスnullmedium
    sasl.login.classLoginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLoginクラスnullmedium
    sasl.mechanismクライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。文字列GSSAPImedium
    security.protocolブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。文字列PLAINTEXTmedium
    send.buffer.bytesデータを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int131072[-1,...]medium
    ssl.enabled.protocolsSSL接続のために有効にされるプロトコルのリスト。listTLSv1.2,TLSv1.1,TLSv1medium
    ssl.keystore.typeキーストアファイルのファイル形式。これはクライアントについては任意です。文字列JKSmedium
    ssl.protocolSSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。文字列TLSmedium
    ssl.providerSSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。文字列nullmedium
    ssl.truststore.typeトラストストアファイルのファイル形式。文字列JKSmedium
    enable.idempotence'true' に設定されると、プロデューサは各メッセージの確実に1回のコピーがストリームに書かれることを保証するでしょう。'false' の場合、プロデューサはブローカーの障害などによる再試行でストリーム内に再試行のメッセージの重複を書き込むかもしれません。等冪を有効にするには max.in.flight.requests.per.connection を5以下に設定する必要があり、retries は0より大きく、ackは 'all' でなければならないことに注意してください。これらの値がユーザによって明示的に設定されない場合、適切な値が選択されるでしょう。互換性の無い値が設定された場合、ConfigException が投げられるでしょう。booleanfalselow
    interceptor.classesインタセプタとして使われるクラスのリスト。org.apache.kafka.clients.producer.ProducerInterceptor インタフェースの実装により、Kafkaクラスタに発行される前にプロデューサによって受け取られるレコードを捉え(そしておそらく変化す)ることができます。デフォルトでは、インタセプタはありません。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@6d4b1c02low
    max.in.flight.requests.per.connectionクライアントがブロックされる前に1つの接続上で送信するだろう、返事の無いリクエストの最大数。この設定が1より大きく設定され、失敗した送信がある場合は、再試行(つまり、再試行が有効な場合)により、メッセージの再注文の可能性があります。int5[1,...]low
    metadata.max.age.msパーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。long300000[0,...]low
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@6093dd95low
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]low
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFO[INFO, DEBUG]low
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[0,...]low
    reconnect.backoff.max.ms接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。long1000[0,...]low
    reconnect.backoff.ms指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。long50[0,...]low
    retry.backoff.ms指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。long100[0,...]low
    sasl.kerberos.kinit.cmdKerberos kinit コマンドライン パス。文字列/usr/bin/kinitlow
    sasl.kerberos.min.time.before.reloginリフレッシュ試行間のログインスレッドのスリープ時間。long60000low
    sasl.kerberos.ticket.renew.jitter更新時間に追加されるランダムなジッターのパーセンテージ。double0.05low
    sasl.kerberos.ticket.renew.window.factor最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。double0.8low
    sasl.login.refresh.buffer.seconds証明書をリフレッシュする時に証明書の有効期限を維持するバッファ時間の秒数。If a refresh would otherwise occur closer to expiration than the number of buffer seconds then the refresh will be moved up to maintain as much of the buffer time as possible. 有効な値は0から3600(1時間); 値が指定されない場合はデフォルトの値 300 (5分)が使われます。この値と sasl.login.refresh.min.period.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short300[0,...,3600]low
    sasl.login.refresh.min.period.seconds証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short60[0,...,900]low
    sasl.login.refresh.window.factorログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.8[0.5,...,1.0]low
    sasl.login.refresh.window.jitterログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.05[0.0,...,0.25]low
    ssl.cipher.suitescipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。listnulllow
    ssl.endpoint.identification.algorithmサーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 文字列httpslow
    ssl.keymanager.algorithmSSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。文字列SunX509low
    ssl.secure.random.implementationSSL暗号化操作のために使われる SecureRandom PRNG 実装。 文字列nulllow
    ssl.trustmanager.algorithmSSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。文字列PKIXlow
    transaction.timeout.msトランザクションのコーディネーターが実行中のトランザクションの破棄の前にプロデューサからのトランザクションの状態更新を待つ最大総時間。もしこの値がブローカー内の transaction.max.timeout.ms 設定よりも大きい場合は、リクエストは`InvalidTransactionTimeout` エラーで失敗するでしょう。int60000low
    transactional.idトランザクションの配送のために使うTransactionalId。これは、クライアントに新しいトランザクションが開始される前に同じトランザクションidを使っているトランザクションを保証するため、複数のプロデューサセッションにまたがる信頼性セマンティクスを有効にします。TransactionalId が指定されない場合、プロデューサは等冪な配送に制限されます。TransactionalIdが設定される場合、enable.idempotence が有効でなければならないことに注意してください。デフォルトはnullで、トランザクションを使うことができないことを意味します。トランザクションはデフォルトでプロダクションのための設定に推奨される少なくとも3つのブローカーのクラスタを必要とすることに注意してください; 開発のためにブローカーの設定 `transaction.state.log.replication.factor`を調整することでこれを変更することができます。文字列null空では無い文字列low

    従来のScala プロデューサの設定に興味がある人のために、ここで情報を見つけることができます。

    3.4コンシューマの設定

    0.9.0.0 で、古いScalaベースの単純で高レベルのコンシューマの置き換えとして新しいJavaコンシューマを導入しました。新しいコンシューマと古いコンシューマの両方の設定を以下で説明します。

    3.4.1新しいコンシューマの設定

    以下は新しいコンシューマのための設定です:
    名前 説明 種類 デフォルト 有効な値 重要性
    key.deserializerorg.apache.kafka.common.serialization.Deserializerインタフェースを実装するキーのためのDeserializerクラス。クラスhigh
    value.deserializerorg.apache.kafka.common.serialization.Deserializerインタフェースを実装する値のためのDeserializerクラス。クラスhigh
    bootstrap.serversKafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,...の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@6093dd95high
    fetch.min.bytesサーバが各フェッチリクエストについて返さなければならないデータの最小量。十分なデータが利用可能では無い場合、リクエストはリクエストに返答する前に多くのデータを集めるのを待つでしょう。デフォルトの設定の1バイトは、データの1バイトが利用可能、あるいはデータの到着を待っているフェッチリクエストがタイムアウトするとすぐにフェッチリクエストに応答することを意味します。これを1より大きいものに設定すると、データの大部分をサーバが待つようになり、ある程度の追加のレイテンシを犠牲にして少しだけサーバのスループットを改善するでしょう。int1[0,...]high
    group.idこのコンシューマが所属するコンシューマグループを識別するユニークな文字列。このプロパティは、もしコンシューマがsubscribe(topic)を使ってグループの管理機能、あるいはKafkaベースのオフセットの管理戦略を使う場合に必須です。文字列""high
    heartbeat.interval.msKafkaのグループ管理機能を使う時に、コンシューマのコーディネータへのハートビート間に期待する時間。ハートビートはコンシューマのセッションが活動中であることを保証し、新しいコンシューマがグループに参加あるいは離れる時のリバランスを円滑にするために使われます。値はsession.timeout.msより小さくなければなりませんが、一般的にはその値の1/3より大きく設定されなければなりません。通常の再バランスについては、期待する時間を制御するために少し小さく調整されるかも知れません。int3000high
    max.partition.fetch.bytesサーバが返すパーティションあたりのデータの最大総量。レコードはコンシューマによってバッチ内で取得されます。取得の最初の空では無いパーティション内の最初のレコードバッチはこの制限よりも大きく、コンシューマが進めることができるようにバッチはまだ返されるでしょう。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。コンシューマのリクエストサイズの制限については、fetch.max.bytes を見てください。int1048576[0,...]high
    session.timeout.msKafkaのグループ管理機能を使う時に、コンシューマの障害を検知するために使われるタイムアウト。コンシューマはその生存をブローカーに示すために定期的なハートビートを送信します。このセッションのタイムアウトが期限切れになる前にハートビートがブローカーによって受け取られない場合は、ブローカーはグループからこのコンシューマを削除しリバランスを初期化するでしょう。値は group.min.session.timeout.msgroup.max.session.timeout.msによって設定されるブローカーの設定内で設定される可能な範囲内でなければならないことに注意してください。int10000high
    ssl.key.passwordキーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。passwordnullhigh
    ssl.keystore.locationキーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。文字列nullhigh
    ssl.keystore.passwordキーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 passwordnullhigh
    ssl.truststore.locationトラストストアーファイルの場所。 文字列nullhigh
    ssl.truststore.passwordトラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。passwordnullhigh
    auto.offset.resetKafkaの初期オフセットが無い場合、あるいは現在のオフセットがサーバ上にもうない場合(例えば、データが削除された)に、何をするか?:
    • earliest: 自動的にオフセットを最も早いものに再設定
    • latest: 自動的にオフセットを最も遅いオフセットに再設定
    • none: コンシューマグループについて以前のオフセットが無い場合はコンシューマに例外を投げる
    • いずれでも無い場合: コンシューマに例外を投げます。
    文字列latest[latest, earliest, none]medium
    connections.max.idle.msこの設定によって指定されるミリ秒後にアイドルの接続を閉じます。long540000medium
    default.api.timeout.msブロックするかもしれないコンシューマAPIについてのタイムアウト(ミリ秒)を指定します。この設定は明示的に timeoutパラメータを受け取らない全てのコンシューマ操作についてのデフォルトのタイムアウトとして使われます。int60000[0,...]medium
    enable.auto.committrueの場合、コンシューマのオフセットはバックグラウンドで定期的にコミットされるでしょう。booleantruemedium
    exclude.internal.topics(オフセットのような)内部トピックからのレコードをコンシューマに公開すべきかどうか。true に設定すると、内部トピックからレコードを受け取る唯一の方法はそれを購読することです。booleantruemedium
    fetch.max.bytesサーバが各フェッチリクエストについて返さなければならないデータの最大量。レコードはコンシューマによってバッチ内で取得されます。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、コンシューマが進めることができるようにレコードのバッチはまだ返されるでしょう。このように、これは絶対的な最大ではありません。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。コンシューマは並行して複数の取得を行うことに注意してください。int52428800[0,...]medium
    isolation.level

    トランザクション的に書き込まれるメッセージをどうやって読むかを制御します。read_committed に設定された場合、consumer.poll() はコミットされたトランザクション的なメッセージのみを返すでしょう。read_uncommitted (デフォルト) に設定された場合、consumer.poll() は破棄されたトランザクション的なメッセージであっても全てのメッセージを返すでしょう。どちらのモードでも非トランザクション的なメッセージは無条件に返されるでしょう。

    メッセージは常にオフセットの順番で返されるでしょう。従って、read_committed モードでは、consumer.poll() は最後の安定したオフセット (LSO) までのメッセージのみを返すでしょう。これは最初に開いたトランザクションのオフセットに他なりません。特に実行中のトランザクションに所属するメッセージの後に現れる全てのメッセージは、関係するトランザクションが完了するまで保留されるでしょう。結果として、read_committed コンシューマは実行中のトランザクションの高いウォーターマークまで読み込むことができないでしょう。

    更に、read_committed では、seekToEnd メソッドはLSOを返すでしょう

    文字列read_uncommitted[read_committed, read_uncommitted]medium
    max.poll.interval.msコンシューマグループ管理を使う時の poll() の起動間の最大の遅延。これはコンシューマがより多くのレコードを取得する前に仕事をしないでいられる総時間に上限を置きます。poll() がこのタイムアウトの期限切れの前に呼ばれなかった場合、コンシューマは失敗したと見なされ、グループはパーティションを他のメンバーに割り当てるためにリバランスするでしょう。 int300000[1,...]medium
    max.poll.recordspoll()への1つの呼び出しで返されるレコードの最大数。int500[1,...]medium
    partition.assignment.strategyグループ管理が使われた場合に、コンシューマの間でパーティションの所有を分散するためにクライアントが使用するパーティション分割ストラテジのクラス名listclass org.apache.kafka.clients.consumer.RangeAssignororg.apache.kafka.common.config.ConfigDef$NonNullValidator@5622fdfmedium
    receive.buffer.bytesデータを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int65536[-1,...]medium
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。int30000[0,...]medium
    sasl.client.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。クラスnullmedium
    sasl.jaas.configJAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*;'。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です;passwordnullmedium
    sasl.kerberos.service.nameKafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。文字列nullmedium
    sasl.login.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandlerクラスnullmedium
    sasl.login.classLoginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLoginクラスnullmedium
    sasl.mechanismクライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。文字列GSSAPImedium
    security.protocolブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。文字列PLAINTEXTmedium
    send.buffer.bytesデータを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int131072[-1,...]medium
    ssl.enabled.protocolsSSL接続のために有効にされるプロトコルのリスト。listTLSv1.2,TLSv1.1,TLSv1medium
    ssl.keystore.typeキーストアファイルのファイル形式。これはクライアントについては任意です。文字列JKSmedium
    ssl.protocolSSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。文字列TLSmedium
    ssl.providerSSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。文字列nullmedium
    ssl.truststore.typeトラストストアファイルのファイル形式。文字列JKSmedium
    auto.commit.interval.msもしenable.auto.committrue に設定されている場合に、コンシューマのオフセットがKafkaに自動コミットされる頻度のミリ秒。int5000[0,...]low
    check.crcs消費されるレコードのCRC32を自動的にチェックする。これにより、通信上あるいはディスク上でメッセージの改竄が無いことを保証します。この調査はいくらかの負荷があるため、極度にパフォーマンスを求めている場合は無効にされているかも知れません。booleantruelow
    client.idリクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。文字列""low
    fetch.max.wait.msすぐに指定されたfetch.min.bytes の要求を満たす十分なデータが無い場合に、サーバがフェッチリクエストに応答する前にブロックする最大の時間。int500[0,...]low
    interceptor.classesインタセプタとして使われるクラスのリスト。org.apache.kafka.clients.consumer.ConsumerInterceptor インタフェースを実装することにより、コンシューマによって受け取られるレコードを捕らえ(そしておそらく変化)することができます。デフォルトでは、インタセプタはありません。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@4883b407low
    metadata.max.age.msパーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。long300000[0,...]low
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""org.apache.kafka.common.config.ConfigDef$NonNullValidator@7d9d1a19low
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]low
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFO[INFO, DEBUG]low
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[0,...]low
    reconnect.backoff.max.ms接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。long1000[0,...]low
    reconnect.backoff.ms指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。long50[0,...]low
    retry.backoff.ms指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。long100[0,...]low
    sasl.kerberos.kinit.cmdKerberos kinit コマンドライン パス。文字列/usr/bin/kinitlow
    sasl.kerberos.min.time.before.reloginリフレッシュ試行間のログインスレッドのスリープ時間。long60000low
    sasl.kerberos.ticket.renew.jitter更新時間に追加されるランダムなジッターのパーセンテージ。double0.05low
    sasl.kerberos.ticket.renew.window.factor最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。double0.8low
    sasl.login.refresh.buffer.seconds証明書をリフレッシュする時に証明書の有効期限を維持するバッファ時間の秒数。If a refresh would otherwise occur closer to expiration than the number of buffer seconds then the refresh will be moved up to maintain as much of the buffer time as possible. 有効な値は0から3600(1時間); 値が指定されない場合はデフォルトの値 300 (5分)が使われます。この値と sasl.login.refresh.min.period.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short300[0,...,3600]low
    sasl.login.refresh.min.period.seconds証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short60[0,...,900]low
    sasl.login.refresh.window.factorログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.8[0.5,...,1.0]low
    sasl.login.refresh.window.jitterログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.05[0.0,...,0.25]low
    ssl.cipher.suitescipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。listnulllow
    ssl.endpoint.identification.algorithmサーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 文字列httpslow
    ssl.keymanager.algorithmSSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。文字列SunX509low
    ssl.secure.random.implementationSSL暗号化操作のために使われる SecureRandom PRNG 実装。 文字列nulllow
    ssl.trustmanager.algorithmSSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。文字列PKIXlow

    3.4.2古いコンシューマの設定

    古いコンシューマの設定の本質的な要素は以下の通りです:
    • group.id
    • zookeeper.connect
    属性 デフォルト 説明
    group.id このコンシューマに所属するコンシューマの処理のグループをユニークに識別する文字列。複数のプロセスに同じグループidを設定することは、それらが全て同じコンシューマグループの一部分であることを示します。
    zookeeper.connect hostname:port の形式でZookeeperの接続文字列を指定します。ここでhostとportはZooKeeperサーバのホストとポートです。Zookeeperのマシーンがダウンしている時に他のZooKeeperノードを経由して接続できるようにするために、hostname1:port1,hostname2:port2,hostname3:port3の形式で複数のホストを指定することもできます。

    サーバはデータをグローバルなZooKeeper名前空間内の何らかのパスの下に置くZooKeeper接続文字列の一部として、ZooKeeperのchrootパスも持つかもしれません。もしそうであればコンシューマは接続文字列の中で同じchrootパスを使う必要があります。例えば、/chroot/path のchrootパスを指定するために、hostname1:port1,hostname2:port2,hostname3:port3/chroot/pathとして接続文字列を指定するでしょう。

    consumer.id null

    設定されていない場合は自動的に生成されます。

    socket.timeout.ms 30 * 1000 ネットワークリクエストのためのソケットタイムアウト。実際のタイムアウトの設定は fetch.wait.max.ms + socket.timeout.ms でしょう。
    socket.receive.buffer.bytes 64 * 1024 ネットワークリクエストのためのソケット受信バッファ
    fetch.message.max.bytes 1024 * 1024 各フェッチリクエストの中で各トピックパーティションについてフェッチしようとするメッセージのバイト数。これらのバイトは各パーティションについてメモリの中に読み込まれるでしょう。つまり、コンシューマによって使われるメモリを制御するのに役立ちます。取得のリクエストサイズは少なくともサーバで可能な最大のメッセージサイズでなければなりません。そうでなければ、プロデューサがコンシューマがフェッチできるより大きなメッセージを送信するかも知れません。
    num.consumer.fetchers 1 データをフェッチするのに使われるfetcherスレッドの数。
    auto.commit.enable true trueの場合、コンシューマによって既にフェッチされたメッセージのオフセットが定期的にZooKeeperにコミットされます。このコミットされたオフセットはプロセスが失敗した時に新しいコンシューマが開始するだろう場所として使われるでしょう。
    auto.commit.interval.ms 60 * 1000 コンシューマのオフセットがzooKeeperにコミットされた頻度のms。
    queued.max.message.chunks 2 消費のためにバッファされるメッセージチャンクの最大数。各チャンクは fetch.message.max.bytes まで大きくなります。
    rebalance.max.retries 4 新しいコンシューマがコンシューマグループに入る時に、コンシューマのセットはパーティションをそれぞれのコンシューマに割り当てるために負荷を "リバランス" しようとします。この割り当てが開始されている間にコンシューマの設定が変更されると、再バランスは失敗し再試行するでしょう。この設定は諦めるまでの最大の試行数を制御します。
    fetch.min.bytes 1 サーバが各フェッチリクエストについて返さなければならないデータの最小量。十分なデータが利用可能では無い場合、リクエストはリクエストに返答する前に多くのデータを集めるのを待つでしょう。
    fetch.wait.max.ms 100 すぐにfetch.min.bytes を満たす十分なデータが無い場合に、サーバがフェッチリクエストに応答する前にブロックする最大の時間。
    rebalance.backoff.ms 2000 再バランス時の再試行の間のバックオフ時間。明示的に設定されない場合、zookeeper.sync.time.ms の値が使われます。
    refresh.leader.backoff.ms 200 パーティションのリーダが行方不明になった時にリーダを決める前に待つバックオフ時間。
    auto.offset.reset largest

    ZooKeeperに初期オフセットが無いか、オフセットが範囲外の場合に、何をするか:
    * smallest : 自動的にオフセットを最小のオフセットに再設定します
    * largest : 自動的にオフセットを最大のオフセットに再設定します
    * それ以外: コンシューマに例外を投げます

    consumer.timeout.ms -1 指定された間隔の後で消費できるメッセージが無い場合は、コンシューマにタイムアウトの例外を投げます
    exclude.internal.topics true (オフセットのような)内部トピックからのメッセージをコンシューマに公開すべきかどうか。
    client.id group id value クライアントidは呼び出しの追跡を手助けするために各リクエストの中で送信されるユーザ定義の文字列です。それはリクエストを生成するアプリケーションを論理的に識別しなければなりません。
    zookeeper.session.timeout.ms  6000 ZooKeeper セッション タイムアウト。もしコンシューマがZooKeeperへのハートビットに失敗した場合、この期間の間deadであると見なされ、再バランスが起こるでしょう。
    zookeeper.connection.timeout.ms 6000 クライアントがzookeeperへの接続を確立する間待つ最大時間。
    zookeeper.sync.time.ms  2000 ZKリーダーからどれだけZKフォロワーが遅れることができるか
    offsets.storage zookeeper どこにオフセットが格納されるべきかを選択します(zookeeperあるいはkafka)。
    offsets.channel.backoff.ms 1000 オフセットチャネルに再接続するか、失敗したオフセットのフェッチ/コミット リクエストを再試行する時のバックオフ期間。
    offsets.channel.socket.timeout.ms 10000 オフセットのフェッチ/コミット リクエストのための応答を読み込む時のソケットタイムアウト。このタイムアウトはオフセットマネージャへのクエリに使われるConsumerMetadataリクエストのためにも使われます。
    offsets.commit.max.retries 5 障害時にこの回数までオフセットのコミットを再試行します。この再試行のカウントはシャットダウン時のオフセットコミットにのみ適用されます。自動コミットスレッドから生成されたコミットへは適用されません。またコミットオフセットの前のオフセット調整のためのクエリの試行へは適用されません。つまり、コンシューマのメタデータ リクエストが何らかの理由で失敗した場合、再試行され、その再試行はこの制限に対してカウントされないでしょう。
    dual.commit.enabled true offsets.storageとして"kafka"を使っている場合は、二つのコミットオフセットを(Kafkaに加えて)ZooKeeperにコミットすることができます。これは、zookeeperに基づいたオフセットストレージからkafkaに基づいたオフセットストレージに移設する時に必要になります。指定されたコンシューマグループについては、(ZooKeeperへ直接の代わりに)グループ内の全てのインスタンスがブローカーにオフセットをコミットする新しいバージョンに移行された後でこれをオフにすると安全です。
    partition.assignment.strategy range

    パーティションをコンシューマのストリームに割り当てるために、"range" あるいは "roundrobin" 戦略から選びます。

    round-robin パーティション アサイナーは全ての利用可能なパーティションと全ての利用可能なコンシューマスレッドを割りつけます。それからパーティションからコンシューマスレッドへの round-robin の割り当てを進めます。a全てのコンシューマのインスタンスの購読が同一の場合、パーティションは均一に分散されるでしょう。(i.e., the partition ownership counts will be within a delta of exactly one across all consumer threads.) ラウンドロビンの割り当ては以下の場合のみ許可されます : (a) 各トピックがコンシューマインスタンス内で同じ数のストリームを持つ (b) グループ内の各コンシューマインスタンスについて購読されたトピックのセットが同じである。

    範囲のパーティションはトピックベースで動作します。各トピックについて、利用可能なパーティションを数字順に、コンシューマのスレッドを辞書順に配置します。それから、各コンシューマに割り当てるパーティションの数を決定するために、パーティションの数をコンシューマ ストリーム(スレッド)の総数で割ります。均等に分割できない場合、最初の幾つかのコンシューマは1つ余分なパーティションを持つでしょう。

    コンシューマの設定に関する詳細は、scala クラス kafka.consumer.ConsumerConfigで見つかるでしょう。

    3.5Kafka 接続設定

    以下はKafka接続フレームワークの設定です。
    名前 説明 種類 デフォルト 有効な値 重要性
    config.storage.topicコネクタの設定が格納されているKafkaトピック名文字列high
    group.idこのワーカーグループが所属する接続クラスタグループを識別するユニークな文字列。文字列high
    key.converterKafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるキーの形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。クラスhigh
    offset.storage.topicコネクタのオフセットが格納されているKafkaトピック名文字列high
    status.storage.topicコネクタとタスクの状態が格納されているKafkaトピック名文字列high
    value.converterKafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれる値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。クラスhigh
    bootstrap.serversKafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,...の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。listlocalhost:9092high
    heartbeat.interval.msKafkaのグループ管理機能を使う時に、コンシューマのグループコーディネータへのハートビート間に期待する時間。ハートビートはワーカーのセッションが活動中であることを保証し、新しいメンバーがグループに参加あるいは離れる時のリバランスを円滑にするために使われます。値はsession.timeout.msより小さくなければなりませんが、一般的にはその値の1/3より大きく設定されなければなりません。通常の再バランスについては、期待する時間を制御するために少し小さく調整されるかも知れません。int3000high
    rebalance.timeout.ms一旦リバランスが開始された後で各ワーカーがグループに入ることができる最大時間。これは基本的に全てのタスクが全ての延期されているデータをフラッシュしオフセットをコミットするのに必要な総時間を制限します。タイムアウトを超えると、ワーカーはグループから削除されるでしょう。これはオフセットのコミットの失敗を起こすでしょう。int60000high
    session.timeout.msワーカーの障害を検知するために使われるタイムアウト。ワーカーはその生存をブローカーに示すために定期的なハートビートを送信します。このセッションのタイムアウトが期限切れになる前にハートビートがブローカーによって受け取られない場合は、ブローカーはグループからこのワーカーを削除しリバランスを初期化するでしょう。値は group.min.session.timeout.msgroup.max.session.timeout.msによって設定されるブローカーの設定内で設定される可能な範囲内でなければならないことに注意してください。int10000high
    ssl.key.passwordキーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。passwordnullhigh
    ssl.keystore.locationキーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。文字列nullhigh
    ssl.keystore.passwordキーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 passwordnullhigh
    ssl.truststore.locationトラストストアーファイルの場所。 文字列nullhigh
    ssl.truststore.passwordトラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。passwordnullhigh
    connections.max.idle.msこの設定によって指定されるミリ秒後にアイドルの接続を閉じます。long540000medium
    receive.buffer.bytesデータを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int32768[0,...]medium
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。int40000[0,...]medium
    sasl.client.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。クラスnullmedium
    sasl.jaas.configJAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*;'。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です;passwordnullmedium
    sasl.kerberos.service.nameKafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。文字列nullmedium
    sasl.login.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandlerクラスnullmedium
    sasl.login.classLoginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLoginクラスnullmedium
    sasl.mechanismクライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。文字列GSSAPImedium
    security.protocolブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。文字列PLAINTEXTmedium
    send.buffer.bytesデータを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int131072[0,...]medium
    ssl.enabled.protocolsSSL接続のために有効にされるプロトコルのリスト。listTLSv1.2,TLSv1.1,TLSv1medium
    ssl.keystore.typeキーストアファイルのファイル形式。これはクライアントについては任意です。文字列JKSmedium
    ssl.protocolSSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。文字列TLSmedium
    ssl.providerSSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。文字列nullmedium
    ssl.truststore.typeトラストストアファイルのファイル形式。文字列JKSmedium
    worker.sync.timeout.msワーカーが他のワーカーとの同期が外れ設定を再同期する必要がある場合、諦め、グループから外れ、再入会する前にバックオフの期間を待つ前に、この時間だけ待ちます。int3000medium
    worker.unsync.backoff.msワーカーが他のワーカーとの同期から外れ、worker.sync.timeout.ms の間に追いつくことに失敗した場合、再び加わる前にこの期間だけコネクトクラスタを離れます。int300000medium
    access.control.allow.methodsAccess-Control-Allow-Methods ヘッダで設定されるクロス オリジン リクエストをサポートするためのメソッドを設定します。Access-Control-Allow-Methods ヘッダのデフォルト値は GET, POST および HEAD のためのクロス オリジン リクエストを許可します。文字列""low
    access.control.allow.originREST APIリクエストのために設定する Access-Control-Allow-Origin ヘッダーの値。クロス オリジン アクセスを有効にするには、これをAPIにアクセスするために許可されなければならないアプリケーションのドメインに設定するか、全てのドメインからのアクセスを許可するために '*' に設定します。デフォルト値はREST APIのドメインからのアクセスのみを許可します。文字列""low
    client.idリクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。文字列""low
    config.providers指定された順番でロードおよびしようされる ConfigProvider クラスのカンマ区切りの名前。インタフェースConfigProviderを実装することで、具体化された秘密鍵のようなコネクタ設定の中の変数参照を置き換えることができます。 list""low
    config.storage.replication.factor設定ストレージトピックを生成する時に使われるレプリケーション ファクターshort3[1,...]low
    header.converterKafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われるHeaderConverterクラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるヘッダ値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。デフォルトでは SimpleHeaderConverter がヘッダ値を文字列にシリアライズ化するために使われ、スキーマを推測することでそれらをデシリアライズ化します。クラスorg.apache.kafka.connect.storage.SimpleHeaderConverterlow
    internal.key.converterKafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるキーの形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。この設定は設定やオフセットのようなフレームワークによって使われる内部的な簿記データによって使われる形式を制御します。つまりユーザは一般的にどのような機能のCコンバーターの実装もつかうことができいます。非推奨; もうすぐやってくるバージョンで削除されるでしょう。クラスorg.apache.kafka.connect.json.JsonConverterlow
    internal.value.converterKafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれる値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。この設定は設定やオフセットのようなフレームワークによって使われる内部的な簿記データによって使われる形式を制御します。つまりユーザは一般的にどのような機能のCコンバーターの実装もつかうことができいます。非推奨; もうすぐやってくるバージョンで削除されるでしょう。クラスorg.apache.kafka.connect.json.JsonConverterlow
    リスナーREST APIがlistenするURIのカンマ区切りのリスト。サポートされるプロトコルは HTTP と HTTPS です。全てのインタフェースにバインドするためには 0.0.0.0 としてホスト名を指定してください。デフォルトのインタフェースにバインドするには、ホスト名を空にします。合法なlistenerのリストの例: HTTP://myhost:8083,HTTPS://myhost:8084listnulllow
    metadata.max.age.msパーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。long300000[0,...]low
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""low
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]low
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFO[INFO, DEBUG]low
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[0,...]low
    offset.flush.interval.msタスクのためのオフセットのコミットを試す間隔。long60000low
    offset.flush.timeout.ms将来の試行でオフセットデータが処理され回復される前に、レコードがフラッシュされパーティションのオフセットデータがオフセットストレージにコミットされる最大のミリ秒数。long5000low
    offset.storage.partitionsオフセット ストレージ トピックを生成する時に使われるパーティションの数int25[1,...]low
    offset.storage.replication.factorオフセットストレージトピックを生成する時に使われるリプリケーション ファクターshort3[1,...]low
    plugin.pathプラグイン (コネクタ、コンバータ、トランスフォーメーション)を含む、カンマ(,) で区切られたパスのリスト。リストは以下の組み合わせを含むトップレベルのディレクトリから成らなければなりません: a) プラグインとそれらの依存を持つjarを直接含むディレクトリ b) プラグインと依存を持つuber-jar c) プラグインとそれらの依存のクラスのパッケージディレクトリ構造を直接含むディレクトリ 注意: 依存あるいはプラグインを見つけるためにsymlinkが続くでしょう。例: plugin.path=/usr/local/share/java,/usr/local/share/kafka/plugins,/opt/connectorslistnulllow
    reconnect.backoff.max.ms接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。long1000[0,...]low
    reconnect.backoff.ms指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。long50[0,...]low
    rest.advertised.host.nameこれが設定されている場合は、これは他のワーカーが接続するように渡されるだろうホスト名です。文字列nulllow
    rest.advertised.listener他のワーカーに使うように渡される通知されたlistener(HTTPあるいはHTTPS)を設定する。文字列nulllow
    rest.advertised.portこれが設定されている場合は、これは他のワーカーが接続するように渡されるだろうポートです。intnulllow
    rest.extension.classes指定された順番でロードおよび呼び出されるConnectRestExtensionクラスのカンマ区切りの名前。インタフェースConnectRestExtensionを実装することで、フィルタのようなユーザ定義のリソースをコネクタのREST APIに差し込むことができます。一般的にログ、セキュリティなどのような独自の機能を追加するために使われます。 list""low
    rest.host.nameREST APIのためのホスト名。設定されている場合は、このインタフェースにのみバインドするでしょう。文字列nulllow
    rest.portREST APIがlistenするポート。int8083low
    retry.backoff.ms指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。long100[0,...]low
    sasl.kerberos.kinit.cmdKerberos kinit コマンドライン パス。文字列/usr/bin/kinitlow
    sasl.kerberos.min.time.before.reloginリフレッシュ試行間のログインスレッドのスリープ時間。long60000low
    sasl.kerberos.ticket.renew.jitter更新時間に追加されるランダムなジッターのパーセンテージ。double0.05low
    sasl.kerberos.ticket.renew.window.factor最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。double0.8low
    sasl.login.refresh.buffer.seconds証明書をリフレッシュする時に証明書の有効期限を維持するバッファ時間の秒数。If a refresh would otherwise occur closer to expiration than the number of buffer seconds then the refresh will be moved up to maintain as much of the buffer time as possible. 有効な値は0から3600(1時間); 値が指定されない場合はデフォルトの値 300 (5分)が使われます。この値と sasl.login.refresh.min.period.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short300[0,...,3600]low
    sasl.login.refresh.min.period.seconds証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short60[0,...,900]low
    sasl.login.refresh.window.factorログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.8[0.5,...,1.0]low
    sasl.login.refresh.window.jitterログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.05[0.0,...,0.25]low
    ssl.cipher.suitescipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。listnulllow
    ssl.client.authクライアント認証をリクエストするためのKafkaブローカーを設定します。以下の設定が一般的です:
    • ssl.client.auth=required required に設定された場合、クライアント認証が必要です。
    • ssl.client.auth=requested これはクライアント認証が任意であることを意味します。requestedと異なり、もしこのオプションが設定された場合、クライアントは自身について認証情報を提供しない事を選択できます。
    • ssl.client.auth=none これはクライアント認証が必要では無いことを意味します。
    文字列nonelow
    ssl.endpoint.identification.algorithmサーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 文字列httpslow
    ssl.keymanager.algorithmSSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。文字列SunX509low
    ssl.secure.random.implementationSSL暗号化操作のために使われる SecureRandom PRNG 実装。 文字列nulllow
    ssl.trustmanager.algorithmSSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。文字列PKIXlow
    status.storage.partitionsステータス ストレージ トピックを生成する時に使われるパーティションの数int5[1,...]low
    status.storage.replication.factorステータスストレージトピックを生成する時に使われるリプリケーション ファクターshort3[1,...]low
    task.shutdown.graceful.timeout.msタスクがgrecefullyにシャットダウンするために待つ時間。これはタスクごとではない総時間です。全てのタスクはシャットダウンを引き起こされ、それからそれらは順番に待ちます。long5000low

    3.6Kafka ストリーム設定

    以下はKafkaストリームのクライアントライブラリの設定です。
    名前 説明 種類 デフォルト 有効な値 重要性
    application.idストリーム処理アプリケーションのための識別子。Kafkaクラスタ内でユニークでなければなりません。1) デフォルトのクライアントidのプリフィックス、2) メンバーシップ管理のためのグループid、3) changelogのトピックのプリフィックス。文字列high
    bootstrap.serversKafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,...の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。listhigh
    replication.factorストリーム処理アプリケーションによって生成されるログトピックとリパーティショントピックの変更のためのリプリケーション要素。int1high
    state.dir状態の格納のためのディレクトリの場所。文字列/tmp/kafka-streamshigh
    cache.max.bytes.buffering全てのスレッドを横断してバッファするために使われるメモリの最大バイト数long10485760[0,...]medium
    client.id内部コンシューマ、プロデューサおよびレストア-コンシューマのクライアントidのために使われる、'-StreamThread--' のパターンを持つIDプリフィックス文字列。文字列""medium
    default.deserialization.exception.handlerorg.apache.kafka.streams.errors.DeserializationExceptionHandler インタフェースを実装する例外処理クラス。クラスorg.apache.kafka.streams.errors.LogAndFailExceptionHandlermedium
    default.key.serde org.apache.kafka.common.serialization.Serdeインタフェースを実装するキーのための デフォルトの Serializer / deserializerクラス。windowed serdeクラスを使う場合、'default.windowed.key.serde.inner' あるいは 'default.windowed.value.serde.inner' を使って org.apache.kafka.common.serialization.Serde インタフェースを実装する内部serderクラスを設定する必要があることに注意してください。クラスorg.apache.kafka.common.serialization.Serdes$ByteArraySerdemedium
    default.production.exception.handlerorg.apache.kafka.streams.errors.ProductionExceptionHandler インタフェースを実装する例外処理クラス。クラスorg.apache.kafka.streams.errors.DefaultProductionExceptionHandlermedium
    default.timestamp.extractororg.apache.kafka.streams.processor.TimestampExtractor インタフェースを実装するデフォルトのタイムスタンプ抽出クラス。クラスorg.apache.kafka.streams.processor.FailOnInvalidTimestampmedium
    default.value.serdeorg.apache.kafka.common.serialization.Serdeインタフェースを実装する値のための デフォルトの Serializer / deserializerクラス。windowed serdeクラスを使う場合、'default.windowed.key.serde.inner' あるいは 'default.windowed.value.serde.inner' を使って org.apache.kafka.common.serialization.Serde インタフェースを実装する内部serderクラスを設定する必要があることに注意してください。クラスorg.apache.kafka.common.serialization.Serdes$ByteArraySerdemedium
    num.standby.replicas各タスクのためのスタンドバイ レプリカの数。int0medium
    num.stream.threadsストリーム処理を実行するためのスレッドの数。int1medium
    processing.guarantee使われるべき処理の保証。可能な値は at_least_once (デフォルト) と exactly_once確実に1回の処理はデフォルトでプロダクションのための設定に推奨される少なくとも3つのブローカーのクラスタを必要とすることに注意してください; 開発のためにブローカーの設定 `transaction.state.log.replication.factor`を調整することでこれを変更することができます。文字列at_least_once[at_least_once, exactly_once]medium
    security.protocolブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。文字列PLAINTEXTmedium
    topology.optimizationトポロジを最適化する必要があるかどうかをKafkaストリームに伝える設定。デフォルトでは無効文字列none[none, all]medium
    application.server1つのKafkaStreams アプリケーションの中のステートストアの場所を見つけるために使うことができる組み込みのユーザ定義のエンドポイントを指すホスト:ポートのペア 文字列""low
    buffered.records.per.partitionパーティションごとのバッファのためのレコードの最大数。int1000low
    commit.interval.msプロセッサーの場所を保存する頻度。(注意、もし 'processing.guarantee' が 'exactly_once' に設定された場合、デフォルトは100、そうでなければデフォルト値は 30000 です。long30000low
    connections.max.idle.msこの設定によって指定されるミリ秒後にアイドルの接続を閉じます。long540000low
    metadata.max.age.msパーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。long300000[0,...]low
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""low
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]low
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFO[INFO, DEBUG]low
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[0,...]low
    partition.grouperorg.apache.kafka.streams.processor.PartitionGrouper インタフェースを実装するパーティショングループクラス。クラスorg.apache.kafka.streams.processor.DefaultPartitionGrouperlow
    poll.ms入力を待つブロックの総時間のミリ秒数。long100low
    receive.buffer.bytesデータを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int32768[0,...]low
    reconnect.backoff.max.ms接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。long1000[0,...]low
    reconnect.backoff.ms指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。long50[0,...]low
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。int40000[0,...]low
    retries0より大きい値を設定すると、クライアントは一時的なエラーによって失敗した全てのリクエストを再送信するでしょう。int0[0,...,2147483647]low
    retry.backoff.ms指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。long100[0,...]low
    rocksdb.config.setterRocks DB 設定セッタークラス、あるいは org.apache.kafka.streams.state.RocksDBConfigSetter インタフェースを実装するクラス名クラスnulllow
    send.buffer.bytesデータを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int131072[0,...]low
    state.cleanup.delay.msパーティションが移行された時の状態を削除する前に待つ総時間のミリ秒数。少なくとも state.cleanup.delay.ms の間修正されていないステート ディレクトリだけが削除されるでしょう。long600000low
    upgrade.from後方互換性のある方法で、バージョン 0.10.0/0.10.1/0.10.2/0.11.0/1.0/1.1 からバージョン 1.2 (あるいはそれより新しい)にアップグレートすることを許可する。1.2 から新しいバージョンにアップグレードする時に、この config.Default を null に指定する必要はありません。受け付けられる値は "0.10.0", "0.10.1", "0.10.2", "0.11.0", "1.0", "1.1" (対応する古いバージョンからのアップグレード)文字列null[null, 0.10.0, 0.10.1, 0.10.2, 0.11.0, 1.0, 1.1]low
    windowstore.changelog.additional.retention.msデータがlogから早まって削除されないことを保証するために、ウィンドウのmaintainMSに追加されます。クロックのズレの許容デフォルトは1日ですlong86400000low

    3.7AdminClient 設定

    以下はKafka Admin クライアント ライブラリの設定です。
    名前 説明 種類 デフォルト 有効な値 重要性
    bootstrap.serversKafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,...の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。listhigh
    ssl.key.passwordキーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。passwordnullhigh
    ssl.keystore.locationキーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。文字列nullhigh
    ssl.keystore.passwordキーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 passwordnullhigh
    ssl.truststore.locationトラストストアーファイルの場所。 文字列nullhigh
    ssl.truststore.passwordトラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。passwordnullhigh
    client.idリクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。文字列""medium
    connections.max.idle.msこの設定によって指定されるミリ秒後にアイドルの接続を閉じます。long300000medium
    receive.buffer.bytesデータを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int65536[-1,...]medium
    request.timeout.msこの設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。int120000[0,...]medium
    sasl.client.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。クラスnullmedium
    sasl.jaas.configJAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*;'。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です;passwordnullmedium
    sasl.kerberos.service.nameKafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。文字列nullmedium
    sasl.login.callback.handler.classAuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandlerクラスnullmedium
    sasl.login.classLoginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLoginクラスnullmedium
    sasl.mechanismクライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。文字列GSSAPImedium
    security.protocolブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。文字列PLAINTEXTmedium
    send.buffer.bytesデータを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。int131072[-1,...]medium
    ssl.enabled.protocolsSSL接続のために有効にされるプロトコルのリスト。listTLSv1.2,TLSv1.1,TLSv1medium
    ssl.keystore.typeキーストアファイルのファイル形式。これはクライアントについては任意です。文字列JKSmedium
    ssl.protocolSSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。文字列TLSmedium
    ssl.providerSSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。文字列nullmedium
    ssl.truststore.typeトラストストアファイルのファイル形式。文字列JKSmedium
    metadata.max.age.msパーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。long300000[0,...]low
    metric.reportersメトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。list""low
    metrics.num.samplesメトリクスを計算するために保持される標本の数。int2[1,...]low
    metrics.recording.levelメトリクスのための最も高い記録レベル。文字列INFO[INFO, DEBUG]low
    metrics.sample.window.msメトリクスの標本が計算されるための時間の窓。long30000[0,...]low
    reconnect.backoff.max.ms接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。long1000[0,...]low
    reconnect.backoff.ms指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。long50[0,...]low
    retries0より大きい値を設定すると、クライアントは一時的なエラーによって失敗した全てのリクエストを再送信するでしょう。int5[0,...]low
    retry.backoff.ms失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。long100[0,...]low
    sasl.kerberos.kinit.cmdKerberos kinit コマンドライン パス。文字列/usr/bin/kinitlow
    sasl.kerberos.min.time.before.reloginリフレッシュ試行間のログインスレッドのスリープ時間。long60000low
    sasl.kerberos.ticket.renew.jitter更新時間に追加されるランダムなジッターのパーセンテージ。double0.05low
    sasl.kerberos.ticket.renew.window.factor最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。double0.8low
    sasl.login.refresh.buffer.seconds証明書をリフレッシュする時に証明書の有効期限を維持するバッファ時間の秒数。If a refresh would otherwise occur closer to expiration than the number of buffer seconds then the refresh will be moved up to maintain as much of the buffer time as possible. 有効な値は0から3600(1時間); 値が指定されない場合はデフォルトの値 300 (5分)が使われます。この値と sasl.login.refresh.min.period.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short300[0,...,3600]low
    sasl.login.refresh.min.period.seconds証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。short60[0,...,900]low
    sasl.login.refresh.window.factorログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.8[0.5,...,1.0]low
    sasl.login.refresh.window.jitterログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。double0.05[0.0,...,0.25]low
    ssl.cipher.suitescipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。listnulllow
    ssl.endpoint.identification.algorithmサーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 文字列httpslow
    ssl.keymanager.algorithmSSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。文字列SunX509low
    ssl.secure.random.implementationSSL暗号化操作のために使われる SecureRandom PRNG 実装。 文字列nulllow
    ssl.trustmanager.algorithmSSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。文字列PKIXlow

    4. 設計

    わたしたちはKafkaを大企業が持つかもしれない全てのリアルタイム データフィードを処理するための統一的なプラットフォームとして振舞うことができるように設計しました。これを行うためにユースケースのかなり大規模なセットを通して考える必要がありました。

    リアルタイムのログの集約のような高ボリュームのイベントストリームをサポートするために高スループットを持つ必要があるでしょう。

    オフラインシステムからの定期的なデータのロードをサポートできるように大規模なデータのバックログを使ってグレースフルに扱う必要があるでしょう。

    それはシステムがもっと伝統的なメッセージングのユースケースを扱うために低レンテンシの配送を扱う必要があることも意味します。

    新しく配送されるフィードを作成するためにそれらのフィードのパーティション、分散、リアルタイム処理をサポートする必要がありました。これがパーティションとコンシューマのモデルをする気にさせました。

    結果的にストリームが提供のために他のデータシステムにフィードされる場合に、システムはマシーンの障害の時に耐障害性を保証することができる必要があるだろうということが分かりました。

    これらの使用をサポートすることで、従来のメッセージングシステムよりデータベースログに近い独自の要素を持つデザインとなりました。以下の章で設計の幾つかの要素の要点を述べるつもりです。

    4.2一貫性

    ファイルシステムを恐れないでください!

    Kafkaはメッセージを格納およびキャッシュするためにファイルシステムに著しく依存します。"ディスクは遅い" という人々が永続的な構造は競争力のあるパフォーマンスを提供することができるということを懐疑的に思わせる一般的な認識があります。実際には、ディスクはどのように使うかによって人々が思うよりかなり遅くなったりかなり速くなったりします; 適切に設計されたディスク構造はしばしばネットワークと同じくらい速くなります。

    ディスクのパフォーマンスについての重要な事実は、ハードディスクのスループットはこの10年間でディスクのシークのレイテンシーとは異なっているということです。結果として、six 7200rpm SATA RAID-5 アレイのJBOD 設定への線形書き込みのパフォーマンスは約 600MB/sec ですが、ランダム書き込みのパフォーマンスは約 100k/sec だけです。- 違いは 6000倍以上です。これらの線形読み込みと書き込みは全ての利用パターンのほとんどと予想可能で、オペレーティングシステムによってすごく最適化されます。現代的なオペレーティングシステムは、大きなブロックの倍数のデータを前もって取得し、小さな論理書き込みを大きな物理書き込みにグループ化する、先行先読みと遅延書き込みの技術を提供します。この問題についての更なる議論はこのACM キューの文章で見つけることができます; ある場合においてはシーケンシャル ディスク アクセスはランダムなメモリアクセスよりも速くなりえます!

    このパフォーマンスの相違を保証するために、現代的なオペレーティングシステムはディスクキャッシュについてのメインメモリの使用にますます積極的になりました。現代的なOSはメモリを取り戻す時に少しのパフォーマンスの罰則を持って喜んで全ての フリーメモリをディスクのキャッシュに転換するでしょう。全てのディスクの読み込みと書き込みはこの統合されたキャッシュを使い果たすでしょう。この機能はダイレクトI/Oを使わない限りは簡単には無効にすることができません。つまりもしプロセスがデータのプロセス内のキャッシュに保持される場合、このデータはおそらく効果的に全てを2度格納しながらOSページキャッシュにデュプリケートされるでしょう。

    更に、私たちはJVMの上に構築しています。Javaのメモリの使い方に時間を費やした人は以下の2つの事を知っています:

    1. オブジェクトのメモリオーバーヘッドは非常に高く、しばしば格納されたデータを2倍(あるいはそれ以上)にします。
    2. Javaのガベージコレクションはヒープ内のデータが増加するに連れて、増加的に扱いづらく遅くなります。

    As a result of these factors using the filesystem and relying on pagecache is superior to maintaining an in-memory cache or other structure—we at least double the available cache by having automatic access to all free memory, and likely double again by storing a compact byte structure rather than individual objects. そうすることで32GB上のマシーンでGCのペナルティ無しに 28-30GB までのキャッシュ内に納まります。さらにこのキャッシュはサービスが再起動した場合でさえも電源が入ったままですが、プロセス内のキャッシュはメモリ内で再構築する必要があります(10GBのキャッシュは10分掛かるかもしれません)あるいは完全に電源が落ちたキャッシュから開始する必要があるでしょう(これは酷い初期パフォーマンスを意味することになりえます)。キャッシュとファイルシステム間のコヒーレントを維持するための全てのロジックが今はOS内にあるため、これはコードを大幅に簡素化します。これは一回限りのプロセス内の試行よりもより効率的でより正しく行う傾向があります。ディスクの使用方法が線形読み込みに向いている場合、先読みは各ディスクの読み込み時に有用なデータを効果的にあらかじめ入力しておきます。

    This suggests a design which is very simple: rather than maintain as much as possible in-memory and flush it all out to the filesystem in a panic when we run out of space, we invert that. 全てのデータは必ずしもディスクへのフラッシュ無しにファイルシステム上の永続ログにすぐに書き込まれます。実際にはこれは単にカーネルのページキャッシュに転送されることを意味します。

    このページキャッシュ中心の設計の方式はVarnishの設計の文章で説明されます (多大なる傲慢さとともに)。

    Constant Time Suffices

    メッセージング システム内で使われる永続データ構造は、しばしばメッセージに関するメタデータを維持するための関連するBTreeあるいは他の一般的な目的のランダムアクセスデータ構造のコンシューマあたりのキューです。BTreeは利用可能な最も融通のきくデータ構造で、メッセージシステム内でトランザクション的あるいは非トランザクション的なセマンティクスの広範囲に及ぶ違いをサポートすることができます。しかしかなりの高コストが付随します: Btree オペレーションは O(log N) です。通常 O(log N) は本質的に一定の時間と等しいですが、これはディスク操作については正しくありません。Disk seeks come at 10 ms a pop, and each disk can do only one seek at a time so parallelism is limited. 従って少量のディスクのシークでさえ高いオーバーヘッドに繋がります。ストレージシステムはとても高速なキャッシュされた操作ととても遅い物理ディスク操作とを混合するため、木構造の観測されるパフォーマンスはデータが固定のキャッシュを使って増加するに従ってしばしば超線形的になります--つまり、データが2倍になると2倍より遅くなります。

    直観的に永続的なキューは1つの読み込み上に構築され、ログの解像度で一般的なようにファイルに追加されるかもしれません。この構造は全てのオペレーションが O(1) であり、読み込みが書き込みあるいはお互いをブロックしないという利点があります。パフォーマンス完全にデータサイズから切り離されるためこれは明らかなパフォーマンスの利点があります - 1つのサーバは今では多くの安い、低レンテンシのスピードの 1+TB SATA ドライバを利用することができます。それらはシークのパフォーマンスが低いですが、これらのドライバは大きな読み込みと書き込みについて許容できるパフォーマンスであり、1/3の値段で、3x の容量です。

    パフォーマンスの犠牲無しに仮想的に無制限のディスク空間へのアクセスはメッセージング システムで通常見られないような幾つかの特徴を提供することができます。例えば、Kafkaではメッセージが消費されるとすぐに削除しようとする代わりに、比較的長い間メッセージを維持することができます(例えば1週間) 。これにより後で説明するようにコンシューマのための大きな柔軟性に繋がります。

    4.3効率

    私たちは多くの努力を効率化に注ぎました。主要なユースケースの1つがwebの動きのデータの処理で、これはとても嵩張るものです: 各ページのビューは何十もの書き込みを生成するかもしれません。更に、発行された各メッセージは少なくとも1つ(しばしば多くの)コンシューマによって読み込まれ、従ってできるだけ手軽に消費しようとします。

    多数の同じようなシステムの構築と実行の経験から、効率化が効率的なマルチ テナント オペレーションのキーであることも知りました。アプリケーションによる使い方の小さな上昇により、もしダウンストリームのインフラストラクチャ サービスが容易にボトルネックになる場合、そのような小さな変更はしばしば問題になるでしょう。By being very fast we help ensure that the application will tip-over under load before the infrastructure. 使い方のパターンの変更が日常的に起こるため、集中化されたクラスタ上での数十あるいは数百のアプリケーションをサポートする集中化されたサービスを実行しようとする時にこれは特に重要です。

    前の章でディスクの効率化について議論しました。一旦貧弱なディスクアクセスパターンが取り除かれると、このタイプのシステムには二つの一般的な非効率の原因があります: あまりに多くの小さな I/O オペレーションと、過度のバイトのコピーです。

    小さなI/Oの問題はクライアントとサーバ間、およびサーバ独自の永続化オペレーションの中で起こります。

    これを避けるために、生まれつきメッセージをグループ化する"メッセージ セット" 抽象化の周りにプロトコルが構築されます。これによりグループメッセージへのネットワークリクエストを1つにすることができ、一度に1つのメッセージを送るのではなくネットワーク周辺のオーバーヘッドを償却します。サーバは次々にログにメッセージのチャンクを追加し、コンシューマは一度に大きな線形のチャンクを取得します。

    この単純な最適化は一桁違う大幅なスピードアップを生成します。バッチは大きなネットワークパケット、大きな連続するディスク操作、連続するメモリブロックなどに繋がります。それら全てによりKafkaは爆発的なランダムなメッセージ書き込みのストリームをコンシューマへ流れる線形の書き込みへ変えることができます。

    もう一つの非効率はバイトのコピーです。低いメッセージレートでは、これは問題ではありませんが、高負荷では影響が大きなものになります。これを避けるためにプロデューサ、ブローカー、コンシューマによって共有される標準化されたバイナリメッセージフォーマットを採用します (つまりデータチャンクはそれらの間で修正されずに転送されます)。

    ブローカーによって維持されるメッセージログはそれ自身は単なるファイルのディレクトリで、それぞれはプロデューサとコンシューマによって使われるのと同じ形式でディスクに書き込まれたメッセージセットの系列があります。この共通のフォーマットを維持することによりほとんどの重要なオペレーションを最適化することができます: 永続的なログのチャックのネットワーク転送。最新のunixオペレーティングシステムはページキャッシュからソケットへの転送のための高度に最適化されたコードパスを提供します; Linuxではこれは sendfile system callを使って行われます。

    sendfileの効果を知るためには、ファイルからソケットへのデータの転送のための共通のデータパスを理解することが重要です:

    1. オペレーティングシステムはデータをディスクからカーネル空間のページキャッシュに読み込む
    2. アプリケーションはデータをカーネル空間からユーザ空間のバッファに読み込む
    3. アプリケーションはデータをソケットバッファのカーネル空間へ書き込む
    4. オペレーティングシステムはデータをソケットバッファからネットワーク上に送信されるNICバッファにコピーする

    これは明らかに非効率です。4つのコピーと2つのシステムコールがあります。sendfileを使い、OSにデータをページキャッシュからネットワークに直接送信できるようにすることで、この再コピーを避けることができます。つまり、この最適化されたパスで、最終的なNICバッファへのコピーだけが必要です。

    一般的なユースケースがトピック上の複数のコンシューマであることを期待します。上のゼロ-コピー最適化を使って、データは読み込まれるたびにメモリに格納しユーザ空間からコピーして取り出す代わりに、確実に1回ページキャッシュにコピーされ、それぞれの消費の度に再利用されます。これによりメッセージはネットワーク接続の制限に近いレートで消費されることができます。

    このpagecacheとsendfileの組み合わせは、コンシューマがほとんど遅れずについていくKafkaクラスタ上では、データを完全にキャッシュから提供するため少しもディスク上の読み込み動作を見ることは無いだろうことを意味します。

    更なるJavaでのsendfileとゼロ-コピーのサポートについては、この文章を見てください。

    End-to-end バッチ圧縮

    ボトルネックが実際にはCPUあるいはディスクでは無いがネットワークの帯域である場合があります。これは広域ネットワークを超えたデータセンター間でメッセージを送信するのに必要なデータパイプラインにとって特に正しいです。もちろんKafkaからの助け無しにユーザは一度に1つのメッセージを常に圧縮することができますが、同じ型のメッセージ間の繰り返しによる相当な冗長性のため、圧縮率が非常に悪くなります (例えば、JSON内のフィールド名あるいはwebログ内のユーザエージェントあるいは共通の文字列の値)。効率的な圧縮には、各メッセージを個別に圧縮するよりも複数のメッセージを一緒に圧縮することが必要です。

    Kafka は効率的なバッチ形式を使ってこれをサポートします。メッセージのバッチは圧縮されてまとめられ、この形式でサーバに送信することができます。このメッセージのバッチは圧縮された形式で書き込まれ、ログ内で圧縮されたままで、コンシューマによってのみ解凍されるでしょう。

    Kafka は GZIP, Snappy および LZ4 圧縮プロトコルをサポートします。圧縮についての詳細は ここで見つけることができます。

    4.4プロデューサ

    ロードバランシング

    プロデューサは仲介するルーティングの層無しにパーティションにとってのリーダーであるブローカーにデータを直接に送信します。プロデューサがこれをするのを助けるために、全てのKafkaのノードはプロデューサが適切にリクエストを指示できるようにどのサーバが生きていてトピックのパーティションのリーダーがどこにあるかを指定した時間でリクエストに答えることができます。

    クライアントはどのパーティションにメッセージを発行するかを制御します。これはある種のランダムなロードバランシングを実装することでランダムに行うか、何らかのセマンティックなパーティション関数を使って行うことができます。We expose the interface for semantic partitioning by allowing the user to specify a key to partition by and using this to hash to a partition (there is also an option to override the partition function if need be). 例えば、もし選択されたキーがユーザidであれば、指定されたユーザについての全てのデータは同じパーティションに送信されるでしょう。これにより次にはコンシューマがそれらの消費についてローカリティの仮説を立てることができます。この形式のパーティション化はコンシューマ内のローカリテイ-センシティブな処理ができるように明示的に設計されます。

    非同期送信

    バッチ処理は効率化の大きな推進要因の1つであり、Kafkaプロデューサのバッチを有効化することでメモリ内でデータを集約し、1つのリクエスト内でより大きなバッチを送出しようとするでしょう。バッチ処理は一定数以下のメッセージを集約し、いくらかの固定のレイテンシの制限(例えば 64k あるいは 10ms)より長く待たないように構成することができます。これによりより多くのバイトの集約を送信することができ、サーバ上ではI/Oオペレーションがより少なくなります。このバッファリングは設定可能で、より良いスループットのために少量の追加のレイテンシをトレードオフする仕組みを提供します。

    設定で詳細に説明され、プロデューサについてのapi はドキュメント内のいたるところで見つけることができます。

    4.5コンシューマ

    Kafkaのコンシューマは、消費したいパーティションに繋がるブローカーへの"fetch" リクエストを発行することで動作します。コンシューマは各リクエストによってログ内のオフセットを指定し、その位置から始まるログのチャックを受け取ります。従ってコンシューマはこの位置について重要な制御を行い、必要であればデータを再消費するために巻き戻すことができます。

    Push vs. pull

    私たちが考慮した最初の問題は、コンシューマがデータをブローカーからpullすべきか、ブローカーがデータをコンシューマにpushすべきかでした。この点で、Kafkaはほとんどのメッセージングシステムで共有される、より伝統的な設計に従います。データはプロデューサからブローカーにpushされ、コンシューマによってブローカーからpullされます。Scribe および Apache Flumeのような幾つかのログ中心のシステムでは、データがダウンストリームにpushされる、とても異なるpushベースのパスに従います。両方のやり方には長所と短所があります。しかし、pushベースのシステムはデータが転送される時のレートをブローカーが制御するので、コンシューマの多様性を扱うのが難しいです。目的は一般的にコンシューマが最大限に可能なレートで消費できることです; 残念ながら、pushシステムでは消費のレートが生成のレートを下回る時(本質的にはサービス拒否アタックです)、このことはコンシューマが圧倒される傾向があることを意味します。pullベースのシステムはコンシューマが単純に後れを取り可能であれば追いつくという良い特性があります。これはコンシューマが圧倒されていることを示すなんらかのバックオフ プロトコルを使って緩和することができますが、コンシューマを完全に使用(しかし、使い過ぎない)するために転送のレートを取得することは思うよりは手の込んだものです。前のこの形式でのシステムの構築の試行により、より伝統的なpullモデルでの連携に導かれました。

    pullベースのシステムのもう一つの利点は、それはコンシューマに送信されるデータの集約的なバッチに役に立つということです。pushベースのシステムは、ダウンストリームのコンシューマがすぐに処理できるかどうかを知らないまま、すぐにリクエストを送信するか、もっとデータを集めそれからそれを送信するかのどちらかを選択しなければなりません。低レンテンシに調整された場合、転送が最後にはどうしてもバッファされるとしても、これは一度に1つのメッセージを送信することになるでしょう。これは無駄です。pullベースの設計はコンシューマが常にログの現在の位置より後(あるいは何らかの設定可能な最大サイズまで)の全ての利用可能なメッセージをpullすることでこれを正します。そして不必要なレイテンシを導入することなく最適なバッチを手にすることができます。

    pullベースのシステムの欠陥は、もしブローカーがデータを持たない場合にコンシューマが短いループで事実上データの到着を忙しく待ってpullすることになるかも知れないということです。これを避けるために、コンシューマのリクエストがデータが到着するまで "長いpoll" の中で待つことを阻止することができるpullリクエスト内のパラメータを持ちます (そして、任意に大きな転送サイズを保証するために指定されたバイト数が利用可能になるまで待ちます)。

    end-to-endのpullだけの他の有り得そうな設計を想像することができるでしょう。プロデューサは局所的にローカルログに書き込み、ブローカーはそれらをpullするコンシューマを使ってpullするでしょう。"store-and-forward" のようなプロデューサがしばしば提案されます。これは興味深いですが、無数のプロデューサがある私たちの目的の使い方にはあまりふさわしくないように思えました。Our experience running persistent data systems at scale led us to feel that involving thousands of disks in the system across many applications would not actually make things more reliable and would be a nightmare to operate. そして実際に、プロデューサの一貫性の必要性無しに大規模なSLAを使ってパイプラインを実行することができることを知りました。

    コンシューマの位置

    何が消費されたかを追跡し続けることは、意外にもメッセージシステムの主要なパフォーマンスの要点の1つです。

    ほとんどのメッセージングシステムはどのメッセージがブローカーで消費されたかについてのメタデータを保持します。つまり、メッセージはコンシューマへ提出され、ブローカーはローカルで即座にその事実を記録あるいはコンシューマからの通知を待つかもしれません。 これはかなり直観的な選択で、実際1つのマシーン上のサーバではこの状態が他のどこへ行くかが明確ではありません。多くのメッセージングシステムでの格納に使われるデータ構造はスケールに乏しいため、これは実用主義でもあります ーブローカーは何が消費されたかを知るため、データサイズが小さいままでそれを即座に削除することができます。

    恐らく明らかでないことは、何が消費されたかについてブローカーとコンシューマが同意に至るまでが些細な問題では無いということです。もしブローカーがネットワーク越しにメッセージが提出されるたびにすぐにメッセージをconsumed として記録すると、もしコンシューマがメッセージの処理に失敗すると(つまり、クラッシュあるいはリクエストのタイムアウトなどなんでも)、メッセージは失われるでしょう。この問題を解決するために、多くのメッセージングシステムはメッセージが送信された時にconsumedではなく単にsent としてマークされることを意味する通知機能を追加します; ブローカーはメッセージを consumedとして記録するためにコンシューマからの特定の通知を待ちます。この戦略はメッセージの喪失の問題を解決しますが新しい問題を起こします。まず最初に、もしコンシューマがメッセージを処理したが通知を送信できる前に失敗した場合、そのメッセージは2度消費されるでしょう。2つ目の問題はパフォーマンス周りです。ブローカーはそれぞれ1つのメッセージについて複数の状態を保持しなければなりません(最初に2度送信されないようにロックし、そして削除できるように恒久的に消費されたとしてマークします)。送信されたが通知されないメッセージをどうするかのような、微妙な問題が扱われなければなりません。

    Kafka はこれをそれぞれに扱います。トピックは全体として並べられたパーティションのセットに分割され、それぞれは確実に1回のコンシューマによって各購買コンシューマグループ内で指定された時に消費されます。このことは各パーティション内のコンシューマの位置は次に消費するメッセージのオフセットである単なる1つの整数であることを意味します。これにより何が消費されたかについての状態は各パーティションごとに1つの数値でとても小さくなります。この状態は定期的にチェックポイントすることができます。これによりメッセージの通知に相当するものはとても安上がりなものになります。

    この決定には副次的な恩恵があります。コンシューマは故意に古いオフセットへrewindし、データを再消費することができます。これはキューの一般的な規約に違反しますが、多くのコンシューマにとって不可欠な機能ということが分かります。例えば、もしコンシューマのコードにバグがあり、いくつかのメッセージが消費された後で発見された場合、バグが修正された後でコンシューマはこれらのメッセージを再消費することができます。

    オフライン データのロード

    スケーラブルな永続性は、Hadoopあるいはリレーショナル データ ウェアハウスのようなオフラインのシステムに、データを定期的にバルクロードするバッチのように定期的に消費するだけのコンシューマの可能性を考慮します。

    Hadoopの場合、ロードの完全な並行化を可能にしてそれぞれのノード/トピック/パーティションの組み合わせについての個々のマップタスクのロードを分割することでデータのロードを並行化します。Hadoopはタスクの管理を提供し、失敗したタスクはデータの重複の危険性無しに再起動することができます - それらは単に元の位置から再起動します。

    4.6メッセージ配送セマンティクス

    プロデューサとコンシューマの働きについて少し理解できたので、Kafkaがプロデューサとコンシューマ間で提供するセマンティックな保証について議論しましょう。提供することができる可能なメッセージ配送の保証は明らかに複数あります:

    • 最大1回—メッセージは紛失するかもしれませんが、決して再配送はされません。
    • 少なくとも1回—メッセージは決して紛失されませんが、再配送されるかもしれません。
    • 確実に1回—これはみんなが本当に欲しいもので、各メッセージは1回だけ配送されます。
    これは2つの問題に分類されることに注目する価値があります: メッセージを発行する際の耐久性の保証と、メッセージを消費する時の保証です。

    多くのシステムは "確実に1回"の配送セマンティクスを提供するように要求します。しかし但し書きを読むことが重要です。それらのほとんどの要求には語弊があります (つまり、それらはコンシューマあるいはプロデューサが失敗する時、複数のコンシューマ処理がある時、あるいはディスクに書き込まれるデータが紛失されるかも知れない時について説明しません)。

    Kafkaのセマンティクスは素直なものです。メッセージを発行する時、ログにメッセージが”コミットされた”ことの記録を持ちます。発行されたメッセージがコミットされると、このメッセージが書き込まれたパーティションをリプリケートする1つのブローカーが "alive" である限り紛失されないでしょう。コミットされたメッセージの定義、aliveパーティション、私たちが処理しようとしている種類の障害の説明については、次の章で詳細に説明されるでしょう。今のところは、完全、紛失無しのブローカーを仮定し、プロデューサとコンシューマについての保証を理解しましょう。Fもしプロデューサがメッセージを発行しようとしてネットワークのエラーに遭遇した場合、もしこのエラーがメッセージが発行された前後で発生すると、確実ではありません。これは自動生成されたキーを持つデータベーステーブルへの挿入のセマンティクスに似ています。

    0.11.0.0 より前は、もしプロデューサがメッセージがコミットされたことを示す応答の受信に失敗した場合、メッセージを再送するというちょっとした選択がありました。元のリクエストが実際には成功していた場合再送の間にメッセージがログに再び書き込まれるかも知れないため、これは少なくとも1回の配送セマンティクスを提供します。0.11.0.0 からはKafkaのプロデューサは再送がログ内の重複エントリに結果的にならないように保証する等冪配送オプションもサポートします。これを行うために、ブローカーは各プロデューサにIDを割り当て、各メッセージと共にプロデューサによって送信されるシーケンス番号を使ってメッセージを1つにします。また 0.11.0.0から、プロデューサはトランザクションのようなセマンティクスを使って複数のトピックパーティションにメッセージを送信する機能をサポートします: つまり、全てのメッセージは完全に書き込まれるか、何も書き込まれないか、のどちらかです。これの主要な利用法はKafkaトピック間の確実に1回の処理です (以下で説明されます)。

    全ての利用法でそのような強い保証が必要なわけではありません。レンテンシーを気にするユーザについては、プロデューサが望ましいレベルの持続性を指定することができます。プロデューサがメッセージがコミットされる時に待ちたいことを指定する場合、これは10ミリ秒程度掛かるかもしれません。しかし、プロデューサは、完全に同期して送信をしたい、あるいはリーダー(必ずしもフォロワーではない)がメッセージを受け取るまでのみ待ちたいということも指定することができます。

    ではコンシューマの視点からのセマンティクスを説明しましょう。全てのレプリカは同じオフセットを使って確実に同じログを持ちます。コンシューマはログ内のその位置を制御します。もしコンシューマが停止しなければ、メモリ内にこの位置を格納するだけです。しかしもしコンシューマが故障し、このトピックパーティションを他のプロセスに交代したい場合は、新しい処理は処理を開始する適切な位置を選択する必要があります。例えば、コンシューマが何らかのメッセージを読むとした場合 -- メッセージを処理しその位置を更新するには幾つかのオプションがあります。

    1. メッセージを読み、ログ内に位置を保存し、最後にメッセージを処理することができます。この場合、位置を保存した後だがそのメッセージの処理の出力を保存する前にコンシューマの処理が停止する可能性があります。この場合、処理を引き継いだプロセスは、その位置より前の2,3のメッセージが処理されなかったとしても、保存された位置から開始するでしょう。この場合コンシューマの不足したメッセージは処理されないかも知れないので、これは"最大1回"のセマンティクスに対応します。
    2. メッセージを読み込み、メッセージを処理し、最後にその位置を保存することができます。この場合、メッセージの処理の後だがその位置を保存する前にコンシューマのプロセスが停止する可能性があります。この場合、新しいプロセスが引き継いだ時に、受信する最初の2,3のメッセージがすでに処理されているでしょう。コンシューマの不足の場合"少なくとも1回"のセマンティクスに対応します。多くの場合においてメッセージはプライマリキーを持ち、そのため更新は等冪です (同じメッセージを2度受信すると、それ自身の他のコピーを使って単純にレコードを上書きします)。

    それで、確実に1回のセマンティクスとは何でしょうか (言い換えると、あなたが本当に欲しいもの)?Kafkaトピックからの消費と他のトピックへの生成(Kafka Streams アプリケーション)時に、上で述べたような 0.11.0.0 での新しいトランザクションのプロデューサ機能を利用することができます。コンシューマの位置はトピック内でメッセージとして格納されるため、処理されたデータを受信する出力トピックとして同じトランザクション内のKafkaへのオフセットを書くことができます。もしトランザクションが中断された場合、コンシューマの位置はそれの古い値に戻され、出力トピック上の生成されたデータは"隔離レベル"に応じて他のコンシューマに見えなくなるでしょう。デフォルトの"read_uncommitted" 隔離レベルでは、全てのメッセージはたとえそれらが中断されたトランザクションであってもコンシューマに見えますが、"read_committed"では、コンシューマはコミットされた(そしてトランザクションの一部ではない全てのメッセージ)トランザクションからのメッセージのみを返すでしょう。

    When writing to an external system, the limitation is in the need to coordinate the consumer's position with what is actually stored as output. これを行う伝統的な方法は、コンシューマの位置の格納とコンシューマの出力の格納との間の2つのフェーズのコミットを導入することでしょう。しかし、これはコンシューマに出力と同じように同じ場所にオフセットを格納させることで、より簡単に一般的に処理することができます。コンシューマが書き込みたい多くの出力システムでは2フェーズのコミットをサポートしないため、これはより良いでしょう。この例として、データとオフセットの両方が更新されるか、あるいはどちらも更新されないことを保証するために、読み込んだデータのオフセットと共にHDFSのデータを取り込むKafka Connectを考えてみましょう。We follow similar patterns for many other data systems which require these stronger semantics and for which the messages do not have a primary key to allow for deduplication.

    つまりKafkaはKafka Streamsの中で確実に1回の配送を効果的にサポートし、Kafkaトピック間でデータを転送および処理する時に確実に1回の配送を提供するためにトランザクションのプロデューサ/コンシューマを一般的に使うことができます。他の宛先のシステムのための確実に1回の配送は一般的にそのようなシステムとの協力を必要としますが、Kafkaはこれを実装することを便利にするオフセットを提供します (Kafka Connectも見てください)。それ以外の場合、Kafkaはデフォルトで少なくとも1回の配送を保証し、プロデューサ上での再試行を無効にしてメッセージのバッチを処理する前にコンシューマ内のオフセットをコミットすることでユーザは最大で1回の配送を実装することができます。

    4.7リプリケーション

    Kafkaは各トピックのパーティションについて設定可能な数のサーバに渡ってログをリプリケートします (このレプリケーションのファクタをトピック毎に基づいて設定することができます)。これによりクラスタ内のサーバに障害が発生した場合にこれらのレプリカに自動的にフェールオーバーすることができ、障害時にメッセージが利用可能になります。

    Other messaging systems provide some replication-related features, but, in our (totally biased) opinion, this appears to be a tacked-on thing, not heavily used, and with large downsides: slaves are inactive, throughput is heavily impacted, it requires fiddly manual configuration, etc. Kafkaはデフォルトでレプリケーションと一緒に使われることになっています - 実際私たちはリプリケーションされていないトピックをリプリケーション要素が1のリプリケートされたトピックとして実装します。

    リプリケーションの単位はトピックのパーティションです。障害が無い状況では、Kafka内の各パーティションは1つのリーダと0以上のフォロワーを持ちます。リーダーを含むレプリカの総数はレプリケーション要素を構築します。全ての読み込みおよび書き込みはパーティションのリーダーに行きます。一般的に、ブローカーよりも多くのパーティションがあり、リーダーは結果的にブローカー間に分散されます。フォロワーのログはリーダーのログと同じです — 全て同じ順番で同じオフセットとメッセージを持ちます (しかしもちろんいつでもリーダーはログの最後にまだリプリケートされていない少しのメッセージを持つかもしれません)。

    フォロワーはリーダーからのメッセージを通常のKafkaコンシューマがするように消費し、それらを自身のログに適用します。フォロワーをリーダーからpullすることは、フォロワーがログに適用するログエントリを自然に一括してバッチ処理することをできる素晴らしい機能を持ちます。

    ほとんどの分散システムと同様に、自動的な障害の処理にはノードが "alive" ということは何なのかを正確に定義する必要があります。Kafkaのノードの生存には2つの条件があります

    1. ノードはZooKeeperを使ってセッションを維持できなければなりません (ZooKeeperのハートビート機構)
    2. スレーブであれば、リーダーに起きた書き込みをレプリケートしなければならず、"あまりに遅れて"はなりません
    "alive" あるいは "failed"の曖昧さを避けるために、この2つの条件を満たすノードを "in sync" と呼びます。リーダーは"同期" ノードのセットを追跡します。もしフォロワーが死亡、立ち往生、あるいは脱落すると、リーダーはそれを同期レプリカのリストから削除するでしょう。立ち往生、レプリカの遅れの決定は replica.lag.time.max.ms 設定によって制御されます。

    分散システムの用語では、ノードが突然動作を停止しその後回復(おそらくそれらが死んだことを知ること無しに)する障害の "fail/recover" モデルのみを扱おうとします。Kafkaはノードが任意あるいは悪意のある応答(おそらくバグあるいは不正な操作による)による所謂 "Byzantine" 障害は扱いません。

    パーティションについての全ての同期レプリカがメッセージをログに適用した時に、メッセージがコミットされたと見なすと、より明確に定義することができます。今までコミットされたメッセージだけがコンシューマに配布されなければなりません。このことはリーダーが失敗した時に紛失されるかも知れないメッセージを一時的に見ることについて、コンシューマが心配する必要がないことを意味します。逆にプロデューサは、レイテンシと持続性の間のトレードオフについての選択に応じて、メッセージがコミットされるのを待つかそうでないかのどちらかの選択肢を持ちます。この特徴はプロデューサが使用するack設定によって制御されます。メッセージが完全な同期レプリカセットに書き込まれたことの通知をプロデューサが要求する時にチェックされる、in-syncレプリカの "最小数" の設定をトピックが持つことに注意してください。あまり厳しくない通知がプロデューサによって要求される場合、in-syncレプリカがその最小数よりも少なくてもメッセージをコミットし消費することができます (例えば、リーダーと同じだけ少ないかもしれません)。

    Kafkaが提供する保証は、常に同期レプリカのうちの少なくとも1つが有効である限り、コミットされたメッセージが喪失されないだろうことです。

    Kafkaは短時間のフェイルオーバー期間の後でノード障害時に利用可能でいますが、ネットワークの分割の場合には利用可能では無いかもしれません。

    レプリケートされたログ: Quorums, ISRs および State Machines (Oh my!)

    Kakfaパーティションの核心はレプリケートされたログです。レプリケートされたログは分散データシステムでの最も基本的なプリミティブの1つですが、それを実装するには多くのやり方があります。リプリケートされたログは他のシステムによって state-machine styleの他の分散システムを実装するためのプリミティブとして使うことができます。

    A replicated log models the process of coming into consensus on the order of a series of values (generally numbering the log entries 0, 1, 2, ...). これを実装するには多くの方法がありますが、最も簡単で速い方法はそれが提供される値の順番を選択するリーダーを使うことです。リーダーが有効である限りは、全てのフォロワーはリーダーが選択した値と順番をコピーする必要があります。

    もちろん、もしリーダーが失敗しなかった場合は、フォロワーを必要としなかったでしょう!リーダーが死亡した場合、フォロワーの中から新しいリーダーを選択する必要があります。しかしフォロワー自身は遅延するか、クラッシュするかもしれません。つまり最新のフォロワーを選択しなければなりません:ログのリプリケーション アルゴリズムが提供しなければならない基本的な保証は、もしメッセージがコミットされたとクライアントに知らせて、リーダーが失敗した場合、選択した新しいリーダーもそのメッセージを受け取らなければならないということです。これはトレードオフをもたらします: もしメッセージがコミットされたことを申告するより前に、より多くのフォロワーがメッセージを応答するのをリーダーが待つ場合、一時的に選択可能なリーダーがより多くいるでしょう。

    必要とされる通知の数と、重複が保証されるようにリーダーを選出するために比較されなければならないログの数をせんたくする場合、これは定足数と呼ばれます。

    このトレードオフの一般的なやり方は、コミットの決定とリーダー選択の両方について多数決を使うことです。これはKafkaが行うものとは違いますが、トレードオフを理解するためにとにかく調べてみましょう。2f+1 のレプリカがあるとします。リーダーによってコミットが宣言される前に f+1 のレプリカが受信しなければならない場合、そして少なくとも f+1 のレプリカから最も完了したログを持ち、f未満の障害のフォロワーを選択することで新しいリーダーが選出された場合、リーダーは全てのコミットされたメッセージを持つことが保証されます。これはf+1 のレプリカの中で、全てのコミットされたメッセージを含む少なくとも1つのレプリカがある筈だからです。そのレプリカのログは最も完了して、下が立って新しいリーダーとして選択されるでしょう。各アルゴリズムが処理しなければならない(たとえばログをより完全にする、リーダーの障害時のログの一貫性の保証、あるいはレプリカセット内のサーバセットの変更を正確に定義する)詳細はたくさんありますが、今はそれらを無視します。

    この多数決のやり方はとても良い特性を持ちます: レイテンシは最も速いサーバのみに依存します。つまり、もしレプリケーションの要素が3つであれば、レイテンシは遅いサーバでは無く最も速いスレーブによって決定されます。

    ZooKeeperの Zab, Raft および Viewstamped Replication を含む数多くのこの類のアルゴリズムがあります。Kafkaの実際の実装で意識した最も類似した学術的な発表はMicrosoftの PacificA です。

    The downside of majority vote is that it doesn't take many failures to leave you with no electable leaders. 1つの障害を耐えるには3つのデータのコピーが必要で、2つの障害を耐えるには5つのデータのコピーが必要です。経験上、実際のシステムにおいて1つの障害に耐えるのに十分な冗長性を持つだけでは十分ではありませんが、5倍のディスク容量と5分の1のスループットで5回の書き込みを実行することは大量のデータ問題に対してはあまり実用的ではありません。これはおそらく定足数アルゴリズムがZooKeeperのような共有クラスタ構成でよく一般的に見かけられる理由ですが、一次データストレージではあまり一般的ではありません。例えばHDFSでは名前ノードの高可用性機能が多数決ベースのジャーナル上に構築されますが、この効果なやり方はデータ自身には使われません。

    Kafkaは定員数のセットを選択するために少し異なるやり方をします。多数決の代わりに、Kafkaは動的にリーダについていく同期レプリカ(ISR)のセットを整備します。このセットのメンバーだけがリーダーとして選出の資格があります。Kafkaのパーティションへの書き込みは、全ての 同期レプリカが書き込みを受け取るまで、コミットされたと見なされません。このISRセットは変更時に常にZooKeeperに存続します。これにより、ISR内の全てのレプリカは選出されたリーダーになる資格があります。多くのパーティションがありリーダーシップのバランスが重要な場合は、Kafkaの利用モデルにとってこれは重要な要素です。このISRモデルとf+1 レプリカを使って、Kafkaのトピックはコミットされたメッセージの喪失無しに f 個の障害に耐えることができます。

    扱いたいほとんどの利用法において、このトレードオフを無理のないものと考えます。実際には、f個の障害を耐えるために、多数決とISRのやり方の両方はメッセージをコミットする前に通知をするために同じ数のレプリカを待つでしょう (例えば、1つの障害を切り抜けるには、多数決の定足数は3つのレプリカと1つの通知を必要とし、ISRのやり方は2つのレプリカと1つの通知を必要とします)。最も遅いサーバ無しにコミットする機能は、多数決のやり方で利点があります。However, we think it is ameliorated by allowing the client to choose whether they block on the message commit or not, and the additional throughput and disk space due to the lower required replication factor is worth it.

    もう一つの重要な設計の違いは、Kafkaはクラッシュしたノードが全てのデータをそのまま回復することを必要としないことです。It is not uncommon for replication algorithms in this space to depend on the existence of "stable storage" that cannot be lost in any failure-recovery scenario without potential consistency violations. この仮定には2つの重要な問題があります。まず、ディスクのエラーは永続的なデータシステムの現実の操作において見た中で最も一般的な問題であり、それらはしばしばデータを損なうということです。次に、これは問題では無いとしても、fsyncは2から3桁のパフォーマンスの低下を起こすかもしれないため、一貫性の保証のために各書き込みにfsyncの使用を必要としたくありません。レプリカがISRを再結合することができる私たちのプロトコルは、再結合の前にたとえクラッシュ時のフラッシュしていないデータを紛失したとしても完全に再び再syncしなければならないことを保証します。

    不透明なリーダー選出: 全て死んだ場合にどうなるか?

    同期中である少なくとも1つのレプリカでのデータの喪失についてのKafkaの保証は予想されていることに注意してください。もしパーティションをレプリケートしている全てのノードが死亡した場合、この保証はもう保持されません。

    しかし、全てのレプリカが死亡する時に、実際のシステムは何かをする必要があります。これが起きてしまうような不運な場合何が起きるかを考慮することは重要です。実装されているかもしれない2つの挙動があります:

    1. ISR内のレプリカを復活するのを待ち、このレプリカをリーダーとして選択する(できれば、それはまだ全てのデータを持っています)。
    2. 復活する最初のレプリカ(ISR内である必要はありません)をリーダーとして選択する。

    これは可用性と一貫性の単純なトレードオフです。もしISRの中のレプリカを待つのであれば、それらのレプリカがダウンする間利用不可能なままになるでしょう。もしそのようなレプリカが破壊されるかそれらのデータが紛失された場合、恒久的にダウンします。一方で、もし非同期のレプリカが復活しそれをリーダーにすることができれば、全てのコミットされたメッセージを持っている保証がないとしてもそのログが事実となるでしょう。バージョン 0.11.0.0からデフォルトでKafkaは最初の戦略を選択し、一貫性のあるレプリカを待つことを好みます。使用可能時間が一貫性より好ましい場合のユースケースをサポートするために、この挙動は unclean.leader.election.enable プロパティの設定を使って変更することができます。

    このジレンマはKafkaに限ったものではありません。どのような定員ベースのスキーマに存在します。例えば、多数決のスキーマにおいて、もしサーバの大多数が恒久的な障害を受けた場合は、データの100%を失うか、新しい事実として既存のサーバ上に残っているものを取り出すことで一貫性を乱すかを選択する必要があります。

    可用性と持続性の保証

    Kafkaに書き込む場合、プロデューサは 0,1 あるいは all (-1) のレプリカによって通知されるメッセージを待つかどうかを選択することができます。"全てのレプリカから通知" は割り当てられたレプリカ全部のセットがメッセージを受け取る保証をするものでは無いことに注意してください。デフォルトでは、acks=allの時に、全ての現在の同期レプリカがメッセージを受け取るとすぐに通知が起きます。例えば、もしトピックが2つのレプリカで構成され、1つが失敗した場合 (つまり、1つの同期レプリカだけが残る)、acks=all を指定した書き込みだけが成功するでしょう。しかし、もし残っているレプリカも失敗した場合は、これらの書き込みは喪失されるかもしれません。これはパーティションの最大の可用性を保証しますが、この挙動は可用性より持続性を望むユーザには望ましくないかもしれません。従って、メッセージの可用性より持続性を好むユーザが使うことができる2つのトピックレベルの設定を提供します。
    1. 汚れたリーダーの選出を無効化 - もし全てのレプリカが利用不可になった場合、ほとんどの最新のリーダー再び利用可能になるまでパーティションは利用不可のままになるでしょう。これはメッセージの喪失のリスクより利用不可を事実上好みます。説明は前の章の汚れたリーダー選出を見てください。
    2. 最小のISRのサイズを指定します - 1つのレプリカへ書き込まれるメッセージの喪失を避けるために、ISRのサイズがこの最小より大きい場合のみパーティションは書き込みを受け付けるでしょう。その後利用不可になります。プロデューサが acks=all を使う場合にのみこの設定は有効で、メッセージが少なくともこれだけの同期レプリカによってメッセージが通知されるだろうことを保証します。この設定は一貫性と可用性のトレードオフを提供します。メッセージが喪失される可能性を減らすためにより多くのレプリカにメッセージが書き込まれることが保証されるため、最小ISRサイズを大きくすると、一貫性が良くなります。しかし、同期レプリカの数が最小の閾値より少ない場合、パーティションが書き込みに利用できないため、可用性が下がります。

    レプリカの管理

    レプリケートされたログについての上の議論は、実際には1つのログのみ、つまり1つのトピックのパーティションを対象とします。しかし、Kafkaクラスタは数十万のこれらのパーティションを管理するでしょう。少ない数のノード上で高ボリュームのトピックのために全てのパーティションをクラスタリングすることを避けるためにラウンドロビン形式のクラスタ内でパーティションをバランスしてみます。同様にパーティションに比例した占有のために各ノードがリーダーとなるように、リーダーシップをバランスしてみます。

    It is also important to optimize the leadership election process as that is the critical window of unavailability. リーダー選出のネィティブな実装は、ノードが失敗した時にノードがホストしている全てのパーティションについてパーティション毎に選択を実行することになります。代わりにブローカーの1つを "controller" として選出します。このコントローラはブローカーレベルで障害を検知し、障害が起きたブローカー内の影響を受けた全てのパーティションのリーダーを変更する責任があります。その結果、必要なリーダーシップ変更の通知をまとめてバッチ処理することができるため、多数のパーティションについて選出のプロセスをはるかに安価で高速にすることができます。コントローラが失敗すると、生き残ったブローカーの1つが新しいコントローラになるでしょう。

    4.8ログの圧縮

    ログの圧縮は、Kafkaが常に1つのトピックパーティションのデータのログ内で各メッセージキーの値について少なくとも最後に知られている値を維持するでしょう。それは、アプリケーションのクラッシュあるいはシステム障害、またはアプリケーションがオペレーション的なメンテナンスの間に再起動した後でキャッシュをリロードするような、ユースケースやシナリオに取り組みます。これらの利用法についてもっと詳しく分け入り、圧縮がどのように動くかを説明します。

    これまで、ある期間の後あるいはなんらかの事前決定されたサイズにログが達した時に廃棄される古いログデータの単純なデータの維持についてのみ説明してきました。これは各レコードが独立しているログのような一時的なイベントデータについては良く動作します。しかしデータストリームの重要なクラスはキー付け、ミュータブルなデータ(例えば、データベースのテーブルへの変更)への変更のログです。

    そのようなストリームについての具体的な例を議論しましょう。ユーザのメールアドレスを含むトピックがあるとします; ユーザがメールアドレスを更新するたびにプライマリーキーとしてユーザidを使ってこのトピックにメッセージを送信します。id 123のユーザについて以下のメッセージを長い期間の後に送信するとします。各メッセージはメールアドレスについての変更に対応します (他のidについてのメッセージは省略されます):

            123 => bill@microsoft.com
                    .
                    .
                    .
            123 => bill@gatesfoundation.org
                    .
                    .
                    .
            123 => bill@gmail.com
        
    ログ圧縮により、各プライマリキー(例えば bill@gmail.com) についての最後の更新だけでも維持をする保証ができるように、もっと細かい保持メカニズムを与えます。こうすることでログが最近変更されたキーについてのみではなく各キーについて最終的な値の完全なスナップショットを含むことを保証します。このことは全ての変更の完全なログを維持することなくダウンストリームのコンシューマがこのトピックから独自の状態を回復することができることを意味します。

    これが有用な2,3の利用法を見ることから始め、それがどのように使われるかを見てみましょう。

    1. データベースの変更の購読。しばしば複数のデータシステムにデータセットを持つことが必要になります。そしてしばしばそれらのシステムのうちの1つはなんらかのデータベースです (RDBMSあるいはおそらく新しい価値のあるキー-値ストア)。例えば、データベース、キャッシュ、検索クラスタおよびHadoopクラスタを持つかもしれません。データベースへの各変更はキャッシュ、検索クラスタ、最終的にHadoopに反映される必要があるでしょう。リアルタイムの更新のみを処理する場合は、最新のログだけが必要です。しかし、キャッシュを再読み込み、あるいは障害を起こした検索ノードを回復したい場合は、完全なデータセットが必要かもしれません。
    2. イベント ソース。This is a style of application design which co-locates query processing with application design and uses a log of changes as the primary store for the application.
    3. 高可用性のためのジャーナリング。A process that does local computation can be made fault-tolerant by logging out changes that it makes to its local state so another process can reload these changes and carry on if it should fail. これの具体的な例は、カウントの処理、集約、ストリームクエリシステムでの別の"group by"のような処理です。リアルタイム ストリーム処理フレームのSamzaはまさにこの目的でこの機能を使います
    これらの各ケースでは、主に変更のリアルタイム フィードを処理する必要がありますが、時にはマシンがクラッシュあるいはデータが再ロードあるいは再処理する必要がある場合には完全なロードをする必要があります。ログの圧縮によりこれらの両方のユースケースを同じ保証トピックから情報を得ることができます。ログの使い方のこの形式はこのブログ投稿の中で更に詳しく説明されます。

    全体的な考えはとても単純です。もし無限のログを保有し、上の場合の各変更を記録した場合、最初に開始された時から各時間においてシステムの状態を獲得していたでしょう。この完全なログを使って、ログ内の最初のNレコードを再生することで時間内の任意の場所へ回復することができるでしょう。この仮説的な完全なログは、安定したデータセットであってもログが無限に成長するため1つのレコードを何度も更新するシステムにとってはあまり実用的ではありません。The simple log retention mechanism which throws away old updates will bound space but the log is no longer a way to restore the current state—now restoring from the beginning of the log no longer recreates the current state as old updates may not be captured at all.

    ログの圧縮は、荒い粒度の時間ベースの保存というより、細かい粒度のレコード単位の保存を行うための仕組みです。同じプライマリキーを持つ、より最近の更新を持つレコードを選択的に削除するという考えです。このやり方でログは各キーについて少なくとも最後の状態を持つことを保証されます。

    この保存ポリシーはトピック毎に設定することができるため、1つのクラスタは保持がサイズあるいは時間によって強制される幾つかのトピックと、保持が圧縮によって強制される他のトピックを持つことができます。

    この機能はLinkdInの最も古く最も成功したインフラストラクチャのうちの1つから着想を得ています -- Databusと呼ばれるデータベース変更ログキャッシングサービス。ほとんどのログ構造のストレージシステムと異なり、Kafkaは購読のために構築され、速い線形読み込みおよび書き込みのためにデータを管理します。Databusと異なり、Kafkaは信頼できる情報源のストアとして振舞うため、上流のデータソースが再生可能では無い場合でも役に立ちます。

    ログの圧縮の基本

    各メッセージについてのオフセットを持つKafkaのログの論理的な構造を表す高レベルな図です。

    ログの先頭は伝統的なKafkaログと同じです。密度、連続するオフセットを持ち、全てのメッセージを保持します。ログの圧縮はログのtailの処理についての選択肢を追加します。上の図は圧縮されたtailのログを示します。ログの最後にあるメッセージは、それらが最初に書き込まれた時に割り当てられた元のオフセットを保持することに注意してください -- それは変更されません。また全てのオフセットはそのオフセットを含むメッセージが圧縮されていたとしても、ログ内での有効な位置のままです; この場合この位置はログに現れる次に高いオフセットと区別することができません。例えば上の図では、オフセット 36, 37 と 38 は全て等価な位置であり、これらのオフセットのいずれかで始まる読み込みは38で始まるメッセージ セットを返します。

    圧縮は削除することもできます。キーと空の荷物を持つメッセージはログからの削除として扱われるでしょう。このdeleteマーカーにより、そのキーを持つ以前のメッセージは(そのキーを持つ新しいメッセージと同じように)削除されますが、deleteマーカーは領域を解放するために一定時間が経過した後でログから自身が削除されるという点で特別なものです。deleteがもう維持されない時点は、上の図で"delete retention point"としてマークされています。

    定期的にログのセグメントを再コピーすることで、バックグラウンドで圧縮が行われます。クリーニングは読み取りをブロックせず、プロデューサとコンシューマに影響を与えることを避けるために設定可能なI/Oスループットの量を超えずに使うように絞ることができます。ログ セグメントの圧縮の実際のプロセスは以下のようなものに見えます:

    ログの圧縮は何を提供しますか?

    ログの圧縮は以下のものをていきょうします:
    1. ログの先頭に追いついているコンシューマは書き込まれた全てのメッセージを見るでしょう; これらのメッセージは連続するオフセットを持つでしょう。トピックのmin.compaction.lag.ms は圧縮される前に書き込まれるメッセージの後で経過しなければならない最小の長さを保証するために使われます。つまり、各メッセージが(非圧縮の)head内に存在するだろう長さの低い方の境界を提供します。
    2. メッセージの順番は常に維持されます。圧縮はメッセージの順番を並び変えることはせず、単に幾つかを削除するでしょう。
    3. メッセージについてのオフセットは変わりません。それはログ内の位置についての恒久的な識別子です。
    4. ログの最初から進んでいるコンシューマは書き込まれた順番で全てのレコードの少なくとも最終的な状態を見るでしょう。さらに、コンシューマがトピックのdelete.retention.ms設定(デフォルトは24時間)より少ない時間でログの先頭に到達した場合、削除されたレコードについての全てのdeleteマーカーが表示されます。別の言い方をすると: deleteマーカーの削除は読み込みと同時に起こるため、もし遅れがdelete.retention.msより大きい場合はコンシューマはdeleteマーカーを紛失するかもしれません。

    ログの圧縮の詳細

    ログの圧縮は、ログクリーナー、ログのセグメントファイルを再コピーするバックグラウンドのスレッドのプール、ログの最初に現れるキーのレコードの削除によって処理されます。各コンパクタースレッドは以下のように動作します:
    1. ログのtailのログの頭の一番高いレートを持つログを選択します
    2. ログの先頭の各キーについての最後のオフセットの簡潔な要約を作成します
    3. ログ内で最近現れたキーを削除しながら、最初から最後までログを再コピーします。新しい、きれいなセグメントはすぐにログに入れ替えられます。つまり必要とされる追加のディスク空間はちょうど1つの追加のログセグメントです (ログの完全なコピーではありません)。
    4. ログの頭の概要は本質的に単なる空間がぎっしりつまったハッシュテーブルです。それはエントリごとに正確に24バイトです。8GBのクリーナーバッファーの結果として、1つのクリナーの繰り返しでログのheadの約366GBをきりえします (1kのメッセージを仮定します)。

    ログクリーナーの設定

    ログクリーナーはデフォルトで有効です。これはクリーナースレッドのプールを開始するでしょう。あるトピック上でログクリーナーを有効にするために、ログ固有のプロパティを追加することができます
      log.cleanup.policy=compact
    これはトピックの作成時あるいは代替のトピックコマンドを使って行うことができます。

    ログクリーナーはログの非圧縮の"head"の最小量を維持するように設定することができます。これは圧縮時間のラグを設定することで有効になります。

      log.cleaner.min.compaction.lag.ms
    これは最小のメッセージ経過時間より新しいメッセージが圧縮されなければならないことを避けるために使うことができます。設定されない場合は、最後の、つまり現在書き込まれているセグメントを除いて、全てのログのセグメントが圧縮の資格があります。有効なセグメントは、たとえメッセージの全てが最小の圧縮タイムのラグより古くても圧縮されないでしょう。

    クリーナーの更なる設定はここで説明されます。

    4.9クォータ

    Kafka クラスタはクライアントにいって使われるブローカーのリソースを制御するために、リクエストに割り当てを強制することができます。クォータを共有するクライアントグループごとにKafkaのブローカーによって2種類のクライアント クォータを適用することができます:

    1. ネットワークの帯域の割り当てはバイトレートの閾値を定義します (0.9から)
    2. リクエストのレートの定員はネットワークとI/Oスレッドのパーセンテージとして、CPUの利用率の閾値を定義します (0.11から)

    定員はなぜ必要なのか?

    プロデューサとコンシューマはとても多くのデータ量を生成/消費、あるいはとても高いレートでリクエストを生成することが可能で、従ってブローカーのリソースを占有し、ネットワークの飽和を起こし、一般的に他のクライアントとブローカー自身のサービス妨害します。クォータを持つことはこれらの問題を防ぎ、少数の悪い挙動をするクライアントが良い挙動をするクライアントのユーザエクスペリエンスを下げるかもしれない大規模なマルチテナントのクラスタにおいてもっと重要です。実際、Kafkaをサービスとして実行する時に、合意に従ってAPIの制限を強制することさえできます。

    クライアント グループ

    Kafkaクライアントの身分証明はセキュアなクラスタ内での認証されたユーザを表すユーザ プリンシパルです。認証されていないクライアントをサポートするクラスタ内では、ユーザのプリンシパルは設定可能なPrincipalBuilderを使ってブローカーによって選択された未認証のユーザのグループです。クライアントidは、クライアントアプリケーションによって選択された意味がある名前を持つクライアントの論理的なグループです。タプル (user, client-id) は、ユーザ プリンシパルとクライアントidの両方を共有するクライアントの安全なロジカルグループを定義します。

    定員は、ユーザあるいはクライアントidグループの、(user, client-id) に適用することができます。指定された接続について、接続に一致するもっとも特定のクォータが適用されます。割り当てグループの全ての接続はグループのために設定された割り当てを共有します。例えば、(user="test-user", client-id="test-client") が10MB/secの生成のクォータを持つ場合、これはクライアント-id "test-client" を持つ ユーザ "test-user" の全てのプロデューサ インスタンスに渡って共有されます。

    割り当ての設定

    割り当ての設定は (user, client-id)、ユーザとクライアントidのグループについて定義されるかもしれません。高い(あるいは低いでも)割合を必要とするどの割り合いレベルでもデフォルトの割合を上書きすることができます。仕組みはトピック毎のログの設定の上書きに似ています。ユーザと (user, client-id) の割り当てはZooKeeperの /config/users の下に書き込まれ、クライアントidの割り当ての上書きは /config/clientsの下に書き込まれます。これらの上書きは全てのブローカーから読み込まれ、すぐに有効になります。これにより、クラスタ全体のローリング再起動をする必要無しに割り当ての変更ができます。詳細はここを見てください。各グループについてのデフォルトの割り当ては同じ仕組みを使って動的に更新することもできます。

    割り当て設定の優先順位は以下の通りです:

    1. /config/users/<user>/clients/<client-id>
    2. /config/users/<user>/clients/<default>
    3. /config/users/<user>
    4. /config/users/<default>/clients/<client-id>
    5. /config/users/<default>/clients/<default>
    6. /config/users/<default>
    7. /config/clients/<client-id>
    8. /config/clients/<default>
    ブローカーのプロパティ(quota.producer.default, quota.consumer.default)はクライアントid グループについての帯域のネットワーク割り当てのデフォルトを設定するために使うこともできます。これらのプロパティは非推奨になっていて、後のリリースでは削除されるでしょう。クライアントidのデフォルトの割り当ては他の割り当ての上書きとデフォルトに似てZooKeeper内で設定することができます。

    ネットワークの帯域の割り当て

    ネットワークの帯域の割り当ては、割り当てを共有するクライアントの各グループについてのバイトレートの閾値として定義されます。デフォルトでは、各ユニークなクライアントグループはクラスタによって定義されたものとして、バイト/秒の一定の割り当てを受け取ります。この割り当てはブローカー単位を基準に定義されます。クライアントの各グループはクライアントが絞られる前にブローカーあたり最大 X バイト/秒を発行/取得することができます。

    リクエスト レートの割り当て

    リクエスト レートのクォータは、クォータウィンドウ内の各ブローカーのリクエストハンドラ I/Oスレッドとネットワークスレッド上でクライアントが使うことができる時間のパーセンテージとして定義されます。割り当てn% は1つのスレッドのn% を表します。つまり割り当ては ((num.io.threads + num.network.threads) * 100)% の総容量以上です。クライアントの各グループは絞られる前にクォータウィンドウ内の全てのI/Oおよびネットワークスレッドにわたってn% までの合計のパーセンテージを使うことができます。I/Oおよびネットワークスレッドに割り当てられるスレッドの数は一般的にブローカーホスト上で利用可能なコアの数に基づくため、リクエストレートのクォータはクォータを共有するクライアントの各グループによって使うことができるCPUの総パーセンテージを表します。

    強制

    デフォルトで、各ユニークなクライアントグループはクラスタで設定された固定の割合を受け取ります。この割り当てはブローカー単位を基準に定義されます。各クライアントは絞られるまでにブローカーあたりのこの割り当てまで利用することができます。ブローカーごとにクォータを定義することは、全てのブローカー間でクライアントのクォータの使用を共有する仕組みを必要とするため、クライアントごとに固定のクラスタの帯域幅を持つよりも優れていると判断しました。これはクォータの実装自体よりも難しくなる可能性があります!

    ブローカーは割り当ての違反を検出した時に、どのように反応しますか?私たちの解決法では、ブローカーはまず違反しているクライアントをクォータの元に持っていくために必要な遅延量を計算し、遅れた応答をすぐに返します。フェッチ リクエストの場合、応答は何もデータを含まないでしょう。その後、ブローカーは遅延が終了するまで、クライアントからの要求を処理しないようにクライアントのチャネルをミュートします。遅延時間が0ではない応答を受信すると、Kafkaクライアントは遅延中にブローカーへ更にリクエストを送信することを控えるでしょう。従って、絞られたクライアントからの要求は両側から効果的にブロックされます。ブローカーからの応答の遅延を考慮しない古いクライアントの実装であっても、ブローカーがソケットチャンネルをミューとすることによって適用されるバックプレッシャーは依然として動作不良のクライアントのスロットルを処理することができます。絞られたチャンネルに更にリクエストを送信するクライアントは遅延が解消した後でのみ応答を受信するでしょう。

    クォータ違反を迅速に検出して訂正するために、複数の小さなウィンドウ(例えば1秒の30個のウィンドウ)に渡ってバイトレートおよびスレッドの使用率が計測されます。一般的に、大きな測定ウィンドウ(例えば30秒の10個のウィンドウ)を持つことは、ユーザにとってはそれほど長くない長期の遅延が続くトラフィックの大きなバーストに繋がります。

    5. 実装

    ネットワーク層はかなり単純なNIOサーバであり、あまり詳細には説明はしないつもりです。sendfileの実装はMessageSet インタフェースにwriteToメソッドを指定することで行われます。これにより、ファイルが後方にあるメッセージは、実行中のバッファされた書き込みの代わりにもっと効率的なtransferTo 実装を使うようにすることができます。スレッドモデルは、1つのアクセプタ スレッドと、固定数の接続をそれぞれ処理するN 個の処理スレッドです。この設計はあちこちで 徹底的にテストされていて、実装し易く高速であることが知られています。他の言語でクライアントの更なる実装ができるように、プロトコルは極めて単純にされています。

    5.2メッセージ

    メッセージは可変長のヘッダ、可変長の不透明なキーのバイト配列、および可変長の不透明な値のバイト配列からなります。ヘッダのフォーマットは以下の章で説明されます。キーと値を不透明なままにしておくことは良い選択です: シリアライズ化ライブラリにおいて現在かなりの進歩があり、特定の選択肢は全ての用途に適しているとは言えません。Kafkaを使っている特定のアプリケーションは言うまでもなくその使用法の一部として独特のシリアライズ タイプを委任されるでしょう。RecordBatch インターフェースはNIOChannelのバルク読み込みと書き込みのために特化したメソッドを使った単純なメッセージ上のイテレータです。

    5.3メッセージ形式

    メッセージ (または レコード) は常にバッチ内で書き込まれます。メッセージのバッチの技術的な用語はレコードバッチで、レコードバッチは1つ以上のレコードを含みます。縮退した場合では、1つのレコードを含むレコードバッチがあります。レコードバッチとレコードは独自のヘッダを持ちます。それぞれの形式が以下で説明されます。

    5.3.1レコードバッチ

    以下はレコードバッチのディスク上の形式です。

    		baseOffset: int64
    		batchLength: int32
    		partitionLeaderEpoch: int32
    		magic: int8 (current magic value is 2)
    		crc: int32
    		attributes: int16
    			bit 0~2:
    				0: no compression
    				1: gzip
    				2: snappy
    				3: lz4
    			bit 3: timestampType
    			bit 4: isTransactional (0 means not transactional)
    			bit 5: isControlBatch (0 means not a control batch)
    			bit 6~15: unused
    		lastOffsetDelta: int32
    		firstTimestamp: int64
    		maxTimestamp: int64
    		producerId: int64
    		producerEpoch: int16
    		baseSequence: int32
    		records: [Record]
    	

    圧縮が有効な場合、圧縮されたレコードデータはレコードの数に続いて直接シリアライズ化されます。

    CRCは属性からバッチの終わりまでのデータをカバーします (つまり、CRCに続く全てのバイト)。それはマジックバイトの後に位置します。それはクライアントはバッチの長さとマジックバイトの間のバイトをどうやって解釈するかを決める前にマジックバイトをパースする必要があることを意味します。このフィールドがブローカーによって受け取られる各バッチによって割り当てられる時に、CRCを再計算する必要を避けるために、CRCの計算内にパーティションリーダーのepochフィールドは含まれません。計算にはCRC-32C (Castagnoli) 多項式が使われます。

    圧縮時: 古いメッセージ形式と異なり、magic v2 以上では、ログが掃除される時に元のバッチからの最初と最後のオフセット/シーケンス番号が保持されます。これはログがリロードされる時にプロデューサの状態を回復することができるようにするために必要です。例えば、最後のシーケンス番号を維持しないとした場合、パーティションリーダーが失敗するとプロデューサは OutOfSequence エラーを見るかもしれません。基本のシーケンス番号は重複チェックのために維持されなければなりません (ブローカーは、入ってくるバッチの最初と最後のシーケンス番号がプロデューサからの最後のものと一致することを検証することで、入ってくるプロデューサのリクエストを重複に関してチェックします)。結果として、バッチ内の全てのレコードが掃除されたが、プロデューサの最後のシーケンス番号を保持するためにバッチがまだ維持されている場合、ログ内に空のバッチを持つことができます。ここで1つ風変りな事は、圧縮の間 baseTimestamp フィールドは維持されないということです。つまり、バッチ内の最初のレコードが圧縮されれば変更されるでしょう。

    5.3.1.1制御バッチ

    制御バッチは制御レコードと呼ばれる1つのレコードを含みます。制御レコードはアプリケーションに渡されるべきではありません。代わりに、それらは破棄されたトランザクションメッセージを除外するために、コンシューマによって使われます。

    制御レコードのキーは以下のスキーマに準拠します:

           version: int16 (現在のバージョンは0です)
           type: int16 (0は破棄マーカーを示し、1はコミットを示します)
        

    制御レコードの値についてのスキーマはtypeに依存します。値はクライアントに対して不透明です。

    5.3.2レコード

    レコード レベルのヘッダーはKafka 0.11.0 で導入されました。ヘッダーを持つレコードのディスク上での形式を以下で説明します。

    		length: varint
    		attributes: int8
    			bit 0~7: unused
    		timestampDelta: varint
    		offsetDelta: varint
    		keyLength: varint
    		key: byte[]
    		valueLen: varint
    		value: byte[]
    		Headers => [Header]
    	

    5.3.2.1レコード ヘッダ

    		headerKeyLength: varint
    		headerKey: String
    		headerValueLength: varint
    		Value: byte[]
    	

    Protobufとして同じ変換エンコーディングを使います。後者についての詳細はここで見つけることができます。レコード内のヘッダーの数も変形としてエンコードされます。

    5.3.3古いメッセージ形式

    Kafka 0.11 より前では、メッセージは変換され、メッセージ セットの中に格納されました。メッセージ セットの中で、各メッセージは独自のメタデータを持ちます。メッセージセットは配列として表されますが、プロトコルの他の配列要素のようにint32の配列サイズが前にあることはありません。

    メッセージ セット:

        MessageSet (Version: 0) => [offset message_size message]
            offset => INT64
            message_size => INT32
            message => crc magic_byte attributes key value
                crc => INT32
                magic_byte => INT8
                attributes => INT8
                    bit 0~2:
                        0: no compression
                        1: gzip
                        2: snappy
                    bit 3~7: unused
                key => BYTES
                value => BYTES
        

        MessageSet (Version: 1) => [offset message_size message]
            offset => INT64
            message_size => INT32
            message => crc magic_byte attributes key value
                crc => INT32
                magic_byte => INT8
                attributes => INT8
                    bit 0~2:
                        0: no compression
                        1: gzip
                        2: snappy
                        3: lz4
                    bit 3: timestampType
                        0: create time
                        1: log append time
                    bit 4~7: unused
                timestamp =>INT64
                key => BYTES
                value => BYTES
        

    Kafka 0.10より前のバージョンでは、サポートされるメッセージの形式のバージョン (これはマジック値によって示されます)は0でした。メッセージ形式のバージョン 1 はバージョン 0.10 でタイムスタンプのサポートと共に導入されました。

    • バージョン2以上と似て、属性の最下位ビットは圧縮タイプを表します。
    • バージョン1では、プロデューサは常にタイムスタンプ型のビットを0にしなければなりませんでした。トピックがログの追記時間を使うように設定されている場合、(ブローカーのレベル設定 log.message.timestamp.type = LogAppendTime あるいはトピックのレベル設定 message.timestamp.type = LogAppendTime)、ブローカーはタイムスタンプの型とメッセージセット中のタイムスタンプを上書きするでしょう。
    • 属性の最上位ビットは0に設定されなければなりません。

    メッセージ形式のバージョン0および1では、Kafkaは圧縮を有効にするために再帰的なメッセージをサポートします。この場合、メッセージの属性は圧縮型の1つを示すように設定されなければならず、値のフィールドはその型で圧縮されたメッセージセットを含むでしょう。ネストされたメッセージを "内部メッセージ"、ラップされたメッセージを "外部メッセージ" と呼びます。キーは外部メッセージについてはnullでなければならず、そのオフセットは最後の内部メッセージのオフセットでしょう。

    再帰バージョン 0のメッセージを受信する時、ブローカーはそれらを解凍し、それぞれの内部メッセージは個々にオフセットを割り当てられます。バージョン1では、サーバ側での再圧縮を避けるために、ラップ メッセージだけがオフセットを割り当てられるでしょう。内部メッセージは相対的なオフセットを持つでしょう。絶対的なオフセットは外部メッセージからのオフセットを使って計算することができます。これは最後の内部メッセージに割り当てられたオフセットに対応します。

    crc フィールドはその後に続くメッセージバイト(マジック バイトからその値へ)の CRC32 (CRC-32C では無い) を含みます。

    5.4ログ

    2つのパーティションを持つ"my_topic"という名前のトピックについてのログは、トピックについてのメッセージを含むデータファイルがある2つのディレクトリから成ります (すなわち、my_topic_0my_topic_1)。ログファイルの形式は "log entries" の系列です; 各ログエントリはNメッセージのバイトが続くメッセージの長さを格納する4バイトの整数N です。各メッセージはパーティション上のトピックにこれまで送信された全てのメッセージのストリーム内でのこのメッセージの開始位置のバイトを与える 64-ビットの整数のoffsetによって一意に識別されます。各メッセージのディスク上での形式は以下で示されます。各ログファイルはそれが含まれる最初のメッセージのオフセットを使って名前を付けられます。つまり、最初に作成されるファイルは 00000000000.kafka でしょう。そしてそれぞれ追加のファイルは設定で指定される最大のログファイルサイズが S の場合に以前のファイルからおよそ S バイトの整数の名前を持つでしょう。

    レコードのための正確なバイナリ形式はバージョン管理され、標準インタフェースとして維持されるので、レコードバッチは必要な時に再コピーあるいは変換無しにプロデューサ、ブローカー およびクライアント間で転送することができます。前の章はレコードのディスク上の形式についての詳細を含んでいました。

    メッセージidとしてのメッセージのオフセットの使用は一般的ではありません。私たちの元の考えは、プロデューサによって生成されたGUIDを使い、各ブローカー上でのオフセットのためにGUIDからのマッピングを維持するものでした。しかし、コンシューマは各サーバについてIDを維持する必要があるため、GUIDのグローバルでの一意性は何ももたらしません。更に、ランダムなidからオフセットへのマッピングの維持の複雑さは、本質的に完全な一貫性を持つランダムアクセスのデータ構造を必要とする、ディスクと同期される必要がある重いインデックス構造を必要とします。したがって、構造の検索を簡単にするために、メッセージを一意に識別するためのパーティションidとノードidを連結することができる単純なパーティションごとのアトミックなカウンタを使うことを決めました。しかしいったんカウンタを決定すると、オフセットを使った直接ジャンプは当然のように思えました — 結局パーティションでユニークな整数が単調に増加しています。オフセットはコンシューマAPIからは隠されているため、この決定は最終的に実装の詳細であり、もっと効率的なやり方を伴いました。

    書き込み

    The log allows serial appends which always go to the last file. このファイルは設定可能なサイズ(例えば1GB)に達すると、新しいファイルにロールオーバーされます。ログは2つの設定パラメータを取ります: M はOSにファイルをディスクにフラッシュを強制する前に書き込むメッセージの数を指定し、S はフラッシュが強制された後の秒数を指定します。これはシステムがクラッシュした時に、最大 M 個のメッセージ、あるいは S 秒のデータが失われることの耐久性の保証をします。

    読み込み

    読み込みはメッセージの64-ビットの論理オフセットとS-バイトの最大チャンクサイズを指定することで行われます。これはS-バイトのバッファ内に含まれるメッセージ上のイテレータを返すでしょう。S はどの1つのメッセージよりも大きくなるように意図されていますが、以上に大きなメッセージの場合には、メッセージの読み込みが成功するまで毎回バッファサイズを2倍にし、読み込みを複数回試行することができます。サーバがあるサイズより大きいメッセージを拒否し、完全なメッセージを取得するために読み込まなければならない最大サイズについてクライアントに制限をつけるために、最大メッセージサイズとバッファサイズを指定することができます。読み込みバッファが部分的なメッセージで終わりがちですが、これはサイズの区切りによって容易に検出されます。

    オフセットから読み込む実際のプロセスでは、まずデータが格納されたログ セグメント ファイルの場所を特定し、グローバル オフセット値からファイル固有のオフセットを計算し、そのファイルオフセットから読み込みます。検索は各ファイルについて保持されるメモリ内の範囲に対して単純な二分木検索の派生物として行われます。

    ログは、クライアントが"right now"として購読を開始できるように最も最近に書かれたメッセージを取得できる機能を提供します。コンシューマがデータを SLAの指定日数内で消費するのに失敗した場合にも便利です。この場合、クライアントが存在しないオフセットを消費しようとすると、OutOfRangeException が与えられ、ユースケースに応じて自身を再設定するか、失敗するかもしれません。

    以下はコンシューマに送信される結果のフォーマットです。

        MessageSetSend (fetch result)
    
        total length     : 4 bytes
        error code       : 2 bytes
        message 1        : x bytes
        ...
        message n        : x bytes
        
        MultiMessageSetSend (multiFetch result)
    
        total length       : 4 bytes
        error code         : 2 bytes
        messageSetSend 1
        ...
        messageSetSend n
        

    削除

    データは一度に1つのログセグメントを削除されます。ログマネージャーは差し込み可能な削除ポリシーを使ってどのファイルが削除されるべきかを選択することができます。現在のポリシーは修正時間がN日以上前の全てのログを削除しますが、最後のN GBを維持するポリシーも有用です。To avoid locking reads while still allowing deletes that modify the segment list we use a copy-on-write style segment list implementation that provides consistent views to allow a binary search to proceed on an immutable static snapshot view of the log segments while deletes are progressing.

    保証

    ログはディスクにフラッシュを強制する前に書き込まれるメッセージの最大数を制御する設定パラメータM を提供します。起動時に最新のログセグメント内の全てのメッセージを繰り返し処理し、各メッセージエントリが有効であることを検証するログ回復プロセスが実行されます。メッセージエントリは、そのサイズとオフセットの合計がファイルの長さよりも小さく、メッセージのペイロードのCRC32がメッセージに格納されたCRCに合致する場合に有効です。衝突が検出された場合、ログは最後に有効だったオフセットに切り詰められます。

    2種類の衝突が処理されなければならないことに注意してください: クラッシュにより紛失した書き込まれていないブロックの切り詰め、ファイルに無意味なブロックが追加されたことによる衝突。これは、一般的にOSはファイルのinodeと実際のブロックデータの間で書き込みの順番の保証をしないため、もしinodeが新しいサイズで更新されたがデータを含むブロックを書き込む前にクラッシュした場合に、更に書き込まれたデータの喪失に加えてファイルは意味の無いデータを取得するかもしれません。CRCはこの人目の届かないケースを検出し、ログを衝突から防ぎます(しかし、書き込まれていないメッセージはもちろん紛失されます)。

    5.5分散

    コンシューマのオフセットの追跡

    高レベルのコンシューマは各パーティション内で消費した最大のオフセットを追跡し、再起動時にそれらのオフセットから回復できるようにそのオフセットのベクトルを定期的にコミットします。Kafka は(グループについての)オフセットマネージャーと呼ばれる専用のブローカー内で、指定されたコンシューマグループについての全てのオフセットを格納する選択肢を提供します。つまり、そのコンシューマグループ内の全てのコンシューマインスタンスは、そのオフセットマネージャー(ブローカー)にオフセットコミットを送信し、取得しなければなりません。高レベルのコンシューマはこれを自動的に処理します。単純なコンシューマを使用する場合は、オフセットを手動で管理しなければならないでしょう。現在のところ、これはZooKeeperでオフセットをコミットあるいは取得だけができるJavaの単純なコンシューマではサポートされていません。Scalaの単純なコンシューマを使っている場合は、オフセットマネージャーを見つけることができ、明示的にオフセットマネージャーにオフセットをコミットあるいは取得することができます。コンシューマはGroupCoordinatorRequestを全てのKafkaブローカーに発行し、オフセットマネージャーを含むだろう GroupCoordinatorResponse を読み込むことで、オフセットマネージャーを調べることができます。それからコンシューマはオフセットマネージャーのブローカーからオフセットをコミットあるいは取得することができます。オフセットマネージャーが移動した場合は、コンシューマはオフセットマネージャーを再び見つける必要があるでしょう。オフセットを手動で管理したい場合は、OffsetCommitRequest と OffsetFetchRequest を発行する方法を説明するコードの例に目を通してください。

    オフセットマネージャーが OffsetCommitRequest を受け取ると、それはリクエストを特別な 圧縮された __consumer_offsetsという名前のKafkaトピックに追加します。オフセットマネジャーは、オフセットトピックの全てのレプリカがオフセットを受け取った時のみ、成功のオフセットコミット応答をコンシューマに送信します。オフセットが設定可能なタイムアウト内でレプリケートに失敗した場合は、オフセットコミットは失敗しコンシューマはバックオフの後でコミットを再試行するかもしれません。(これは高レベルのコンシューマによって自動的に行われます。) このブローカーはパーティション毎に最も最近のオフセットだけを維持する必要があるため、このブローカーは定期的にオフセットを圧縮します。オフセットマネジャーはオフセットの取得を素早く提供するために、メモリ内のテーブルの中にオフセットのキャッシュも行います。

    オフセットマネージャーがオフセットの取得リクエストを受け取る時に、単純にオフセットのキャッシュから最後にコミットされたオフセットのベクトルを返します。オフセットマネージャーが開始したばかりか、あるいは(オフセットトピックのパーティションのためのリーダーになることで)新しいコンシューマグループのセットとしてオフセットマネージャーになったばかりの場合は、オフセットのトピックパーティションをキャッシュにロードする必要があるかもしれません。この場合、オフセットの取得は OffsetsLoadInProgress 例外で失敗し、コンシューマはバックオフの後で OffsetFetchRequest を試行するかもしれません。(これは高レベルのコンシューマによって自動的に行われます。)

    オフセットをZooKeeperからKafkaにマイグレート

    初期のリリースでのKafkaのコンシューマはそれらのオフセットをデフォルトでZooKeeperに格納します。以下のステップに従って、オフセットをコミットするためにこれらのコンシューマをKafkaに移設することができます:

    1. コンシューマの設定の中でoffsets.storage=kafkadual.commit.enabled=true を設定します。
    2. コンシューマのローリング バランスを行い、コンシューマがhealthyであることを確認します。
    3. コンシューマの設定の中でdual.commit.enabled=falseを設定します。
    4. コンシューマのローリング バランスを行い、コンシューマがhealthyであることを確認します。
    offsets.storage=zookeeperを設定した場合は、上のステップを使ってロールバック (つまり、Kafka から ZooKeeper への戻し)を行うこともできます。

    ZooKeeperのディレクトリ

    以下はコンシューマとブローカー間を対等にするために使われるZooKeeperの構造とアルゴリズムを示します。

    表記法

    パス内の要素が [xyz] で示される場合、それはxyzの値が固定ではなく、実際にはxyzの値を取りうるZooKeeperのznodeであることを意味します。例えば、/topics/[topic] は それぞれトピック名についてのサブディレクトリを含む /topics という名前のディレクトリかもしれません。サブディレクトリ 0, 1, 2, 3, 4 を示すために [0...5] のような数値の範囲も渡されます。矢印 -> がznodeの内容を示すために使われます。例えば /hello -> は 値 "world" を含む znode /hello を示すでしょう。

    ブローカーノードのレジストリ

        /brokers/ids/[0...N] --> {"jmx_port":...,"timestamp":...,"endpoints":[...],"host":...,"version":...,"port":...} (ephemeral node)
        

    これは存在する全てのブローカーノードのリストです。それぞれはコンシューマで識別するユニークな論理ブローカーidを提供します (設定の一部として指定されなければなりません)。始めに、ブローカーノードは /broders/ids の下に論理ブローカーidを持つznodeを作成することで自身を登録します。論理ブローカーidの目的はブローカーがコンシューマに影響を与えずに異なる物理マシーンに移動できるようにするということです。既に使用されている(例えば2つのサーバが同じブローカーidで設定されているため)ブローカーidを登録しようとするとエラーになります。

    ブローカーは短命のznodeを使って自身をZooKeeperに登録するため、この登録は動的で、もしブローカーがシャットダウンあるいは死亡した場合には消えるでしょう (従って、コンシューマへの通知はもう利用できません)。

    ブローカーのトピックのレジストリ

        /brokers/topics/[topic]/partitions/[0...N]/state --> {"controller_epoch":...,"leader":...,"version":...,"leader_epoch":...,"isr":[...]} (ephemeral node)
        

    各ブローカーは自身をそのトピックについてのパーティションの数を維持し格納するトピックの下に登録します。

    コンシューマとコンシューマグループ

    トピックのコンシューマは、お互いに調整しデータの消費をバランスするために、自身をZooKeeperに登録することもできます。コンシューマは offsets.storage=zookeeperを設定することでそれらのオフセットをZooKeeperに格納することもできます。しかし、このオフセットの格納の機構は将来のリリースで非推奨になるでしょう。従ってオフセットのストレージをKafkaに移設することをお勧めします。

    多数のコンシューマはグループを形成し、連帯して1つのトピックを消費することができます。同じグループ内の各コンシューマは共有group_idを与えられます。例えば、1つのコンシューマが3つのマシーンを横断して実行されるfoobarプロセスであれば、このコンシューマのグループにid "foobar" を割り当てるかもしれません。このグループidはコンシューマの設定内で提供され、コンシューマがどのグループに所属しているかをコンシューマに知らせる手段です。

    グループ内のコンシューマは出来る限り等しくパーティションを分割します。各パーティションはコンシューマグループ内の確実に1つのコンシューマによって消費されます。

    コンシューマ id のレジストリ

    グループ内の全てのコンシューマによって共有されるgroup_id に加えて、各コンシューマは一時的な、ユニークな (hostname:uuid形式の) consumer_id を与えられます。コンシューマidは以下のディレクトリに登録されます。

        /consumers/[group_id]/ids/[consumer_id] --> {"version":...,"subscription":{...:...},"pattern":...,"timestamp":...} (ephemeral node)
        
    グループ内の各コンシューマはグループの下に登録され、そのconsumer_idを使ってznodeを生成します。znodeの値は <topic, #streams> のマップを含みます。このidは単純にグループ内でアクティブなコンシューマを識別するために使われます。これは短命ノードなので、コンシューマの処理が終了すると消えるでしょう。

    コンシューマのオフセット

    コンシューマは各パーティション内で消費した最大のオフセットを追跡します。もしoffsets.storage=zookeeperであれば、この値はZooKeeperディレクトリ内に格納されます。

        /consumers/[group_id]/offsets/[topic]/[partition_id] --> offset_counter_value (persistent node)
        

    パーティションのオーナーのレジストリ

    各ブローカーのパーティションは指定されたコンシューマグループ内の1つのコンシューマによって消費されます。コンシューマは消費を始める前に指定されたパーティションの所有を確立しなければなりません。所有を確立するために、コンシューマは要求している特定のブローカーパーティションの下の短命ノード内に自身のidを書きます。

        /consumers/[group_id]/owners/[topic]/[partition_id] --> consumer_node_id (ephemeral node)
        

    クラスターid

    クラスターidはKafkaクラスタに割り当てられるユニークで不変の識別子です。クラスタidは最大22文字を持ち、許される文字は正規表現 [a-zA-Z0-9_\-]+ で定義されます。これはパディング無しのURLセーフなBase64の変種によって使われる文字に対応します。概念的には、クラスタが初めて開始した時に自動生成されます。

    実装上は、バージョン 0.10.1以降のブローカーが初めて正常に開始された時に生成されます。ブローカーは開始時に/cluster/id znode からクラスタidを取得しようとします。もしznodeが存在しない場合は、ブローカーは新しいクラスタidを生成し、このクラスタidを使ってznodeを生成します。

    ブローカーのノードの登録

    ブローカーのノードは基本的に依存しません。つまり、それらは何を持っているかについて情報を公開するだけです。ブローカーが参加した時に、それは自身をブローカーノードのレジストリディレクトリに登録し、ホスト名とポートについての情報を書き込みます。ブローカーも既存のトピックのリストとそれらの論理パーティションをブローカーのトピックのレジストリに書き込みます。新しいトピックはそれらがブローカー上に生成された時に動的に登録されます。

    コンシューマーの登録アルゴリズム

    コンシューマが開始すると、それは以下のことを行います:

    1. 自身をグループの下のコンシューマid内に登録します。
    2. コンシューマidレジストリの下に変更時(新しいコンシューマが参加あるいは既存のコンシューマの中止)の監視を登録する。(各変更は変更されたコンシューマが所属するグループ内の全てのコンシューマ間でリバランスを引き起こします。)
    3. ブローカーidレジストリの下に変更時(新しいブローカーが参加あるいは既存のブローカーの中止)の監視を登録する。(各変更は全てのコンシューマグループ内の全てのコンシューマ間でリバランスを引き起こします。)
    4. コンシューマがトピックフィルターを使ってメッセージストリームを生成した場合、コンシューマはブローカートピックレジストリの下に変更時(新しいトピックが追加)の監視も登録します。(各変更はどのトピックがトピックフィルターによって許されるかを決定するために、利用可能なトピックの再評価を引き起こすでしょう。新しく許されたトピックはコンシューマグループ内の全てのコンシューマ間でリバランスを引き起こすでしょう。)
    5. コンシューマ グループ内で強制的にリバランスしてください。

    コンシューマーのリバランスのアルゴリズム

    コンシューマのリバランスアルゴリズムにより、グループ内の全てのコンシューマはどのコンシューマがどのパーティションを消費しているかの同意を取ることができます。コンシューマのリバランスはブローカーノードおよび同じグループ内の他のコンシューマの両方の追加あるいは削除時に引き起こされます。指定されたトピックおよび指定されたコンシューマグループについて、ブローカーのパーティションは最終的にグループ内のコンシューマ間で分配されます。パーティションは常に1つのコンシューマによって消費されます。この設計は実装を単純にします。パーティションが同時に複数のコンシューマによって消費されるようにしたため、パーティション上での競争および何らかの種類のロックが必要とされるでしょう。パーティションより多くのコンシューマがある場合、いくつかのコンシューマは全くデータを取得しないでしょう。リバランスの間に、各コンシューマが接続しなければならないブローカーノードの数を減らすような方法で、パーティションをコンシューマに割り当てようとします。

    各コンシューマはリバランスの間に以下のことを行います:

        1. Ci が購読している各トピックTについて
        2.   PT がトピックTを生成している全てのパーティションにする
        3.   CG を、トピック Tを消費する Ci として同じグループ内の全てのコンシューマにする
        4.   PT をソートする (同じブローカー上のパーティションが一緒にクラスタにされるように)
        5.   ソート CG
        6.   i を CG内の Ci のインデックスの位置にし、N = size(PT)/size(CG) にする
        7.   i*N から (i+1)*N - 1 のパーティションをコンシューマ Ciに割り当てる
        8.   パーティションオーナーのレジストリから Ci によって所有されている現在のエントリを削除する
        9.   新しく割り当てられたパーティションをパーティションオーナーのレジストリに追加する
                (元のパーティションオーナーが所有を解放するまでこれを再試行する必要があるかもしれません)
        

    1つのコンシューマでリバランスが引き起こされた場合、リバランスは同じ時間について同じグループ内の他のコンシューマで引き起こされなければなりません。

    6. 操作

    この章ではあなたがKafkaクラスタで実施するだろう最も一般的な操作を再検討するでしょう。この章で検討される全てのツールはKafkaの配布物のbin/ディレクトリの下で利用可能で、各ツールは引数無しで実行した場合に全ての可能なコマンドラインオプションの詳細を出力するでしょう。

    トピックの追加と削除

    トピックを手動で追加するか、あるいは存在しないトピックに初めてデータが発行された時に自動的に生成されるようにするかの選択肢があります。トピックが自動生成された場合、自動生成されたトピックに使われるデフォルトのトピックの設定を調整したいかもしれません。

    トピックはトピックツールを使って追加および修正されます:

      > bin/kafka-topics.sh --zookeeper zk_host:port/chroot --create --topic my_topic_name
            --partitions 20 --replication-factor 3 --config x=y
      
    リプリケーションのファクターはどれだけ多くのサーバが書き込まれる各メッセージをリプリケートするかを制御します。リプリケーションファクターが3の場合、データへのアクセスが失われるまでに2つまでのサーバが失敗することができます。データの消費無しにマシーンを透過的に解雇できるように、リプリケーションファクターを2または3にすることをお勧めします。

    パーティションのカウントはどれだけ多くのログをトピックが共有するかを制御します。パーティションのカウントの効果には幾つかあります。最初に、各パーティションは完全に1つのサーバ上に納まらなければなりません。つまり、20のパーティションを持つ場合(そして、読み込みと書き込みをする)、全体のデータセットは20以下のサーバで処理されるでしょう(レプリカを数えません)。結果的に、パーティション数はコンシューマの最大並行度に影響を与えます。これは概念の章で詳細に議論されます。

    共有された各パーティションログはKafkaログディレクトリの下の独自のフォルダに配置されます。そのようなフォルダの名前はダッシュ (-) とパーティションidが追加されたトピック名から成ります。一般的なフォルダ名は255を超える文字超にはできないため、トピック名の長さには制限があるでしょう。パーティションの数はいつでも100,000を超えないでしょう。従って、トピック名は249文字よりも長くすることはできません。これによりフォルダ名にはダッシュと5桁の可能性のあるパーティションidにちょうど余裕があります。

    コマンドライン上で追加された設定は、データが維持しなければならない期間のようなサーバのデフォルト設定を上書きします。トピック毎の設定の完全なセットはここで説明されます。

    トピックの修正

    同じトピックツールを使っているトピックの設定あるいはパーティショニングを変更する事ができます。

    パーティションを追加するには

      > bin/kafka-topics.sh --zookeeper zk_host:port/chroot --alter --topic my_topic_name
            --partitions 40
      
    パーティションのユースケースの1つは意味論的にデータをパーティション化することであり、パーティションの追加は既存データのパーティションを変更しないため、もしコンシューマがそのパーティションに依存する場合はコンシューマを乱すかもしれないことに注意してください。つまり、もしデータがhash(key) % number_of_partitionsでパーティション化されている場合、このパーティション化はパーティションの追加によってシャッフルされるかもしれませんが、Kafkaはどうであれ自動的にはデータを再分配しようとしないでしょう。

    設定を追加するには:

      > bin/kafka-configs.sh --zookeeper zk_host:port/chroot --entity-type topics --entity-name my_topic_name --alter --add-config x=y
      
    設定を削除するには:
      > bin/kafka-configs.sh --zookeeper zk_host:port/chroot --entity-type topics --entity-name my_topic_name --alter --delete-config x
      
    そして、結果的にトピックを削除するには:
      > bin/kafka-topics.sh --zookeeper zk_host:port/chroot --delete --topic my_topic_name
      

    Kafka は今のところトピックについてのパーティションの数の削減をサポートしていません。

    トピックのリプリケーション ファクターについての説明はここで見つけることができます。

    Graceful シャットダウン

    Kafkaクラスタは自動的にブローkーアのシャットダウンあるいは障害を検知し、そのマシーン上のパーティションの新しいリーダーを選出するでしょう。これは、サーバが失敗するか、メンテナンスあるいは設定の変更のために意図的に落とすかのどちらかで、起こるでしょう。後者の場合、Kafkaはサーバを停止するために単にkillするよりもより優雅な機構をサポートします。サーバがgracefullyに停止した場合、利用可能な2つの最適化があります:
    1. 再起動をした時にログの回復をする必要を避けるためにディスクに全てのログを同期するでしょう (つまり、ログのtailの中で全てのメッセージについてチェックサムの検証をする)。ログの回復には時間がかかるため、これは内部的な再起動を高速化します。
    2. シャットダウンする前に、そのサーバがリーダーになっている全てのパーティションを他のレプリカに移行するでしょう。リーダーシップの転送を高速化し、各パーティションが利用できない時間を数ミリ秒に最小化するでしょう。
    サーバがハードkillで停止されない場合はログの同期が自動的に起こりますが、制御されたリーダーシップの移設には特別な設定の利用が必要です:
          controlled.shutdown.enable=true
      
    制御されたシャットダウンはブローカー上でホストされる全てのパーティションがレプリカを持つ場合のみ成功するでしょう (つまり、レプリケーションのファクターが1以上で少なくともそれらのレプリカの1つが活動中である)。最後のレプリカをシャットダウンするとトピックパーティションが使えなくなるので、これは一般的に望ましいものです。

    リーダーシップのバランシング

    ブローカーが停止あるいはクラッシュした時はいつでも、ブローカーのパーティションが他のレプリカに転送されます。このことは、デフォルトでブローカーが再起動した場合、それの全てのパーティションについてフォロワーだけが存在することを意味します。それはクライアントの読み込みと書き込みに使われないだろうことを意味します。

    この不均衡を避けるために、Kafkaは優先のレプリカの概念を持ちます。パーティションのためのレプリカのリストが1,5,9の場合、ノード1はレプリカのリストの中で先にあるためノード1がノード5あるいは9のどちらよりもリーダーとして優先されます。以下のコマンドを実行することで回復されたレプリカのリーダーを回復しようとするKafkaクラスタを持つことができます:

      > bin/kafka-preferred-replica-election.sh --zookeeper zk_host:port/chroot
      
    このコマンドの実行は退屈かもしれないため、以下の設定をすることでKafkaにこれを自動的に行うように設定することもできます:
          auto.leader.rebalance.enable=true
      

    ラックを超えたレプリカのバランシング

    ラックの認識機能は異なるラックを超えた同じパーティションのレプリカを分散します。これはKafkaがラック障害を補うためにブローカーの障害に対して提供する保証を延長し、ラック上の全てのブローカーが一度に障害になった場合のデータの喪失のリスクを制限します。その機能はEC2での可用性領域のような他のブローカーのグルーピングへ適用することもできます。

    ブローカーの設定にプロパティを追加することで、ブローカーが特定のラックに所属するように指定することもできます:
       broker.rack=my-rack-id
    トピックが生成, 修正 あるいはレプリカが再分配された時に、レプリカができる限り多くのラックにまたがるようにしながら、ラックの制約が尊重されるでしょう。

    レプリカをブローカーに割り当てるために使われるアルゴリズムは、ブローカーがどのようにラックを超えて分散されるかに関係なく、ブローカーあたりのリーダーの数が一定であることを確実にします。これはバランスのスループットを保証します。

    しかし、もしラックが異なる数のブローカーに割り当てられる場合、レプリカの割り当ては均等ではないでしょう。より多くのストレージを使用しより多くのレプリケーションにリソースを割り当てることを意味するため、より少ないブローカーを持つラックはより多くのレプリカを取得するでしょう。従って、ラック毎に同じ数のブローカーを設定することは意味があります。

    クラスタ間のデータのミラーリング

    1つのクラスタ内のノードの間で起こるレプリケーションとの混乱を避けるために、Kafkaクラスタ のデータのレプリケートのプロセスを "ミラーリング"とします。KafkaはKafkaクラスタ間でデータをミラーリングするためのツールを同梱します。ツールはソースクラスタから消費し、目的のクラスタへ生成します。この種類のミラーリングについての一般的なユースケースは、他のデータセンター内のレプリカを提供することです。このシナリオは次の章で詳細に議論されるでしょう。

    スループットを増やし耐障害性のために多くのそのようなミラーリング プロセスを実行することができます (もし1つのプロセスが終了すると、他のプロセスは追加の負荷を引き継ぎます)。

    データはソースクラスタ内のトピックから読み込まれ、目的のクラスタ内の同じ名前のトピックに書き込まれるでしょう。実施はミラーメイカーはKafkaコンシューマおよび一緒にフックされるプロデューサよりも少し多くの事をします。

    ソースおよび目的のクラスタは完全にエンティティに依存しません: それらは異なる数のパーティションを持ち、オフセットは同じでは無いでしょう。この理由で、(カスタマの位置が異なるだろうため) ミラー クラスタは対障害性の仕組みとして実際には意図されていません; そのためには通常のクラスタ内のレプリケーションの使用をお勧めします。しかし、ミラーメイカープロセスはパーティションについてのメッセージキーを維持し使用します。つまり順番はキー毎ベースで保持されます。

    入力クラスターから1つの(my-topicという名前の)トピックをミラーする方法を示す例です:

      > bin/kafka-mirror-maker.sh
            --consumer.config consumer.properties
            --producer.config producer.properties --whitelist my-topic
      
    --whitelistオプションを使ってトピックのリストを指定することに注意してください。このオプションはJava-style regular expressionsを使う全ての正規表現を許可します。つまり--whitelist 'A|B'を使ってABという名前の2つのトピックをミラーすることができます。あるいは--whitelist '*'を使って全てのトピックをミラーすることができます。シェルがファイルパスとして正規表現を展開しないように、全ての正規表現をクォートするようにしてください。便宜上、トピックのリストを指定するために '|' の代わりに ',' の仕様を許可します。

    何が欲しく無いかを言うことが簡単な時があります。ミラーされたくないことを述べるために--whitelistを使う代わりに、除外したいものを述べるために--blacklistを使うことができます。これも正規表現の引数を取ります。しかし、--blacklist は新しいコンシューマが有効にされた時にはサポートされません (つまり、bootstrap.servers がコンシューマの設定で定義された時)。

    ミラーリングと設定 auto.create.topics.enable=true と組み合わせると、新しいトピックが追加された時でもソースのクラスタ内の全てのデータを自動的に生成しレプリケートするレプリカクラスタを持つことができます。

    コンシューマの位置の調査

    コンシューマの位置を知るのに便利な時があります。コンシューマグループ内の全てのコンシューマの位置と、それらログの最後からどれだけ遅れているかを知るツールがあります。このツールをmy-topicという名前のトピックを消費しているmy-group という名前のコンシューマグループ上で実行するには、以下のようになるでしょう:
      > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group
    
      注意: これはJavaコンシューマAPI (ZooKeeperベースのコンシューマではない) を使うコンシューマについての情報のみを示すでしょう。
    
      TOPIC                          PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG        CONSUMER-ID                                       HOST                           CLIENT-ID
      my-topic                       0          2               4               2          consumer-1-029af89c-873c-4751-a720-cefd41a669d6   /127.0.0.1                     consumer-1
      my-topic                       1          2               3               1          consumer-1-029af89c-873c-4751-a720-cefd41a669d6   /127.0.0.1                     consumer-1
      my-topic                       2          2               3               1          consumer-2-42c1abd4-e3b2-425d-a8bb-e1ea49b29bb2   /127.0.0.1                     consumer-2
      
    このツールは ZooKeeperベースのコンシューマとも連携します:
      > bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --describe --group my-group
    
      注意: これはZooKeeperを使うコンシューマ(JavaコンシューマAPIを使うものでは無い)についての情報のみを示すでしょう。
    
      TOPIC                          PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG        CONSUMER-ID
      my-topic                       0          2               4               2          my-group_consumer-1
      my-topic                       1          2               3               1          my-group_consumer-1
      my-topic                       2          2               3               1          my-group_consumer-2
      

    コンシューマグループの管理

    ConsumerGroupCommand ツールを使って、コンシューマグループをリスト化、表現、削除することができます。新しいコンシューマAPI (ブローカーがパーティションの処理およびリバランスの調整を行う)を使う時、グループは手動で削除されるか、グループについての最後にコミットされたオフセットが期限切れになる時に自動的に削除されます。手動の削除はグループが何もアクティブなメンバーを持たない場合のみ動作します。例えば、全てのトピックに渡って全てのコンシューマグループをリスト化するには:
      > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
    
      test-consumer-group
      
    以前に述べたように、オフセットを見るには、以下のようにコンシューマグループを"describe"します:
      > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group
    
      TOPIC           PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG             CONSUMER-ID                                    HOST            CLIENT-ID
      topic3          0          241019          395308          154289          consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1      consumer2
      topic2          1          520678          803288          282610          consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1      consumer2
      topic3          1          241018          398817          157799          consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1      consumer2
      topic1          0          854144          855809          1665            consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1      consumer1
      topic2          0          460537          803290          342753          consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1      consumer1
      topic3          2          243655          398812          155157          consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1      consumer4
      
    新しいコンシューマAPIを使うコンシューマグループについてのより詳細な情報を提供するために使うことができる多くの追加の "describe" オプションがあります:
    • --members: このオプションはコンシューマグループ内の全てのアクティブなメンバーのリストを提供します。
            > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group --members
      
            CONSUMER-ID                                    HOST            CLIENT-ID       #PARTITIONS
            consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1      consumer1       2
            consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1      consumer4       1
            consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1      consumer2       3
            consumer3-ecea43e4-1f01-479f-8349-f9130b75d8ee /127.0.0.1      consumer3       0
            
    • --members --verbose: 上の "--members" オプションで報告される情報の上に、このオプションは各メンバに割り当てられたパーティションの情報も提供します。
            > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group --members --verbose
      
            CONSUMER-ID                                    HOST            CLIENT-ID       #PARTITIONS     ASSIGNMENT
            consumer1-3fc8d6f1-581a-4472-bdf3-3515b4aee8c1 /127.0.0.1      consumer1       2               topic1(0), topic2(0)
            consumer4-117fe4d3-c6c1-4178-8ee9-eb4a3954bee0 /127.0.0.1      consumer4       1               topic3(2)
            consumer2-e76ea8c3-5d30-4299-9005-47eb41f3d3c4 /127.0.0.1      consumer2       3               topic2(1), topic3(0,1)
            consumer3-ecea43e4-1f01-479f-8349-f9130b75d8ee /127.0.0.1      consumer3       0               -
            
    • --offsets: これはデフォルトの記述オプションで、"--describe" オプションと同じ出力を提供します。
    • --state: このオプションは有用なグループレベルの情報を提供します。
            > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group --state
      
            COORDINATOR (ID)          ASSIGNMENT-STRATEGY       STATE                #MEMBERS
            localhost:9092 (0)        range                     Stable               4
            
    1つ以上のコンシューマグループを手動で削除するには、"--delete" オプションを使うことができます:
      > bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --delete --group my-group --group my-other-group
    
      注意: これは古いZookeeperベースのコンシューマについての情報を表示しないでしょう。
      Deletion of requested consumer groups ('my-group', 'my-other-group') was successful.
      
    古い高レベルのコンシューマを使っていて、ZooKeeperにグループのメタデータが格納している場合(つまりoffsets.storage=zookeeper)、bootstrap-serverの代わりに--zookeeperを渡します:
      > bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --list
      

    クラスタの拡張

    Kafkaクラスタへサーバを追加することは簡単で、単にそれらにユニークなブローカーidを割り当て、新しいサーバ上でKafkaを開始します。しかし、これらの新しいサーバは自動的にデータのパーティションを割り当てられないでしょう。つまり、パーティションがそれらに移動されない場合、新しいトピックが作成されるまでそれらは何も仕事をしないでしょう。そのようにして通常はクラスタにマシーンを追加する時に何らかの既存のデータをこれらのマシーンに移設したいでしょう。

    データの移設のプロセスは手動で起動されますが、完全に自動化されます。背後では、Kafkaが新しいサーバを移設しているパーティションのフォロワーとして追加し、パーティション内の既存のデータを完全にレプリケートすることができます。新しいサーバがこのパーティションの内容を完全にレプリケートし同期のレプリカが加わった時に、既存のレプリカの1つがそれらのパーティションデータを削除するでしょう。

    ブローカーを超えてパーティションを移動するためにパーティション再割り当てツールを使うことができます。理想的なパーティションの分散は、全てのブローカーに渡って均等なデータの負荷とパーティションのサイズを保証するでしょう。パーティションの再割り当てツールは、自動的にKafkaクラスタ内のデータ分散を学習して負荷の均等な分散を行うためにパーティションを移動する機能はありません。そのように、管理者はどのトピックあるいはパーティションが周りに移動されなければならないかを見積もる必要があります。

    パーティションの再割り当てツールは3つの相互排他モードで実行することができます:

    • --generate: このモードでは、トピックのリストとブローカーのリストを指定し、ツールは指定されたトピックの全てのパーティションを新しいブローカーへ移動するための再割り当ての候補を生成します。このオプションは、トピックと目的のブローカーのリストが指定されたパーティションの再割り当て計画を生成する簡易な方法を提供するだけです。
    • --execute: このモードでは、ツールはユーザが提供した再割り当て計画に基づいたパーティションの再割り当て計画を開始します。(--reassignment-json-file オプションを使います)。これは、管理者によって手作りされた独自の再割り当て計画か、あるいは--generateオプションを使って提供されたもののどちらかかもしれません
    • --verify: このモードでは、ツールは最後の --execute の間リスト化された全てのパーティションについての再割り当ての状態を検証します。状態は、完全に完了した、失敗した、あるいは実行中のいずれかです
    新しいマシーンへのデータの自動的な移設
    パーティション再割り当てツールは現在のブローカーのセットから新しく追加されたブローカーへ幾つかのトピックを移動するのに使うことができます。トピック全体を新しいブローカーのセットへ移動するのが簡単なため、これは既存のクラスタを拡張し、1つのパーティションを同時に移動するのに有用です。これを使う時には、ユーザは新しいブローカーのセットに移動されるべきトピックのリストと目的の新しいブローカーのリストを提供する必要があります。ツールは結果的に指定されたトピックのリストについての全てのパーティションを新しいブローカーのセットに渡って分散します。この移動の間、トピックのリプリケーションのファクターは一定に保たれます。入力のトピックのリストについての全てのパーティションのレプリカは、古いブローカーのセットから新しく追加されたブローカーへ効果的に移動されます。

    例えば、以下の例はトピック foo1, foo2 の全てのパーティションを新しいブローカーのセット 5,6 へ移動するでしょう。この移動の最後に、トピック foo1 と foo2 の全てのパーティションはブローカー 5,6 にのみ存在します。

    ツールは入力のトピックのリストをjsonファイルとして受け付けるため、最初に移動したいトピックを識別し以下のようにjsonファイルを作成する必要があります:

      > cat topics-to-move.json
      {"topics": [{"topic": "foo1"},
                  {"topic": "foo2"}],
      "version":1
      }
      
    jsonファイルの準備ができると、候補の割り当てを生成するためにパーティション再割り当てツールを使います:
      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --topics-to-move-json-file topics-to-move.json --broker-list "5,6" --generate
      現在のパーティションのレプリカの割り当て
    
      {"version":1,
      "partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]},
                    {"topic":"foo1","partition":0,"replicas":[3,4]},
                    {"topic":"foo2","partition":2,"replicas":[1,2]},
                    {"topic":"foo2","partition":0,"replicas":[3,4]},
                    {"topic":"foo1","partition":1,"replicas":[2,3]},
                    {"topic":"foo2","partition":1,"replicas":[2,3]}]
      }
    
      指定されたパーティションの再割り当ての設定
    
      {"version":1,
      "partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]},
                    {"topic":"foo1","partition":0,"replicas":[5,6]},
                    {"topic":"foo2","partition":2,"replicas":[5,6]},
                    {"topic":"foo2","partition":0,"replicas":[5,6]},
                    {"topic":"foo1","partition":1,"replicas":[5,6]},
                    {"topic":"foo2","partition":1,"replicas":[5,6]}]
      }
      

    ツールはトピック foo1, foo2 からブローカー 5,6 へ全てのパーティションを移動する候補の割り当てを生成します。しかし、この時点では、パーティションの移動は開始されておらず、現在の割り当てと提案された新しい割り当てを知らせるだけなことに注意してください。ロールバックしたい場合は現在の割り当てが保存されなければなりません。新しい割り当ては、以下のように --execute オプションを使ってツールの入力になるように、jsonファイルに保存されなければなりません (例えば、expand-cluster-reassignment.json):

      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file expand-cluster-reassignment.json --execute
      現在のパーティションのレプリカの割り当て
    
      {"version":1,
      "partitions":[{"topic":"foo1","partition":2,"replicas":[1,2]},
                    {"topic":"foo1","partition":0,"replicas":[3,4]},
                    {"topic":"foo2","partition":2,"replicas":[1,2]},
                    {"topic":"foo2","partition":0,"replicas":[3,4]},
                    {"topic":"foo1","partition":1,"replicas":[2,3]},
                    {"topic":"foo2","partition":1,"replicas":[2,3]}]
      }
    
      ロールバックの間に --reassignment-json-file オプションとして使うために、これを保存します
      パーティションの再割り当ての開始の成功
      {"version":1,
      "partitions":[{"topic":"foo1","partition":2,"replicas":[5,6]},
                    {"topic":"foo1","partition":0,"replicas":[5,6]},
                    {"topic":"foo2","partition":2,"replicas":[5,6]},
                    {"topic":"foo2","partition":0,"replicas":[5,6]},
                    {"topic":"foo1","partition":1,"replicas":[5,6]},
                    {"topic":"foo2","partition":1,"replicas":[5,6]}]
      }
      

    最後に、パーティションの再割り当ての状態を調べるために、ツールと一緒に--verify オプションを使うことができます。--verify オプションと一緒に、同じ expand-cluster-reassignment.json (--execute オプションと一緒に使われた) が使われなければならないことに注意してください:

      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file expand-cluster-reassignment.json --verify
      パーティションの再割り当ての状態:
      Reassignment of partition [foo1,0] completed successfully
      Reassignment of partition [foo1,1] is in progress
      Reassignment of partition [foo1,2] is in progress
      Reassignment of partition [foo2,0] completed successfully
      Reassignment of partition [foo2,1] completed successfully
      Reassignment of partition [foo2,2] completed successfully
      
    独自のパーティションの割り当てと移設
    パーティション再割り当てツールはパーティションのレプリカを選択的に特定のブローカーのセットに移動するために使うこともできます。このように使った場合、--generateステップを効率的にスキップし--executeステップに直接移動しながら、ユーザが再割り当て計画を知っていて、ツールが候補の再割り当てを必要としないことを仮定します。

    例えば、以下の例はトピック foo1 の パーティション 0 を ブローカー 5,6 へ、トピック foo2 のパーティション 1 を ブローカー 2,3 へ移動します:

    最初のステップはjsonファイルに独自の再割り当て計画を手作りすることです:

      > cat custom-reassignment.json
      {"version":1,"partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]},{"topic":"foo2","partition":1,"replicas":[2,3]}]}
      
    そして --execute オプションにjsonファイルを使って、プロセスを再割り当てし始めます:
      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file custom-reassignment.json --execute
      現在のパーティションのレプリカの割り当て
    
      {"version":1,
      "partitions":[{"topic":"foo1","partition":0,"replicas":[1,2]},
                    {"topic":"foo2","partition":1,"replicas":[3,4]}]
      }
    
      ロールバックの間に --reassignment-json-file オプションとして使うために、これを保存します
      パーティションの再割り当ての開始の成功
      {"version":1,
      "partitions":[{"topic":"foo1","partition":0,"replicas":[5,6]},
                    {"topic":"foo2","partition":1,"replicas":[2,3]}]
      }
      

    パーティションの再割り当ての状態を調べるために、ツールに --verify オプションを使うことができます。--verify オプションと一緒に、同じ expand-cluster-reassignment.json (--execute オプションと一緒に使われた) が使われなければならないことに注意してください:

      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file custom-reassignment.json --verify
      パーティションの再割り当ての状態:
      Reassignment of partition [foo1,0] completed successfully
      Reassignment of partition [foo2,1] completed successfully
      

    ブローカーの縮退

    パーティション再割り当てツールはブローカーを退役するために再割り当て計画を自動的に生成する機能をまだ持っていません。そのため、管理者はブローカー上でホストされる全てのパーティションのためのレプリカを退役するために移動するための再割り当て計画をブローカーの残りに対して提供する必要があります。再割り当ては、全てのレプリカが廃止されたブローカーから他の1つだけのブローカーに移動されないようにする必要があるため、比較的面倒な作業かもしれません。このプロセスを容易くするために、退役するブローカーのためのツールのサポートを将来追加する予定です。

    リプリケーション要素の増加

    既存のパーティションのリプリケーション ファクターを増加することは容易です。独自の再割り当てjsonファイル内の余分なレプリカを単に指定し、指定されたパーティションのレプリケーション ファクタを増やすために --execute オプションと一緒に使います。

    例えば、以下の例はトピックfooのパーティション0のリプリケーション ファクターを1から3に増やします。リプリケーション ファクターを増やす前は、ブローカー5上にはパーティションのレプリカだけが存在します。レプリケーション ファクターの増加の一部として、ブローカー6と7にレプリカを追加するでしょう。

    最初のステップはjsonファイルに独自の再割り当て計画を手作りすることです:

      > cat increase-replication-factor.json
      {"version":1,
      "partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}
      
    そして --execute オプションにjsonファイルを使って、プロセスを再割り当てし始めます:
      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --execute
      現在のパーティションのレプリカの割り当て
    
      {"version":1,
      "partitions":[{"topic":"foo","partition":0,"replicas":[5]}]}
    
      ロールバックの間に --reassignment-json-file オプションとして使うために、これを保存します
      パーティションの再割り当ての開始の成功
      {"version":1,
      "partitions":[{"topic":"foo","partition":0,"replicas":[5,6,7]}]}
      

    パーティションの再割り当ての状態を調べるために、ツールに --verify オプションを使うことができます。--verify オプションと一緒に、同じ increase-replication-factor.json (--execute オプションと一緒に使われた) が使われなければならないことに注意してください:

      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file increase-replication-factor.json --verify
      パーティションの再割り当ての状態:
      Reassignment of partition [foo,0] completed successfully
      
    kafka-topicツールを使ってレプリケーション ファクターの増加を検証することもできます:
      > bin/kafka-topics.sh --zookeeper localhost:2181 --topic foo --describe
      Topic:foo	PartitionCount:1	ReplicationFactor:3	Configs:
        Topic: foo	Partition: 0	Leader: 5	Replicas: 5,6,7	Isr: 5,6,7
      

    データの移設の間の帯域の使い方の制限

    マシーンからマシーンへレプリカを移動するために使われる帯域に上限を設定して、Kafkaはレプリケーションのトラフィックに抑圧を適用します。これは、クラスタをリバランス、新しいブローカーをブートストラップ、ブローカーを削除する時に、それらのデータに集中的な操作がユーザに与える影響を制限するため、便利です。

    絞りを保証するために使うことができる2つのインタフェースがあります。最も単純で最も安全なのはkafka-reassign-partitions.shを起動する時に絞りを適用することですが、kafka-config.shは直接絞りの値を表示および変更するために使うこともできます。

    つまり、例えば前のコマンドを使ってリバランスを実行した場合、50MB/s未満でパーティションを移動するでしょう。
    $ bin/kafka-reassign-partitions.sh --zookeeper myhost:2181--execute --reassignment-json-file bigger-cluster.json —throttle 50000000
    このスクリプトを実行すると、絞りが行われるのが分かるでしょう。
      絞りの限界は 50000000 B/s に設定されていました
      パーティションの再割り当てが無事に開始されました

    Should you wish to alter the throttle, during a rebalance, say to increase the throughput so it completes quicker, you can do this by re-running the execute command passing the same reassignment-json-file:

    $ bin/kafka-reassign-partitions.sh --zookeeper localhost:2181  --execute --reassignment-json-file bigger-cluster.json --throttle 700000000
      既存の実行中の再割り当てがあります
      絞りの制限は 700000000 B/s に設定されていました

    リバランスがいったん完了すると、管理者は --verify オプションを使ってリバランスの状態を調べることができます。リバランスが完了すると、絞りは --verifyコマンドによって削除されるでしょう。--verify オプションと共にコマンドを実行することでリバランスが完了すると、管理者がしかるべき方法で絞りを削除することが重要です。それに失敗すると通常のレプリケーションのトラフィックが絞られるかもしれません。

    --verify オプションが実行され、再割り当てが完了すると、スクリプトは絞りが削除されたことを確認するでしょう:

      > bin/kafka-reassign-partitions.sh --zookeeper localhost:2181  --verify --reassignment-json-file bigger-cluster.json
      パーティションの再割り当ての状態:
      Reassignment of partition [my-topic,1] completed successfully
      Reassignment of partition [mytopic,0] completed successfully
      Throttle was removed.

    管理者はkafka-configs.shを使って割り当てられた設定を検証することもできます。絞りのプロセスを管理するために使われる絞りの設定の2つのペアがあります。絞り値自体。これは動的なプロパティを使ってブローカーレベルで設定されます:

    leader.replication.throttled.rate
      follower.replication.throttled.rate

    絞られたレプリカの列挙のセットもあります:

    leader.replication.throttled.replicas
      follower.replication.throttled.replicas

    これらはトピックごとに設定されます。4つ全ての設定値はkafka-reassign-partitions.shによって自動的に割り当てられます (以下で議論されます)。

    絞りの制限設定を見るには:

      > bin/kafka-configs.sh --describe --zookeeper localhost:2181 --entity-type brokers
      Configs for brokers '2' are leader.replication.throttled.rate=700000000,follower.replication.throttled.rate=700000000
      Configs for brokers '1' are leader.replication.throttled.rate=700000000,follower.replication.throttled.rate=700000000

    これはレプリケーションプロトコルのリーダーおよびフォロワーの両方に適用される絞りを示します。デフォルトでは両方の側は同じ絞られたスループットの値を割り当てられます。

    絞られたレプリカのリストを見るには:

      > bin/kafka-configs.sh --describe --zookeeper localhost:2181 --entity-type topics
      Configs for topic 'my-topic' are leader.replication.throttled.replicas=1:102,0:101,
          follower.replication.throttled.replicas=1:101,0:102

    ここで、リーダーの絞りがブローカー102上のパーティション1 および ブローカー101上のパーティション0に適用されることを見ます。同様にフォロワーの絞りはぶろかー101上のパーティション1およびブローカー102上のパーティション0に適用されます。

    デフォルトでは、kafka-reassign-partitions.sh はリーダーの絞りをリバランス前に存在する全てのレプリカに適用します。それらのうちの1つはリーダーかもしれません。それはフォロワーの絞りを全ての移動の宛先に適用します。つまり、ブローカー102, 103 に再割り当てされるブローカー101,102上のレプリカを持つパーティションがある場合、そのパーティションのリーダーの絞りは101,102に適用され、フォロワーの絞りは103だけに適用されるでしょう。

    必要であれば、絞りの設定を手動で変更するためにkafka-configs.shの--alterスイッチを使うこともできます。-

    絞られたレプリケーションの安全な使い方

    絞られたレプリケーションを使う時は幾らかの注意が必要です。実際には:

    (1) 絞りの削除:

    一旦再割り当てが完了すると、しかるべき方法で絞りを削除する必要があります (kafka-reassign-partitions --verifyを実行することで)。

    (2) 進捗の保証:

    入ってくる書き込みレートに比較して絞りがあまりに低く設定された場合、レプリケーションが進捗しないことがありえます。これは以下の時に起こります:

    max(BytesInPerSec) > throttle

    BytesInPerSec はプロデューサの各ブローカーへの書き込みスループットを監視するメトリックです。

    管理者は、以下のメトリックを使って、リバランスの間にレプリケーションが進捗しているかどうかを監視することができます:

    kafka.server:type=FetcherLagMetrics,name=ConsumerLag,clientId=([-.\w]+),topic=([-.\w]+),partition=([0-9]+)

    レプリケーションの間に遅延は定常的に減らなければなりません。メトリックが減らない場合、管理者は上で説明したように絞りのスループットを増やさなければなりません。

    クォータの設定

    クォータは、ここで説明されるように、(user, client-id)、ユーザあるいはクライアントidレベルで設定されるデフォルトを上書きします。デフォルトでは、クライアントは無制限のクォータを受け取ります。各 (user, client-id)、ユーザあるいはクライアントidグループ について、独自のクォータを設定することができます。

    (user=user1, client-id=clientA) についての独自のクォータを設定する:

      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-name user1 --entity-type clients --entity-name clientA
      エンティティ: user-principal 'user1', client-id 'clientA' について更新された設定。
      
    user=user1 についての独自のクォータを設定する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-name user1
      エンティティ: user-principal 'user1' について更新された設定。
      
    client-id=clientA について独自のクォータを設定する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-name clientA
      エンティティ: client-id 'clientA' について更新された設定。
      
    --entity-nameの代わりに--entity-defaultオプションを指定することで、各 (user, client-id)、ユーザあるいはクライアントidグループについてのデフォルトのクォータを設定することができます。

    user=userAについてのデフォルトのclient-id クォータを設定する:

      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-name user1 --entity-type clients --entity-default
      Updated config for entity: user-principal 'user1', default client-id.
      
    ユーザについてのデフォルトのクォータを設定する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-default
      エンティティ: デフォルト user-principal についての設定を更新する
      
    client-idについてのデフォルトのクォータを設定する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-default
      エンティティ: デフォルト client-id についての設定を更新する
      
    指定された (user, client-id) についてのクォータを説明する方法:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --describe --entity-type users --entity-name user1 --entity-type clients --entity-name clientA
      Configs for user-principal 'user1', client-id 'clientA' are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      
    指定された user についてのクォータを説明する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --describe --entity-type users --entity-name user1
      Configs for user-principal 'user1' are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      
    指定された client-id についてのクォータを説明する:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --describe --entity-type clients --entity-name clientA
      Configs for client-id 'clientA' are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      
    エンティティ名が指定されない場合、指定された型の全てのエンティティが説明されます。例えば、全てのユーザを説明するには:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --describe --entity-type users
      Configs for user-principal 'user1' are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      Configs for default user-principal are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      
    同様に、(user, client) については:
      > bin/kafka-configs.sh  --zookeeper localhost:2181 --describe --entity-type users --entity-type clients
      Configs for user-principal 'user1', default client-id are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      Configs for user-principal 'user1', client-id 'clientA' are producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200
      

    これらの設定をブローカーに設定することで、全てのクライアントidに適用されるデフォルトのクォータを設定することができます。これらのプロパティはクォータが上書きするか、デフォルトがZooKeeper内で設定されていない場合のみ適用されます。デフォルトでは、各クライアントidは無制限のクォータを受け取ります。以下はプロデューサとコンシューマ毎のデフォルトのクォータを 10MB/sec に設定します。

        quota.producer.default=10485760
        quota.consumer.default=10485760
      
    これらのプロパティは非推奨で、将来のリリースでは削除されるかもしれないことに注意してください。kafka-configs.shを使って設定されるデフォルトは、これらのプロパティよりも優先されます。

    6.2データセンタ

    幾つかの配備は複数のデータセンタをまたぐデータパイプラインを管理する必要があるでしょう。これのお勧めの方法は、各データセンター内でローカルクラスタ内でのみやり取りをしクラスタ間でミラーリングをするアプリケーション インスタンスを各データセンタ内でローカルKafkaクラスタを配備しすることです (これを行う方法についてはミラー メイカー ツールのドキュメントを見てください)。

    この配備のパターンによりデータセンタは依存しないエンティティとして振舞うことができ、中央集権的にデータセンター内を管理および調整することができます。これにより、データセンター間が利用不可であっても各ファシリティはスタンドアローンで操作することができます: これが起きた時、リンクが追いつく時点まで回復するまでミラーリングは遅れます。

    全てのデータのグローバルビューを必要とするアプリケーションのために、全てのデータセンター内のローカルクラスタからミラーされた集約データを持つクラスタを提供するためにミラーリングを使うことができます。これらの集約クラスタは完全なデータセットを必要とするアプリケーションによって読み込まれるために使われます。

    これは配備のパターンにだけ可能なわけではありません。WANを超えてリモートのKafkaクラスタから読み込みあるいは書き込みすることが可能ですが、これはクラスタを取得するために必要な何らかのレイテンシを追加するでしょう。

    Kafkaは本質的にプロデューサおよびコンシューマの両方の中にデータを揃えます。つまり高レイテンシの接続上であっても高スループットを達成することができます。しかしこれを可能にするには、socket.send.buffer.bytessocket.receive.buffer.bytesの設定を使って、プロデューサ、コンシューマおよびブローカーのTCPソケットバッファサイズを増やす必要があるかもしれません。これを設定する適切な方法はここで提供されます。

    高レンテンシのリンク上で複数のデータセンタに掛かる単独のKafkaクラスタを実行することは、一般的に望ましいものではありません。これはKafkaの書き込みおよびZookeeperの書き込みの両方に高レプリケーション レイテンシを招き、もし場所間のネットワークが利用できない場合にKafkaあるいはZooKeeperのどちらも全ての場所で利用できないままになるでしょう。

    6.3Kafka 設定

    重量なクライアント設定

    最も重要な古いScalaプロデューサの設定の制御
    • acks
    • 圧縮
    • sync vs async production
    • バッチ サイズ (非同期プロデューサのため)
    最も重要な新しいJavaプロデューサの設定の制御
    • acks
    • 圧縮
    • バッチ サイズ
    最も重要なコンシューマの設定はfetchサイズです。

    全ての設定は設定の章の中で提供されます。

    プロダクションのサーバ設定

    以下はプロダクションのサーバ設定の例です:
      # ZooKeeper
      zookeeper.connect=[list of ZooKeeper servers]
    
      # ログの設定
      num.partitions=8
      default.replication.factor=3
      log.dir=[ディレクトリのリスト。Kafka は独自の専用ディスク(s)あるいはSSD(s)を持つべきです]
    
      # 他の設定
      broker.id=[整数。0から開始し、新しいブローカー毎に1追加。]
      listeners=[リスナーのリスト]
      auto.create.topics.enable=false
      min.insync.replicas=2
      queued.max.requests=[同時実行リクエストの数]
      
    私たちのクライアントの構成はユースケースごとにかなり異なります。

    6.4Java バージョン

    自由に利用可能な古いバージョンはセキュリティ脆弱性が暴露されたため、セキュリティの観点から、JDK1.8の最新のリリースされたバージョンを使うことをお勧めします。LinkedInは現在のところG1コレクタを使ってJDK 1.8 u5を動かしています (新しいバージョンにアップグレードするように気を付けています)。LinkedInの調整は以下のようなものです:
      -Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC
      -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M
      -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80
      
    参照として、LinkedInの最も忙しいクラスタ(ピーク時)の1つのstatです:
    • 60 ブローカ
    • 50k パーティション (リプリケーション要素 2)
    • 800k メッセージ/秒 in
    • 300 MB/sec inbound, 1 GB/sec+ outbound
    調整はとても積極的に見えますが、クラスタ内の全てのブローカーは約21msの90% GC休止、そして秒間あたり1つのyoung GCを行っています。

    6.5ハードウェアとOS

    24GBのメモリを持つデュアル クアッド-コア Intel Xeon マシーンを使っています。

    アクティブ リーダーとライターをバッファするために十分なメモリが必要です。30秒間のバッファができるようにしたいと仮定することで、必要メモリの簡単な計算の推測と、必要なメモリをwrite_throughtput * 3 として計算できます。

    ディスクのスループットは重要です。8x7200 rpm SATA ドライブがあります。一般的に、ディスクのスループットはパフォーマンスのボトルネックで、ディスクが多いほうが良いです。フラッシュの挙動をどのように設定するかに依存して、より高価なディスクから恩恵を受けるか受けないかもしれません (しばしばフラッシュを強制する場合は、高い RPM SAS ドライブがより良いかもしれません)。

    OS

    Kafkaはどのようなunixシステム上でも良く動作する必要があり、LinuxおよびSolaris上でテストされています。

    Windows上での実行の2,3の問題を見つけました。Windowsは現在のところ良くサポートされたプラットフォームではありませんが、それを変えることができれば嬉しいです。

    多くのOSレベルの調整を必要とすることはないでしょうが、2つの潜在的な重要なOSレベルの設定があります:

    • ファイル ディスクリプタの制限: Kafkaはセグメントの記録と接続を開くためにファイルディスクリプタを使います。ブローカーが多くのパーティションをホストする場合は、ブローカーが作成する接続の数に加えて、全てのログセグメントを追跡するためにブローカーは少なくとも (number_of_partitions)*(partition_size/segment_size) を必要とすることを考慮してください。開始時点としてブローカーの処理のために少なくとも 100000 のファイルディスクリプタを許可することをお勧めします。
    • 最大ソケット バッファ サイズ: ここで説明されたようにデータセンタ間で高パフォーマンスのデータ転送を有効にするために増やされるかもしれません。

    ディスクとファイルシステム

    良いスループットを得るために複数のドライブを使い、良いレンテンシを保証するためにKafkaデータに使われるのと同じドライブをアプリケーションログあるいは他のOSファイルシステムの動作と共有しないことをお勧めします。これらのドライブを1つのボリュームにRAIDするか、独自のディレクトリとして各ドライブをフォーマットおよびmountすることができます。Kafkaはリプリケーションを持つため、RAIDによって提供される冗長性はアプリケーションレベルでも提供することができます。この選択には幾つかのトレードオフがあります。

    複数のデータディレクトリを設定する場合、パティションはデータディレクトリにラウンドロビンで割り当てられるでしょう。各パーティションは完全にデータディレクトリのうちの1つの中でしょう。もしデータがパーティション間で良くバランスされない場合、これはディスク間で負荷の不均衡につながるかもしれません。

    RAIDは負荷を低レベルでバランスするため、RAIDは潜在的にディスク間の負荷のバランスを良くします(しかし常にそうではないようにみえます)。RAIDの主な不利な点は、通常書き込みのスループットに大きな余分に掛かる負荷があり、利用可能なディスクスペースを減らします。

    RAIDの他の潜在的な恩恵はディスク障害への耐性です。しかし私たちの経験ではRAIDアレイの再構築はとてもI/Oが強烈で事実上サーバを使えなくします。つまりこれは現実的な可用性の改善を提供しません。

    アプリケーション 対 OSフラッシュ管理

    Kafkaは常にすぐに全てのデータをファイルシステムに書き込み、いつデータがフラッシュを使ってOSキャッシュからディスクに強制的に追い出すかを制御できるフラッシュポリシーを設定する機能をサポートします。このフラッシュポリシーは一定時間の後、あるいはある数のメッセージが書き込まれた後で強制的にデータをディスクに追い出すことを制御することができます。この設定には幾つかの選択があります。

    Kafkaはデータがフラッシュされたことを知るために結果的にfsyncを呼びます。クラッシュから回復する時に、fsyncしたかどうかを知らないログセグメントのためにKafkaはCRCをチェックすることで各メッセージの完全性を調べ、開始時に実行される回復プロセスの一部として付属するオフセットインデックスファイルも再構築するでしょう。

    故障したノードは常にそのレプリカから回復されるだろうため、Kafkaでの耐久性はディスクへの同期を必要としないことに注意してください。

    完全なアプリケーションの同期を無効にするデフォルトのフラッシュの設定を使うことをお勧めします。このことはOSによって行われるバックグラウンドのフラッシュとKafkaの独自のバックグランドのフラッシュを頼りにすることを意味します。これはほとんどの使い方にとって最善を提供します: 調整ツマミが無く、スループットとレイテンシが大きく、完全な回復保証。レプリケーションによって提供される保証がローカルディスクへの同期よりも強いと一般的に思いますが、偏執症な人はまだ両方を持つことを好むかも知れず、アプリケーションレベルのfsyncポリシーはまだサポートされます。

    アプリケーションレベルのフラッシュ設定を使う不利な点は、ディスクの使用パターンで非効率なことです(それにより書き込みを再び並べるのにOSに行動の自由がない)。バックグランドのフラッシュはページレベルのブロックであるのに対し、ほとんどのLinuxファイルシステムでのfsyncはファイルへの書き込みをブロックするため、レイテンシを導入するかもしれません。

    一般的にファイルシステムの低レベルの調整をする必要はありませんが、以下の幾つかの章ではそれが有用な場合に備えてこれの幾つか調べます。

    Linux OSのフラッシュの挙動の理解

    Linuxではファイルシステムへのデータの書き込みは(アプリケーションレベルのfsyncあるいはOS独自のフラッシュポリシーによって)ディスクに書き込まれなければならなくなるまで、ページキャッシュ内に維持されます。データのフラッシュはpdflush(あるいは以前の2.6.32カーネルでは"flusher threads")と呼ばれる一組のバックグランド スレッドによって行われます。

    Pdflush はどれだけ多くのdirtyデータがキャッシュ内に維持され、ディスクに書き戻されなければならなくなるまでどれだけ長く維持されるかを制御する設定可能なポリシーを持ちます。このポリシーはここで説明されます。When Pdflush cannot keep up with the rate of data being written it will eventually cause the writing process to block incurring latency in the writes to slow down the accumulation of data.

    以下を行うことでOSメモリの使用の現在の状態を見ることができます

     > cat /proc/meminfo 
    これらの値の意味は上のリンクで説明されます。

    ディスクに書き込まれるデータの格納について、pagecacheの使用はプロセス内のキャッシュよりいくつかの利点があります:

    • I/O スケジューラは連続する小さな書き込みをスループットを改善するより大きな物理書き込みに詰め込むでしょう。
    • I/O スケジューラはスループットを改善するディスクの移動の最小化のために書き込みを再順序化しようとするでしょう。
    • それは自動的にマシーン上のフリーなメモリの全てを使います

    ファイルシステムの選択

    Kafkaはディスク上の通常ファイルを使い、それ自体では特定のファイルシステムへの厳しい依存はありません。しかし最もよく使われる2つのファイルシステムは、EXT4 と XFS です。歴史的にはEXT4の使用が増えていますが、XFSファイルシステムの最近の改良により、安定性が損なわれることなくKafkaの作業のパフォーマンス特性が向上しています。.

    様々なファイルシステムの作成とmountオプションを使って、意味のあるメッセージの負荷を持つクラスタ上で比較テストが行われました。監視されるKafkaの主要なメトリックは "Request Local Time" で、追加操作が行われた時間を示します。XFS はより良いローカル時間 (最善のEXT4設定について 160ms 対 250ms+) と、より低い平均待ち時間の結果になりました。XFSのパフォーマンスもディスクパフォーマンスにおいて変わりにくいことを示しました。

    一般的なファイルシステムの注意
    Linuxシステム上で、データディレクトリに使われる全てのファイルシステムについて、以下のオプションがmount時に使われることをお勧めします:
    • noatime: このオプションは、ファイルが読み込まれる時にファイルのatime(最後のアクセス時間)属性の更新を無効にします。これは特にコンシューマが起動する場合のファイルシステムの書き込み数を取り除くことができます。Kafkaはatime属性を全く頼りにしないため、これを無効にしても安全です。
    XFSの注意
    XFS ファイルシステムは適切な多くの自動調整を持つため、ファイルシステムの作成時あるいはmount時のどちらかでデフォルトの設定に変更をする必要はありません。考慮する価値のある唯一の調整パラメータは以下の通りです:
    • largeio: これはstat呼び出しによって報告される優先I/Oサイズに影響します。これは大きなディスクの書き込みでよりパフォーマンスが高くなりますが、実際にはパフォーマンスには最小限あるいは全く効果がありません。
    • nobarrier: バッテリーで支援されるキャッシュを持つ背後にあるデバイスのためで、このオプションは定期的な書き込みフラッシュを無効にすることでほんの少しのパフォーマンスを提供することができます。しかし、もし背後にあるデバイスが良く振舞った場合、それはファイルシステムにフラッシュが必要無いと報告します。このオプションは影響が無いでしょう。
    EXT4の注意
    EXT4はKafkaデータディレクトリとしてファイルシステムの実用的な選択ですが、それで最善のパフォーマンスを得るには幾つかのmountオプションの調整を必要とするでしょう。更に、これらのオプションは一般的に障害時のシナリオで安全では無く、より多くのデータロスと衝突に終わるでしょう。1つのブローカーの障害については、ディスクは拭い取られレプリカがクラスタから再構築されるため、心配することはほとんどありません。停電のような複数の障害のシナリオにおいて、これは簡単には回復できない背後にあるファイルシステム(従ってデータ)の衝突を意味するかもしれません。以下のオプションが調節可能です:
    • data=writeback: Ext4のデフォルトは data=ordered で、いくつかの書き込みにおいて順番に強きを置きます。Kafkaは全てのフラッシュされていないログにとても偏執的なデータ回復を行うため、この順番は必要としません。この設定は順番の制約を削除し、レイテンシを極めて減らすように見えます。
    • ジャーナリングの無効: ジャーナリングはトレードオフです: サービスのクラッシュの後で再起動を高速化しますが、書き込みパフォーマンスへの変化をもたらす多くの追加のロックを導入します。再起動時間を気にせず、書き込みレイテンシのスパイクの主要な原因を減らしたい人は、ジャーナリングを完全に止めることができます。
    • commit=num_secs: これはext4がメタデータジャーナルにコミットする頻度を調整します。これを少ない値に設定すると、クラッシュ中のフラッシュされていないデータの紛失を減らします。これを大きな値に設定するとスループットを改善するでしょう。
    • nobh: この設定は data=writeback モードを使う時に追加の順番の保証を制御します。書き込みの順番に依存しないため、Kafkaではこれは安全に違いなく、スループットとレイテンシを改善します。
    • delalloc: Delayed allocation はファイルシステムが物理的な書き込みが発生するまでブロックの割り当てを避けることを意味します。これによりext4は小さなページの代わりに大きな範囲を割り当てることができ、データが連続して書き込まれることを保証します。この機能はスループットにとって素晴らしいです。ファイルシステム内でほんの少しのレイテンシの変化を追加するなんらかのロッキングを必要とするようです。

    6.6監視

    Kafkaはサーバ内とScalaクライアントのメトリクスレポートのためにYammer Metricsを使います。Java クライアントはKafkaメトリクス、クライアントアプリケーションにpullされる推移的依存を最小化する組み込みのメトリクスレジストリを使います。両方ともメトリクスをJMXを使って公開し、監視システムにホックアップするためにプラグ可能なstatsレポーターを使ってstatsをレポートするように設定することができます。

    全てのKafkaのレート メトリックにはサフィクス-totalが付いた対応する累積カウント メトリックがあります。例えば、records-consumed-raterecords-consumed-totalという名前の対応するメトリックを持ちます。

    利用可能なメトリクスを見る最も簡単な方法はjconsoleを立ち上げ、それを実行中のkafkaクライアントあるいはサーバに向けることです; これにより全てのメトリクスをJMXを使ってブラウズすることができるでしょう。

    以下のメトリクスをグラフおよびアラートします:
    説明 Mbean 名 通常値
    メッセージのレート kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec
    クライアントからのバイトのレート kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec
    他のブローカーからのバイトのレート kafka.server:type=BrokerTopicMetrics,name=ReplicationBytesInPerSec
    リクエストのレート kafka.network:type=RequestMetrics,name=RequestsPerSec,request={Produce|FetchConsumer|FetchFollower}
    エラー レート kafka.network:type=RequestMetrics,name=ErrorsPerSec,request=([-.\w]+),error=([-.\w]+) リクエスト型、エラーコード毎にカウントされた応答の中のエラーの数。応答が複数のエラーを含む場合は、全てがカウントされます。error=NONE indicates successful responses.
    リクエスト サイズのバイト kafka.network:type=RequestMetrics,name=RequestBytes,request=([-.\w]+) 各リクエストの型についてのリクエストのサイズ。
    一時的なメモリサイズのバイト kafka.network:type=RequestMetrics,name=TemporaryMemoryBytes,request={Produce|Fetch} メッセージ形式の変換と解凍のために使われる一時メモリ。
    メッセージの変換時間 kafka.network:type=RequestMetrics,name=MessageConversionsTimeMs,request={Produce|Fetch} メッセージ形式の変換に費やされる時間のミリ秒。
    メッセージの変換レート kafka.server:type=BrokerTopicMetrics,name={Produce|Fetch}MessageConversionsPerSec,topic=([-.\w]+) メッセージ形式の変換に必要なレコードの数。
    クライアントへのバイトのレート kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec
    他のブローカーへのバイトのレート kafka.server:type=BrokerTopicMetrics,name=ReplicationBytesOutPerSec
    ログのフラッシュレートと時間 kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMs
    # of under replicated partitions (|ISR| < |all replicas|) kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions 0
    # of under minIsr partitions (|ISR| < min.insync.replicas) kafka.server:type=ReplicaManager,name=UnderMinIsrPartitionCount 0
    # of offline log directories kafka.log:type=LogManager,name=OfflineLogDirectoryCount 0
    ブローカー上でコントローラがアクティブかどうか kafka.controller:type=KafkaController,name=ActiveControllerCount クラスタ内の唯一のブローカーが1つを持つ筈です
    リーダーの選出レート kafka.controller:type=ControllerStats,name=LeaderElectionRateAndTimeMs ブローカーの障害の時には非0
    消去されていないリーダーの選出レート kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSec 0
    パーティションの数 kafka.server:type=ReplicaManager,name=PartitionCount ほとんどはブローカーを横断して偶数
    リーダーのレプリカの数 kafka.server:type=ReplicaManager,name=LeaderCount ほとんどはブローカーを横断して偶数
    ISR のシュリンク レート kafka.server:type=ReplicaManager,name=IsrShrinksPerSec もしブローカーがダウンする場合、パーティションのISRはシュリンクするでしょう。ブローカーが再び上がる時、一旦レプリカが完全に追いつくとISRは一度拡大するでしょう。それと違う場合、ISRシュリンクレートと拡張レートの両方の期待値は0です。
    ISR 拡大レート kafka.server:type=ReplicaManager,name=IsrExpandsPerSec 上を見てください
    フォロワーとリーダーレプリカの間でのメッセージの最大の遅れ kafka.server:type=ReplicaFetcherManager,name=MaxLag,clientId=Replica 遅れは生成リクエストの最大バッチサイズに比例するべきです。
    フォロワーレプリカごとのメッセージの遅れ kafka.server:type=FetcherLagMetrics,name=ConsumerLag,clientId=([-.\w]+),topic=([-.\w]+),partition=([0-9]+) 遅れは生成リクエストの最大バッチサイズに比例するべきです。
    Requests waiting in the producer purgatory kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=Produce ack=-1 が使われる場合非0
    Requests waiting in the fetch purgatory kafka.server:type=DelayedOperationPurgatory,name=PurgatorySize,delayedOperation=Fetch サイズはコンシューマ内のfetch.wait.max.msに依存します
    リクエストの総時間 kafka.network:type=RequestMetrics,name=TotalTimeMs,request={Produce|FetchConsumer|FetchFollower} キュー、ローカル、リモートおよび応答の送信時間に分割されます
    リクエストがリクエストキューの中で待つ時間 kafka.network:type=RequestMetrics,name=RequestQueueTimeMs,request={Produce|FetchConsumer|FetchFollower}
    リクエストがリーダーで処理される時間 kafka.network:type=RequestMetrics,name=LocalTimeMs,request={Produce|FetchConsumer|FetchFollower}
    リクエストがフォロワーを待つ時間 kafka.network:type=RequestMetrics,name=RemoteTimeMs,request={Produce|FetchConsumer|FetchFollower} ack=-1の時はプロデューサのリクエストについては非0
    リクエストが応答キューの中で待つ時間 kafka.network:type=RequestMetrics,name=ResponseQueueTimeMs,request={Produce|FetchConsumer|FetchFollower}
    応答を送信する時間 kafka.network:type=RequestMetrics,name=ResponseSendTimeMs,request={Produce|FetchConsumer|FetchFollower}
    コンシューマがプロデューサに遅れるメッセージの数。ブローカーでは無く、コンシューマによって発表されます。

    古いコンシューマ: kafka.consumer:type=ConsumerFetcherManager,name=MaxLag,clientId=([-.\w]+)

    新しいコンシューマ: kafka.consumer:type=consumer-fetch-manager-metrics,client-id={client-id} Attribute: records-lag-max

    ネットワーク プロセッサが仕事をしていない平均断片時間 kafka.network:type=SocketServer,name=NetworkProcessorAvgIdlePercent 0と1の間。理想的には > 0.3
    リクエスト ハンドラのスレッドが仕事をしていない平均断片時間 kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent 0と1の間。理想的には > 0.3
    ユーザあるいはクライアントidごと(user, client-id)の帯域割り当てメトリクス kafka.server:type={Produce|Fetch},user=([-.\w]+),client-id=([-.\w]+) 2つの属性。throttle-time はクライアントが絞られていた総時間をミリ秒で示します。Ideally = 0. byte-rate はクライアントのデータの生成/消費レートを bytes/sec で示します。(user, client-id) 割り当て量については、ユーザおよびクライアントidの両方が指定されます。もしclient-id毎の割り当て量がクライアントに適用される場合は、ユーザは指定されません。もしuser毎の割り当てが適用される場合、クライアントidは指定されません。
    ユーザあるいはクライアントidごと (user, client-id)のリクエストの割り当て量のメトリクス kafka.server:type=Request,user=([-.\w]+),client-id=([-.\w]+) 2つの属性。throttle-time はクライアントが絞られていた総時間をミリ秒で示します。Ideally = 0. request-time はクライアントグループからリクエストを処理するためにブローカー ネットワークとI/Oスレッド内で費やされた時間のパーセンテージを示します。(user, client-id) 割り当て量については、ユーザおよびクライアントidの両方が指定されます。もしclient-id毎の割り当て量がクライアントに適用される場合は、ユーザは指定されません。もしuser毎の割り当てが適用される場合、クライアントidは指定されません。
    絞りを免れたリクエスト kafka.server:type=Request exempt-throttle-time は絞りを免れたリクエストを処理するためにブローカーネットワークとI/Oスレッドで費やされた時間のパーセンテージを示します。
    ZooKeeperのクライアント リクエストのレイテンシ kafka.server:type=ZooKeeperClientMetrics,name=ZooKeeperRequestLatencyMs ブローカーからのZooKeeperのリクエストについてのレイテンシのミリ秒。
    ZooKeeperの接続ステータス kafka.server:type=SessionExpireListener,name=SessionState ブローカーのZooKeeperセッションの接続ステータスで、Disconnected|SyncConnected|AuthFailed|ConnectedReadOnly|SaslAuthenticated|Expired のうちの1つが可能です。

    プロデューサ/コンシューマ/コネクタ/ストリームのための一般的な監視メトリクス

    以下のメトリクスがプロデューサ/コンシューマ/コネクタ/ストリーム インスタンス上で利用可能です。特定のメトリクスについては、以下の章を見てください。
    メトリック/属性 名 説明 Mbean 名
    connection-close-rate ウィンドウ内での秒間あたりの閉じられた接続 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    connection-creation-rate ウィンドウ内で秒間あたりに確立された新しい接続 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    network-io-rate 全ての接続の秒間あたりのネットワーク オペレーション(読み込みあるいは書き込み)の数の平均。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    外に行くバイトのレート 全てのサーバへの送信される外に行くバイトの秒間あたりの平均数。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    リクエスト レート 秒間あたり送信されるリクエストの平均数 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    リクエストのサイズの平均 ウィンドウ内の全てのリクエストの平均サイズ。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    リクエストサイズの最大 ウィンドウ内に送信されるリクエストの最大サイズ。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    やってくるバイトのレート 全てのソケットの読み込みのバイト/秒。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    応答レート Responses received sent per second. kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    select-rate I/O層が新しいI/Oを調べる秒間あたりの回数。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    io-wait-time-ns-avg I/Oスレッドが読み込みあるいは書き込みの準備ができたソケットを待つために費やした平均時間のナノ秒数。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    io-wait-ratio I/Oスレッドが待つのに費やした断片時間。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    io-time-ns-avg select呼び出しごとのI/Oの平均時間のナノ秒数。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    io-ratio I/OスレッドがI/Oを行うために費やした断片時間。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    connection-count 現在のアクティブな接続の数 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    successful-authentication-rate SASLあるいはSSLを使って認証が成功した接続。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)
    failed-authentication-rate 認証が失敗した接続。 kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)

    プロデューサ/コンシューマ/コネクタ/ストリームのためのブローカーごとの一般的なメトリクス

    以下のメトリクスがプロデューサ/コンシューマ/コネクタ/ストリーム インスタンス上で利用可能です。特定のメトリクスについては、以下の章を見てください。
    メトリック/属性 名 説明 Mbean 名
    外に行くバイトのレート ノードについての外に送信されるバイトの秒間あたりの平均数。 kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    リクエスト レート ノードについての秒間あたり送信されるリクエストの平均数 kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    リクエストのサイズの平均 ノードについてのウィンドウ内の全てのリクエストの平均サイズ。 kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    リクエストサイズの最大 ノードについてのウィンドウ内に送信されるリクエストの最大サイズ。 kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    やってくるバイトのレート ノードについての秒間あたり受信される応答の平均数 kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    request-latency-avg ノードについての平均リクエストレイテンシのms kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    request-latency-max ノードについての最大リクエストレイテンシのms kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)
    応答レート Responses received sent per second for a node. kafka.producer:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)

    プロデューサの監視

    以下のメトリクスがプロデューサのインスタンス上で利用可能です。
    メトリック/属性 名 説明 Mbean 名
    waiting-threads バッファメモリがレコードをキューに入れるのをブロックして待っているユーザスレッドの数。 kafka.producer:type=producer-metrics,client-id=([-.\w]+)
    buffer-total-bytes クライアントが利用することができるバッファメモリの最大量 (現在それが使われているかどうか)。 kafka.producer:type=producer-metrics,client-id=([-.\w]+)
    buffer-available-bytes 使用されていないバッファメモリの総量 (割り当てられていないかフリーのリストにあるかどちらか)。 kafka.producer:type=producer-metrics,client-id=([-.\w]+)
    bufferpool-wait-time appenderが空間の割り当てを待つ時間の割合。 kafka.producer:type=producer-metrics,client-id=([-.\w]+)
    プロデューサの送信のメトリクス
    kafka.producer:type=producer-metrics,client-id="{client-id}"
    属性名 説明
    batch-size-avgリクエスト毎のパーティション毎に送信されるバイトの平均数。
    batch-size-maxリクエスト毎のパーティション毎に送信されるバイトの最大数。
    batch-split-rate秒間あたりの平均バッチ分割数
    batch-split-totalバッチの総分割数
    compression-rate-avgレコード バッチの平均圧縮レート。
    metadata-age使用されている現在のプロデューサのメタデータの経過時間の秒。
    produce-throttle-time-avgブローカーによって絞られたリクエストの平均ms
    produce-throttle-time-maxブローカーによって絞られたリクエストの最大ms
    record-error-rateエラーになったレコード送信数の秒間あたりの平均
    record-error-totalエラーになったレコード送信数の総数
    record-queue-time-avgレコードバッチがsendバッファ内で費やした平均時間。
    record-queue-time-maxレコードバッチがsendバッファ内で費やした最大時間のms
    record-retry-rate再送信されたレコード数の秒間あたりの平均
    record-retry-total再送信されたレコードの総数
    record-send-rate秒間あたり送信されたレコードの平均数。
    record-send-total送信されたレコードの総数。
    record-size-avg平均レコードサイズ
    record-size-max最大レコードサイズ
    records-per-request-avgリクエスト毎のレコードの平均数。
    request-latency-avg平均リクエストレイテンシのms
    request-latency-max最大リクエストレイテンシのms
    requests-in-flight応答を待っている送信中のリクエストの現在の数。
    kafka.producer:type=producer-topic-metrics,client-id="{client-id}",topic="{topic}"
    属性名 説明
    byte-rateトピックについての送信されるバイトの秒間あたりの平均数。
    byte-totalトピックについての送信された総バイト数
    compression-rateトピックについてのレコード バッチの平均圧縮レート。
    record-error-rateトピックについてのエラーになったレコード送信数の秒間あたりの平均
    record-error-totalトピックについてのエラーになったレコード送信数の総数
    record-retry-rateトピックについての再送信されたレコード数の秒間あたりの平均
    record-retry-totalトピックについての再送信されたレコードの総数
    record-send-rateトピックについての送信されるレコードの秒間あたりの平均数。
    record-send-totalトピックについての送信された総レコード数

    新しいコンシューマの監視

    以下のメトリクスが新しいコンシューマのインスタンス上で利用可能です。
    コンシューマグループのメトリクス
    メトリック/属性 名 説明 Mbean 名
    commit-latency-avg コミット リクエストにかかる平均時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    commit-latency-max コミット リクエストにかかる最大時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    commit-rate 秒間あたりのコミット呼び出しの数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    assigned-partitions 現在のところこのコンシューマに割り当てられたパーティションの数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    heartbeat-response-time-max ハートビート リクエストへの応答を受信するのに掛かった最大時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    heartbeat-rate 秒間あたりのハートビートの平均数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    join-time-avg グループのrejoinにかかる平均時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    join-time-max グループのrejoinにかかる最大時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    join-rate 秒間あたりのグループjoinの数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    sync-time-avg グループのsyncにかかる平均時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    sync-time-max グループのsyncにかかる最大時間 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    sync-rate 秒間あたりのグループ同期の数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    last-heartbeat-seconds-ago 最後のコントローラーのハートビートからの秒数 kafka.consumer:type=consumer-coordinator-metrics,client-id=([-.\w]+)
    コンシューマのフェッチ メトリクス
    kafka.consumer:type=consumer-fetch-manager-metrics,client-id="{client-id}"
    属性名 説明
    bytes-consumed-rate秒間あたりに消費されるバイトの平均数
    bytes-consumed-total消費されるバイトの総数
    fetch-latency-avgフェッチリクエストにかかる平均時間
    fetch-latency-maxフェッチリクエストに掛かる最大時間。
    fetch-rate秒間あたりのフェッチリクエストの数。
    fetch-size-avgリクエスト毎にフェッチされる平均バイト数
    fetch-size-max秒間あたりにフェッチされる最大バイト数
    fetch-throttle-time-avg平均スロットル時間のms
    fetch-throttle-time-max最大スロットル時間のms
    fetch-totalフェッチリクエストの総数
    records-consumed-rate秒間あたりに消費される平均レコード数
    records-consumed-total消費されるレコードの総数
    records-lag-maxこのウィンドウ内の任意のパーティションについてレコード数という点での最大の遅延
    records-lead-minこのウィンドウ内の任意のパーティションについてレコード数という点での最小のリード数
    records-per-request-avg各リクエスト内の平均レコード数
    kafka.consumer:type=consumer-fetch-manager-metrics,client-id="{client-id}",topic="{topic}"
    属性名 説明
    bytes-consumed-rateトピックについての秒間あたりに消費されるバイトの平均数。
    bytes-consumed-totalトピックについての消費された総バイト数
    fetch-size-avgトピックについてのリクエスト毎にフェッチされる平均バイト数
    fetch-size-maxトピックについてのリクエスト毎にフェッチされる最大バイト数
    records-consumed-rateトピックについての秒間あたりに消費されるレコードの平均数。
    records-consumed-totalトピックについての消費された総レコード数
    records-per-request-avgトピックについての各リクエスト内の平均レコード数
    kafka.consumer:type=consumer-fetch-manager-metrics,partition="{partition}",topic="{topic}",client-id="{client-id}"
    属性名 説明
    records-lagパーティションの最新の遅延
    records-lag-avgパーティションの平均遅延
    records-lag-maxパーティションの最大遅延
    records-leadパーティションの最新のリード
    records-lead-avgパーティションの平均のリード
    records-lead-minパーティションの最小のリード

    接続の監視

    コネクトのワーカープロセスは全てのプロデューサとコンシューマのメトリクスと、コネクトに固有のメトリクスを含みます。ワーカープロセス自身は多くのメトリクスを持ちますが、各コネクタとタスクは追加のメトリクスを持ちます。
    kafka.connect:type=connect-worker-metrics
    属性名 説明
    connector-countこのワーカー内で実行されるコネクタの数。
    connector-startup-attempts-totalこのワーカーが試行したコネクタの開始の総数。
    connector-startup-failure-percentageこのワーカーのコネクタの開始が失敗した平均パーセンテージ。
    connector-startup-failure-totalコネクタの開始が失敗した総数。
    connector-startup-success-percentageこのワーカーのコネクタの開始が成功した平均パーセンテージ。
    connector-startup-success-totalコネクタの開始が成功した総数。
    task-countこのワーカー内で実行されるタスクの数。
    task-startup-attempts-totalこのワーカーが試行したタスクの開始の総数。
    task-startup-failure-percentageこのワーカーのタスクの開始が失敗した平均パーセンテージ。
    task-startup-failure-totalタスクの開始が失敗した総数。
    task-startup-success-percentageこのワーカーのタスクの開始が成功した平均パーセンテージ。
    task-startup-success-totalタスクの開始が成功した総数。
    kafka.connect:type=connect-worker-rebalance-metrics
    属性名 説明
    completed-rebalances-totalこのワーカーによって完了したリバランスの総数。
    epochこのワーカーのepochあるいは世代数。
    leader-nameグループリーダーの名前。
    rebalance-avg-time-msこのワーカーによってリバランスするのにかかった平均時間のミリ秒数
    rebalance-max-time-msこのワーカーによってリバランスするのに費やされた最大時間のミリ秒数。
    rebalancingこのワーカーが現在リバランスしているかどうか。
    time-since-last-rebalance-msこのワーカーが最も最近のリバランスを完了してからのミリ秒数。
    kafka.connect:type=connector-metrics,connector="{connector}"
    属性名 説明
    connector-classコネクタ クラスの名前
    connector-typeコネクタの型'source' あるいは 'sink' の1つ。
    connector-versionコネクタによって報告されたコネクタクラスのバージョン。
    状態コネクタの状態。'unassigned', 'running', 'paused', 'failed' または 'destroyed' のうちの1つ。
    kafka.connect:type=connector-task-metrics,connector="{connector}",task="{task}"
    属性名 説明
    batch-size-avgコネクタによって処理されたバッチの平均サイズ。
    batch-size-maxコネクタによって処理されたバッチの最大サイズ。
    offset-commit-avg-time-msこのタスクによってオフセットをコミットするのに掛かった平均時間のミリ秒数。
    offset-commit-failure-percentageこのタスクのオフセットのコミットの試行が失敗した平均パーセンテージ。
    offset-commit-max-time-msこのタスクによってオフセットをコミットするのにかかった最大時間のミリ秒数。
    offset-commit-success-percentageこのタスクのオフセットのコミットの試行が成功した平均パーセンテージ。
    pause-ratioこのタスクが休止状態で費やした断片時間。
    running-ratioこのタスクが実行中の状態で費やした断片時間。
    状態コネクタのタスクの状態。'unassigned', 'running', 'paused', 'failed' または 'destroyed' のうちの1つ。
    kafka.connect:type=sink-task-metrics,connector="{connector}",task="{task}"
    属性名 説明
    offset-commit-completion-rate完了が成功したオフセット コミットの完了の秒間あたりの平均数。
    offset-commit-completion-total完了が成功したオフセット コミットの完了の総数。
    offset-commit-seq-noオフセット コミットのための現在のシーケンス番号。
    offset-commit-skip-rateあまりに遅くスキップ/無視されたオフセット コミットの完了の秒間あたりの平均数。
    offset-commit-skip-totalあまりに遅くスキップ/無視されたオフセット コミットの完了の総数。
    partition-countこのワーカー内で名前付きのシンクコネクタへ所属するこのタスクに割り当てられるトピックパーティションの数。
    put-batch-avg-time-msこのタスクがシンクのレコードのバッチを格納するのに掛かる平均時間。
    put-batch-max-time-msこのタスクがシンクのレコードのバッチを格納するのに掛かる最大時間。
    sink-record-active-countKafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの数。
    sink-record-active-count-avgKafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの平均数。
    sink-record-active-count-maxKafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの最大数。
    sink-record-lag-maxシンクのタスクがどのトピックのパーティションに対してもコンシューマの位置よりも後ろにあるレコードの数という点での最大の遅延。
    sink-record-read-rateこのワーカー内の名前付きのシンク コネクタに所属するこのタスクについてKafkaから読み込まれるレコードの数の秒あたりの平均数。これは変換前が適用されます。
    sink-record-read-totalタスクが最後に再起動されてから、このワーカー内の名前付きのシンク コネクタに所属するこのタスクによってKafkaから読み込まれるレコードの総数。
    sink-record-send-rate変換から出力され、このワーカー内の名前付きのシンク コネクタに所属するこのタスクに送信/配置されたレコードの秒間あたりの平均数。これは変換後が適用され、変換によって除外された全てのレコードが除外されます。
    sink-record-send-total変換から出力され、タスクが最後に再起動されてから、このワーカー内の名前付きシンク コネクタに所属するこのタスクに送信/配置されたレコードの総数。
    kafka.connect:type=source-task-metrics,connector="{connector}",task="{task}"
    属性名 説明
    poll-batch-avg-time-msこのタスクがソースのレコードのバッチをポーリングするのに掛かる平均ミリ秒。
    poll-batch-max-time-msこのタスクがソースのレコードのバッチをポーリングするのに掛かる最大ミリ秒。
    source-record-active-countこのタスクによって生成されたがまだKafkaへ完全には書き込まれていないレコードの数。
    source-record-active-count-avgこのタスクによって生成されたがまだKafkaへ完全には書き込まれていないレコードの平均数。
    source-record-active-count-maxこのタスクによって生成されたがまだKafkaへ完全には書き込まれていないレコードの最大数。
    source-record-poll-rateこのワーカー内の名前付きのソース コネクタに所属するこのタスクによって(変換前に)生成/ポーリングされるレコードの数の秒あたりの平均数。
    source-record-poll-totalこのワーカー内の名前付きのソース コネクタに所属するこのタスクによって(変換前に)生成/ポーリングされるレコードの数の総数。
    source-record-write-rate変換から出力され、このワーカー内の名前付きのシンク コネクタに所属するこのタスクについてKafkaに書き込まれたレコードの秒間あたりの平均数。これは変換後が適用され、変換によって除外された全てのレコードが除外されます。
    source-record-write-total変換から出力され、タスクが最後に再起動されてから、このワーカー内の名前付きソース コネクタに所属するこのタスクについてKafkaに書き込まれたレコードの数。
    kafka.connect:type=task-error-metrics,connector="{connector}",task="{task}"
    属性名 説明
    deadletterqueue-produce-failuresデッド レター キューへの書き込みに失敗した数。
    deadletterqueue-produce-requestsデッド レター キューへの書き込み試行回数。
    last-error-timestampこのタスクが最後にエラーが発生した時のエポック タイムスタンプ。
    total-errors-logged記録されたエラーの数。
    total-record-errorsこのタスクのレコード処理エラーの数。
    total-record-failuresこのタスクのレコード処理失敗の数。
    total-records-skippedエラーによってスキップされたレコードの数。
    total-retries再試行されたオペレーションの数。

    ストリームの監視

    Kafka ストリームインスタンスは、全てのプロデューサとコンシューマのメトリクスと、ストリームに固有の追加のメトリクスを含みます。デフォルトで、Kafkaストリームは2つの記録レベルを持つメトリクスを持ちます: debug と info。debugレベルは全てのメトリクスを記録しますが、infoレベルはスレッドレベルのメトリクスのみを記録します。

    メトリクスは3層構造を持つことに注意してください。一番上のレベルとしてスレッド毎のメトリクスがあります。各スレッドは独自のメトリクスを持つタスクを持ちます。各タスクは独自のメトリクスを持つプロセッサーノードを持ちます。各タスクも独自のメトリクスを持つ多くの状態ストアとレコードキャッシュを持ちます。

    どのメトリクスを収集したいかを指定するために以下の設定オプションを使います:
    metrics.recording.level="info"
    スレッドのメトリクス
    以下の全てのメトリクスは``info``の記録レベルを持ちます:
    メトリック/属性 名 説明 Mbean 名
    commit-latency-avg このスレッドの全ての実行中のタスクに渡る、コミットのための平均実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    commit-latency-max このスレッドの全ての実行中のタスクに渡る、コミットのための最大実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    poll-latency-avg このスレッドの全ての実行中のタスクに渡る、ポーリングのための平均実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    poll-latency-max このスレッドの全ての実行中のタスクに渡る、ポーリングのための最大実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    process-latency-avg このスレッドの全ての実行中のタスクに渡る、処理のための平均実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    process-latency-max このスレッドの全ての実行中のタスクに渡る、処理のための最大実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    punctuate-latency-avg このスレッドの全ての実行中のタスクに渡る、パンクチュエートのための平均実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    punctuate-latency-max このスレッドの全ての実行中のタスクに渡る、パンクチュエートのための最大実行時間のミリ秒。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    commit-rate 秒間あたりのコミットの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    commit-total 全てのタスクに渡ってのコミット呼び出しの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    poll-rate 秒間あたりのpollの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    poll-total 全てのタスクに渡ってのpoll呼び出しの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    process-rate 秒間あたりの処理呼び出しの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    process-total 全てのタスクに渡っての処理呼び出しの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    punctuate-rate 秒間あたりの中断の平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    punctuate-total 全てのタスクに渡っての中断呼び出しの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    task-created-rate 秒間あたりに新しく生成されるタスクの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    task-created-total 作成されたタスクの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    task-closed-rate 秒間あたりに閉じられるタスクの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    task-closed-total 閉じられたタスクの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    skipped-records-rate 秒間あたりにスキップされるレコードの平均数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    skipped-records-total スキップされたレコードの総数。 kafka.streams:type=stream-metrics,client-id=([-.\w]+)
    タスクのメトリクス
    以下の全てのメトリクスは ``debug``の記録レベルを持ちます:
    メトリック/属性 名 説明 Mbean 名
    commit-latency-avg このタスクについての平均コミット時間のns。 kafka.streams:type=stream-task-metrics,client-id=([-.\w]+),task-id=([-.\w]+)
    commit-latency-max このタスクについての最大コミット時間のns。 kafka.streams:type=stream-task-metrics,client-id=([-.\w]+),task-id=([-.\w]+)
    commit-rate 秒間あたりのコミット呼び出しの平均数 kafka.streams:type=stream-task-metrics,client-id=([-.\w]+),task-id=([-.\w]+)
    commit-total コミット呼び出しの総数。 kafka.streams:type=stream-task-metrics,client-id=([-.\w]+),task-id=([-.\w]+)
    プロセッサーノードのメトリクス
    以下の全てのメトリクスは ``debug``の記録レベルを持ちます:
    メトリック/属性 名 説明 Mbean 名
    process-latency-avg 平均プロセス実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    process-latency-max 最大プロセス実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    punctuate-latency-avg 平均中断実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    punctuate-latency-max 最大中断実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    create-latency-avg 平均生成実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    create-latency-max 最大生成実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    destroy-latency-avg 平均破棄実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    destroy-latency-max 最大破棄実行時間のns。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    process-rate 秒間あたりの処理オペレーションの平均数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    process-total 呼び出された処理オペレーションの総数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    punctuate-rate 秒間あたりの中断オペレーションの平均数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    punctuate-total 呼び出された中断オペレーションの総数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    create-rate 秒間あたりの生成オペレーションの平均数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    create-total 呼び出された作成オペレーションの総数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    destroy-rate 秒間あたりの破棄オペレーションの平均数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    destroy-total 呼び出された破壊オペレーションの総数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    forward-rate ソースノードのみから、転送されるダウンストリームの秒間あたりのレコードの平均レート。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    forward-total ソースノードのみから、転送されるダウンストリームのレコードの総数。 kafka.streams:type=stream-processor-node-metrics,client-id=([-.\w]+),task-id=([-.\w]+),processor-node-id=([-.\w]+)
    応対ストアのメトリクス
    以下の全てのメトリクスは ``debug``の記録レベルを持ちます。``store-scope``値はユーザの独自の状態ストアのStoreSupplier#metricsScope()内で指定されることに注意してください; 組み込みの状態ストアについては、今のところ、in-memory-state, in-memory-lru-state, rocksdb-state (RocksDBが背後にあるキー-値ストア), rocksdb-window-state (RocksDBが背後にあるウィンドウ ストア) および rocksdb-session-state (RocksDBが背後にあるセッションストア) があります。
    メトリック/属性 名 説明 Mbean 名
    put-latency-avg 平均配置実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-latency-max 最大配置実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-if-absent-latency-avg 存在しない時に配置する平均実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-if-absent-latency-max 存在しない時に配置する最大実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    get-latency-avg 平均取得実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    get-latency-max 最大取得実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    delete-latency-avg 平均削除実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    delete-latency-max 最大削除実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-all-latency-avg put-all 実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-all-latency-max 最大 put-all 実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    all-latency-avg 全てのオペレーションの平均実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    all-latency-max 全てのオペレーションの最大実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    range-latency-avg 平均range実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    range-latency-max 最大range実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    flush-latency-avg 平均flush実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    flush-latency-max 最大flush実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    restore-latency-avg 平均回復時刻時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    restore-latency-max 最大回復実行時間のns。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-rate このストアについての平均putレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-total このストアについてのput呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-if-absent-rate このストアについての平均put-if-absentレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-if-absent-total このストアについてのput-if-absent呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    get-rate このストアについての平均getレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    get-total このストアについてのget呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    delete-rate このストアについての平均deleteレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    delete-total このストアについてのdelete呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-all-rate このストアについての平均put-allレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    put-all-total このストアについてのput-all呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    all-rate このストアについての全てのオペレーションの平均レート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    all-total このストアについての全てのオペレーション呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    range-rate このストアについての平均rangeレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    range-total このストアについてのrange呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    flush-rate このストアについての平均flushレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    flush-total このストアについてのflush呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    restore-rate このストアについての平均restoreレート。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    restore-total このストアについてのrestore呼び出しの総数。 kafka.streams:type=stream-[store-scope]-metrics,client-id=([-.\w]+),task-id=([-.\w]+),[store-scope]-id=([-.\w]+)
    レコード キャッシュのメトリクス
    以下の全てのメトリクスは ``debug``の記録レベルを持ちます:
    メトリック/属性 名 説明 Mbean 名
    hitRatio-avg The average cache hit ratio defined as the ratio of cache read hits over the total cache read requests. kafka.streams:type=stream-record-cache-metrics,client-id=([-.\w]+),task-id=([-.\w]+),record-cache-id=([-.\w]+)
    hitRatio-min 最小キャッシュ ヒット レシオ。 kafka.streams:type=stream-record-cache-metrics,client-id=([-.\w]+),task-id=([-.\w]+),record-cache-id=([-.\w]+)
    hitRatio-max 最大キャッシュ ヒット レシオ。 kafka.streams:type=stream-record-cache-metrics,client-id=([-.\w]+),task-id=([-.\w]+),record-cache-id=([-.\w]+)

    その他

    GC時間と他のstats、そしてCPU 利用率、I/O サービス 時間などのような様々なサーバのstatsを監視することをお勧めします。クライアント側ではメッセージ/バイト レート(グローバルとトピック毎)、リクエスト レート/サイズ/時間、そしてコンシューマー側では全てのパーティションに渡るメッセージ内の最大遅延と最小取得リクエストレートを監視することをお勧めします。コンシューマが遅れずについていくには、最大の遅延が閾値より少ない必要があり、最小の取得レートが0より大きい必要があります。

    監査

    私たちが行う最後の警告は、データの配送の正確さについてです。送信された各メッセージが全てのコンシューマによって消費されることを監査し、これが起こるための遅延を計測します。重要なトピックについては、もしある期間内に一定の完成度が達成されない場合に警告します。これの詳細はKAFKA-260で議論されます。

    6.7 ZooKeeper

    安定バージョン

    現在の安定ブランチは3.4で、ブランチの最新リリースは3.4.9です。

    ZooKeeperを操作可能にする

    操作上は、健全なZooKeeperのインストレーションのために以下を行います:
    • Redundancy in the physical/hardware/network layout: try not to put them all in the same rack, decent (but don't go nuts) hardware, try to keep redundant power and network paths, etc. 一般的なZooKeeperの集合は5または7のサーバを持ちます。これはそれぞれ2および3のサーバのダウンに耐性があります。もし小さな配備を持つ場合は、3つのサーバの使用が許容されますが、この場合1つのサーバのダウンのみに耐性があるだろうことを忘れないでください。
    • I/O 細分化: 書き込み型のトラフィックを多くする場合は、ほとんど間違いなく専用のディスクグループにトランザクションログが欲しいでしょう。トランザクションログへの書き込みは非同期(しかしパフォーマンスのためにバッチ化される)で、結果的に同時に起こる書き込みがパフォーマンスに極めて影響するかもしれません。ZooKeeperのスナップショットは同時に起こる書き込みのソースのようなものかもしれません。理想的にはトランザクションログとは別にディスクグループに書き込まれるべきです。スナップショットは非同期でディスクに書き込まれます。つまり、オペレーティングシステムとメッセージログファイルと一緒に共有することは一般的に大丈夫です。dataLogDirパラメータを持つ別個のディスクグループを持つようにサーバを設定することができます。
    • アプリケーションの分離: 同じbox上にインストールしたい他のアプリケーションのパターンを本当に理解しない限り、ZooKeeperを分離して実行することは良い考えかもしれません。(しかしこれはハードウェアの機能を使ったバランス行為かもしれません)。
    • Use care with virtualization: It can work, depending on your cluster layout and read/write patterns and SLAs, but the tiny overheads introduced by the virtualization layer can add up and throw off ZooKeeper, as it can be very time sensitive
    • ZooKeeperの設定: javaですので '十分な' ヒープ空間を与えるようにしてください (通常それらを3-5Gで実行しますが、それはほとんど持っているデータセットのサイズです)。残念ながらそれの良い計算式を持っていませんが、ZooKeeperの状態をより考慮することはスナップショットが大きくなるかもしれないことを意味し、大きなスナップショットは回復時間に影響します。実際、もしスナップショットがあまりに大きく(2,3ギガバイト)なると、サーバが回復し集合に加わるのに十分な時間を与えるためにinitLimit パラメータを増やす必要があるかもしれません。
    • 監視: JMX と 4文字の単語 (4lw) のコマンドはとても便利で、それらは時にはオーバーラップします(そしてそれらの場合私たちは4文字のコマンドを好みます。それらはより予想可能、あるいはそれらはLI監視インフラストラクチャーと良く連携することは確かです)
    • クラスタを建て過ぎないでください: 大きなクラスタ、特に書き込みが激しい使用パターンは多くのクラスタ内の通信(書き込みの定員とその後のクラスタメンバーの更新)を意味しますが、中途半端に建てないでください(リスクがクラスタを圧倒します)。サーバを増やすと、読み取りの容量が増えます。
    全体としては、私たちはZooKeeperシステムを仕事を処理できるだけ小さく(プラス標準的な成長可能性の計画)、できるだけ単純にしようとします。公式のリリースに比べて設定あるいはアプリケーションレイアウトに気まぐれなことをしないようにし、可能な限り自己内包し続けるようにします。これらの理由から、OSパッケージ化されたバージョンはOSの標準構造に配置する傾向があり、それは言うなれば'乱雑'に成り得るため、私たちはそれらをスキップしがちです。

    7. セキュリティ

    リリース 0.9.0.0で、Kafkaコミュニティは、個々にあるいは一緒に使われる、Kafkaクラスタのセキュリティを強める多くの機能を追加しました。以下のセキュリティ手段が現在のところサポートされます:
    1. SSLまたはSASLを使って、クライアント(プロデューサとコンシューマ)、他のブローカおよびツールからブローカーへの接続の認証。Kafkaは以下のSASL機構をサポートします:
      • SASL/GSSAPI (Kerberos) - バージョン0.9.0.0から
      • SASL/PLAIN - バージョン0.10.0.0から
      • SASL/SCRAM-SHA-256 and SASL/SCRAM-SHA-512 - バージョン 0.10.2.0から
      • SASL/OAUTHBEARER - バージョン 2.0から
    2. ブローカーからZooKeeperへの接続の認証
    3. SSLを使って、ブローカーとクライアント間、ブローカー間、あるいはブローカーとツール間で転送されるデータを暗号化 (SSLが有効な場合にパフォーマンスの低下があり、大きさはCPUの型とJVM実装に依存することに注意してください)。
    4. クライアントによる 読み込み/書き込み操作の認証
    5. 認証は差し込み可能で外部の認証サービスとの統合がサポートされます
    セキュリティは任意であることに留意する価値はあります - 非セキュアなクラスタ、認証の混合、非認証、暗号化と非暗号化のクライアントがサポートされます。以下の説明はクライアントとブローカーの両方でセキュリティ機能を設定および使う方法を説明します。

    7.2SSLを使った暗号化と認証

    Apache Kafka を使ってクライアントはSSL上で接続することができます。デフォルトでは、SSLは無効ですが、必要に応じて作動することができます。
    1. 各KafkaブローカーのためのSSLキーと証明書を生成する

      SSLをサポートする1つ以上のブローカーを配備する最初のステップは、クラスタ内の各マシーンのためにキーと証明書を生成することです。この作業を実行するためにJavaのキーツール ユーティリティを使うことができます。キーをエクスポートし後でCAを使って署名するために、最初にキーを一時的なキーストアに生成しましょう。
                  keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey -keyalg RSA
      上のコマンドの中で2つのパラメータを指定する必要があります:
      1. キーストア: 証明書を保存するキーストアファイル。キーストア ファイルは証明書の秘密鍵を含みます; 従って安全にしておく必要があります。
      2. 有効期間: 証明書の有効な期間の日数。

      ホスト名の検証の設定
      Kafkaバージョン 2.0.0以降から、クライアント接続と、中間者攻撃を避けるために内部ブローカー接続のために、デフォルトでサーバのホスト名検証が有効にされています。ssl.endpoint.identification.algorithmを空文字に設定することで、サーバホスト名の検証を無効にすることができます。例えば:
      	ssl.endpoint.identification.algorithm=
      動的に設定されたブローカーのリスナーについては、ホスト名の検証は kafka-configs.shを使って無効にすることができます。例えば:
              bin/kafka-configs.sh --bootstrap-server localhost:9093 --entity-type brokers --entity-name 0 --alter --add-config "listener.name.internal.ssl.endpoint.identification.algorithm="
              
      Kafkaの古いバージョンについては、ssl.endpoint.identification.algorithm はデフォルトでは定義されていないため、ホスト名の検証は行われません。ホスト名の検証を有効にするには、プロパティが HTTPS に設定されなければなりません。
      	ssl.endpoint.identification.algorithm=HTTPS 
      もしサーバのエンドポイントが外部的に検証されていない場合、中間者攻撃を避けるにはホスト名の検証が有効にされていなければなりません。
      証明書のホスト名の設定
      ホスト名の検証が有効の場合、クライアントはサーバの完全修飾ドメイン名(FQDN)を以下の2つのフィールドのうちの1つに対して検証するでしょう:
      1. 一般名 (CN)
      2. サブジェクトの別名 (SAN)

      両方のフィールドが有効ですが、RFC-2818 はSANの使用を勧めます。複数のDNSエントリが宣言されることで、SAN はもっと柔軟になります。他の利点はCNは認証目的のためのもっと意味のある値を設定することができることです。SANフィールドを追加するには、以下の引数 -ext SAN=DNS:{FQDN} をキーツールコマンドに追加します:
              keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey -keyalg RSA -ext SAN=DNS:{FQDN}
              
      以下のコマンドは生成された証明書の内容を検証するために後で実行することができます:
              keytool -list -v -keystore server.keystore.jks
              
    2. 独自のCAの生成

      最初のステップの後で、クラスタ内の各マシーンは公開-秘密キーのペアと、マシーンを識別するための証明書を持ちます。しかし証明書は署名されていません。このことは攻撃者が全てのマシーンの不利をするためにそのような証明書を作ることができることを意味します。

      従ってクラスタ内の各マシーンについてそれらを署名することで偽造された証明書を避けることは重要です。認証局(CA)は証明書の署名に責任があります。CAはパスポートを発行する政府機関のように動作します - 政府機関はパスポートを偽造することが難しくなるように各パスポートにスタンプを押し(署名)ます。他の政府機関はパスポートが信頼できることを保証するためにスタンプを検証します。同様に、CAは証明書を署名し、暗号は署名された証明書が計算上は偽造することが難しいことを保証します。従って、CAが本物で信頼された当局であれば、クライアントは信頼できるマシーンに接続していることを保証します。

                  openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
      生成されたCAは単純に公開-秘密鍵のペアと証明書で、他の証明書を署名する事を目的とします。次のステップはクライアントがこのCAを信頼できるように生成されたCAを **clients' truststore** に追加することです:
                  keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert
      注意: もしKafka brokers configで ssl.client.auth を "requested" あるいは "required" に設定することでKafkaブローカーがクライアントの認証を必要とするように設定する場合、Kafkaブローカーのためのトラストストアを提供しクライアントのキーが署名された全てのCA証明書を持つようにしなければなりません。
                  keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert
      各マシーンの独自の身元を格納するステップ1でのキーストアとは対照的に、クライアントのトラストストアはクライアントが信頼すべき全ての証明書を格納します。証明書をトラストストアにインポートすることはその証明書によって署名された全ての証明書を信頼することを意味します。上の例えから政府機関(CA)を信頼することは、発行した全てのパスポート(証明書)を信頼することも意味します。この特質は信頼の連鎖と呼ばれ、SSLを大規模なKafkaクラスタに配備する時に特に便利です。1つのCAを使ってクラスタ内の全ての証明書を署名することができ、全てのマシーンにそのCAを信頼する同じトラストストアを共有することができます。そのようにして全てのマシーンは全ての他のマシーンを認証することができます。
    3. 証明書の署名

      次のステップはステップ2で生成されたCAを使ってステップ1で生成された全ての証明書を署名することです。最初に、キーストアからの証明書をエクスポートする必要があります:
                  keytool -keystore server.keystore.jks -alias localhost -certreq -file cert-file
      そして、CAを使って署名します:
                  openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days {validity} -CAcreateserial -passin pass:{ca-password}
      最後にCAの証明書と署名された証明書をキーストアの両方をインポートする必要があります:
                  keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
                  keytool -keystore server.keystore.jks -alias localhost -import -file cert-signed
      パラメータの定義は以下の通りです:
      1. keystore: キーストアの場所
      2. ca-cert: CAの証明書
      3. ca-key: CAの秘密鍵
      4. ca-password: CAのパスフレーズ
      5. cert-file: エクスポートされた、サーバの未署名の証明書
      6. cert-signed: サーバの署名された証明書
      これは上の全てのステップを使ったbashスクリプトの例です。コマンドのうちの1つは`test1234`のパスワードを仮定し、つまり実行前にパスワードの使用あるいはコマンドの編集のどちらかをすることに注意してください。
                  #!/bin/bash
                  #Step 1
                  keytool -keystore server.keystore.jks -alias localhost -validity 365 -keyalg RSA -genkey
                  #Step 2
                  openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
                  keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert
                  keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert
                  #Step 3
                  keytool -keystore server.keystore.jks -alias localhost -certreq -file cert-file
                  openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days 365 -CAcreateserial -passin pass:test1234
                  keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
                  keytool -keystore server.keystore.jks -alias localhost -import -file cert-signed
    4. Kafkaブローカーの設定

      Kafkaブローカーは複数のポート上での接続のlistenをサポートします。server.properties 内で以下のプロパティを設定する必要があります。これは1つ以上のカンマ区切りの値を持つ必要があります:
      リスナー
      もしSSLが内部ブローカーの通信で有効で無い場合(有効にする方法は以下を見てください)、PLAINTEXT と SSL ポートの両方が必要になるでしょう。
                  listeners=PLAINTEXT://host.name:port,SSL://host.name:port
      以下のSSL設定がブローカー側で必要とされます
                  ssl.keystore.location=/var/private/ssl/server.keystore.jks
                  ssl.keystore.password=test1234
                  ssl.key.password=test1234
                  ssl.truststore.location=/var/private/ssl/server.truststore.jks
                  ssl.truststore.password=test1234
      注意: ssl.truststore.password は技術的には任意ですが強くお勧めします。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。考慮に値する任意の設定:
      1. ssl.client.auth=none ("required" => クライアントの認証が必要です、"requested" => クライアント認証が必要で、証明書なしのクライアントはまだ接続することができます。"requested"の使用は大丈夫だという誤った間隔を与え、間違ったクライアントはまだ接続に成功するだろうためお勧めできません。)
      2. ssl.cipher.suites (任意)。cipherスイートはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる認証、暗号、MACおよびキー交換アルゴリズムの組み合わせで名前を付けられます。(デフォルトは空のリストです)
      3. ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1 (クライアントから受け付けるつもりのSSLプロトコルをリスト化する。SSLはTLSに賛成して非推奨で、プロダクションでのSSLの使用はお勧めされないことに注意してください)
      4. ssl.keystore.type=JKS
      5. ssl.truststore.type=JKS
      6. ssl.secure.random.implementation=SHA1PRNG
      内部ブローカー通信のためにSSLを有効にしたい場合、以下を server.properties ファイル (デフォルトは PLAINTEXTです)に追加します
                  security.inter.broker.protocol=SSL

      幾つかの国での輸入規定により、Oracleの実装はデフォルトで利用可能な暗号アルゴリズムの挙動が制限されます。より強いアルゴリズム(例えば AES with 256-bit keys)が必要な場合JCE Unlimited Strength Jurisdiction Policy Files を取得しJDK/JRE にインストールする必要があります。詳しくはJCA Providers Documentationを見てください。

      JRE/JDKは暗号操作のために使われるデフォルトの疑似ランダム数字生成器(PRNG)を持つだろうため、使われる実装を設定する必要はありません

      ssl.secure.random.implementation
      . しかし、いくつかの実装ではパフォーマンスの問題があります (特にLinuxシステム上でのデフォルトの選択
      NativePRNG
      はグローバルロックを使います)。SSL接続のパフォーマンスが問題になる場合は、明示的に使用する実装の設定を考慮してください。The
      SHA1PRNG
      実装は非ブロッキングで高負荷でとても良いパフォーマンスの特徴を示しています (50 MB/sec of produced messages, plus replication traffic, per-broker)。

      一度ブローカーを開始すると、server.logで見ることができる筈です
                  with addresses: PLAINTEXT -> EndPoint(192.168.64.1,9092,PLAINTEXT),SSL -> EndPoint(192.168.64.1,9093,SSL)
      もしサーバのキーストアとトラストストアが適切にセットアップされているかをすばやく確認するために、以下のコマンドを実行することができます
      openssl s_client -debug -connect localhost:9093 -tls1
      (注意: TLSv1 は ssl.enabled.protocols の下にリスト化されているべきです)
      このマンドの出力の中にサーバの証明書を見る筈です:
                  -----BEGIN CERTIFICATE-----
                  {variable sized random bytes}
                  -----END CERTIFICATE-----
                  subject=/C=US/ST=CA/L=Santa Clara/O=org/OU=org/CN=Sriharsha Chintalapani
                  issuer=/C=US/ST=CA/L=Santa Clara/O=org/OU=org/CN=kafka/emailAddress=test@test.com
      もし証明書が現れないか、他のエラーメッセージがある場合は、キーストアが適切にセットアップされていません。
    5. Kafkaクライアントの設定

      SSLは新しいKafkaプロデューサとコンシューマでサポートされ、古いAPIはサポートされません。SSLの設定はプロデューサとコンシューマの両方で同じでしょう。
      もしクライアントの認証がブローカーで必要ではない場合、以下が最小の設定の例です:
                  security.protocol=SSL
                  ssl.truststore.location=/var/private/ssl/client.truststore.jks
                  ssl.truststore.password=test1234
      注意: ssl.truststore.password は技術的には任意ですが強くお勧めします。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。もしクライアントの認証が必要な場合、ステップ1でのようにキーストアが生成されなければならず、以下も設定されなければなりません:
                  ssl.keystore.location=/var/private/ssl/client.keystore.jks
                  ssl.keystore.password=test1234
                  ssl.key.password=test1234
      必要とされるかもしれない他の構成の設定は、要求とブローカーの設定によります:
      1. ssl.provider (任意)。SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。
      2. ssl.cipher.suites (任意)。cipherスイートはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる認証、暗号、MACおよびキー交換アルゴリズムの組み合わせで名前を付けられます。
      3. ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1. ブローカー側で設定される少なくとも1つのプロトコルがリスト化されるべきです
      4. ssl.truststore.type=JKS
      5. ssl.keystore.type=JKS

      コンソール-プロデューサとコンソール-コンシューマを使った例:
                  kafka-console-producer.sh --broker-list localhost:9093 --topic test --producer.config client-ssl.properties
                  kafka-console-consumer.sh --bootstrap-server localhost:9093 --topic test --consumer.config client-ssl.properties

    7.3SASLを使った認証

    1. JAAS 設定

      KafkaはSASL設定のためのJavaの認証と権限サービス(JAAS) を使います。

      1. KafkaブローカーのためのJAAS設定

        KafkaServer は各KafkaServer/ブローカーによって使われるJAASファイルでのセクション名です。このセクションは内部ブローカーのためにブローカーによって作成されたSASLクライアント接続を含むブローカーのためのSASL設定オプションを提供します。複数のlistenerがSASLを使うように設定される場合、セクション名はピリオドが続く小文字のlistener名が前に付くかもしれません。例えば sasl_ssl.KafkaServer

        Client セクションはzookeeperを使ったSASL接続を認証するために使われます。またブローカーだけがこれらのノードを変更できるように、これらのノードをロックするSASL ACLをブローカーがzookeeperノード上に設定することができます。全てのブローカーに渡って同じprincipal名を持つ必要があります。クライアント以外のセクション名を使いたい場合は、システムプロパティzookeeper.sasl.clientconfigを適切な名前 (例えば-Dzookeeper.sasl.clientconfig=ZkClient)に設定してください。

        ZooKeeperはデフォルトでサービス名として "zookeeper" を使います。もしこれを変更したい場合は、システムプロパティzookeeper.sasl.client.usernameを適切な名前 (例えば-Dzookeeper.sasl.client.username=zk)に設定してください。

      2. ブローカーはブローカー設定プロパティ sasl.jaas.configも使ってJAASを設定するかもしれません。プロパティ名はSASL機構を含むlistenerのプリフィックスを前に付けなければなりません。つまりlistener.name.{listenerName}.{saslMechanism}.sasl.jaas.config。設定値の中で1つのログインモジュールだけが指定されるかもしれません。もし複数の仕組みがlistener上で設定された場合、設定はlistenerと仕組みのプリフィックスを使って各機構ごとに提供されなければなりません。例えば:

                listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
                    username="admin" \
                    password="admin-secret";
                listener.name.sasl_ssl.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
                    username="admin" \
                    password="admin-secret" \
                    user_admin="admin-secret" \
                    user_alice="alice-secret";
        もしJAAS設定が異なるレベルで定義される場合、以下の優先度の順番が使われます:
        • ブローカーの設定プロパティ listener.name.{listenerName}.{saslMechanism}.sasl.jaas.config
        • 静的なJAAS設定の {listenerName}.KafkaServer セクション
        • 静的なJAAS設定の KafkaServer セクション
        ZooKeeper JAAS設定は静的なJAAS設定を使ってのみ設定されるかもしれないことに注意してください。

        ブローカーの設定の例についてはGSSAPI (Kerberos), PLAIN, SCRAM あるいは OAUTHBEARER を見てください。

    2. KafkaクライアントのためのJAAS設定

      クライアントは、クライアントの設定プロパティ sasl.jaas.config あるいはブローカーのように 静的な JAAS 設定ファイルを使って設定することができます。

      1. クライアントの設定プロパティを使ったJAAS 設定

        クライアントは物理的な設定ファイル無しにプロデューサあるいはコンシューマプロパティとしてJAAS設定を指定することができます。このモードはクライアントごとに異なるプロパティを指定することで同じJVM内の異なるプロデューサとコンシューマに異なる証明書を使うことができるようにもします。もし静的なJAAS設定システムプロパティjava.security.auth.login.config とクライアントプロパティ sasl.jaas.config の両方が指定された場合、クライアントプロパティが使われるでしょう。

        設定の例についてはGSSAPI (Kerberos), PLAIN, SCRAM あるいは OAUTHBEARER を見てください。

      2. 静的な設定ファイルを使ったJAAS設定
        静的なJAAS設定ファイルを使ってクライアント上でSASL認証を設定するには:
        1. KafkaClientという名前のクライアント ログイン セクションを持つJAAS設定ファイルを追加します。GSSAPI (Kerberos), PLAIN SCRAM あるいは OAUTHBEARERを設定するために、例の中で説明されたように選択された仕組みのための KafkaClient 内のログインモジュールを設定する。例えば、GSSAPI証明書は以下のように設定することができます:
                  KafkaClient {
                  com.sun.security.auth.module.Krb5LoginModule required
                  useKeyTab=true
                  storeKey=true
                  keyTab="/etc/security/keytabs/kafka_client.keytab"
                  principal="kafka-client-1@EXAMPLE.COM";
              };
        2. JVMパラメータとしてJAAS設定ファイルの場所を各クライアントのJVMに渡す。例えば:
              -Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf
  • SASL設定

    SASLはそれぞれセキュリティプロトコル SASL_PLAINTEXT あるいは SASL_SSL を使ってトランスポート層としてPLAINTEXTあるいはSSLと一緒に使われるかもしれません。もし SASL_SSL が使われた場合、SSLも設定されなければなりません

    1. SASL 機構
      Kafkaは以下のSASL機構をサポートします:
    2. Kafkaブローカーのための SASL 設定
      1. 少なくとも SASL_PLAINTEXT あるいは SASL_SSL のうちの1つを listeners パラメータに追加することで、server.properties内のSASLポートを設定します。これは1つ以上のカンマ区切りの値を含みます:
            listeners=SASL_PLAINTEXT://host.name:port
        SASLポートのみを設定している場合 (あるいはKafkaブローカーにSASLを使ってお互いを認証させたい場合)、内部ブローカーの通信のために同じSASLプロトコルを設定するようにしてください:
            security.inter.broker.protocol=SASL_PLAINTEXT (あるいは SASL_SSL)
      2. ブローカー内で有効にするために1つ以上のsupported mechanismsを選択し、仕組みのためのSASLを設定するためにステップに従います。ブローカー内で複数の仕組みを有効にするには、ここのステップに従ってください。
    3. KafkaクライアントのためのSASL設定

      SASL認証は新しいJava Kafkaプロデューサとコンシューマについてのみサポートされ、古いAPIはサポートされません。

      クライアント上でSASL認証を設定するには、クライアント認証のためにブローカー内で有効にされるSASL仕組みを選択し、選択された仕組みのためのSASLを設定するためにステップに従います。

  • SASL/Kerberos を使った認証

    1. 必要条件
      1. Kerberos
        組織がすでにKerberosサーバを使っている場合(例えば、Activeディレクトリを使って)、Kafkaのためだけに新しいサーバをインストールする必要はありません。そうでなければ、インストールする必要があります。LinuxのベンダーがおそらくKerberosのためのパッケージとそれをどうやってインストールおよび設定する方法についての概要を持っているでしょう (Ubuntu, Redhat)。Oracle Javaを使っている場合は、JavaバージョンのためのJCEポリシーファイルをダウンロードし、それらを $JAVA_HOME/jre/lib/security にコピーする必要があるでしょう。
      2. Kerberos Principalsの作成
        組織のKerberosあるいはActiveディレクトリ サーバを使っている場合は、(クライアントとツールを経由して)Kerberos認証を使ってKafkaにアクセスするだろうクラスタ内の各Kafkaブローカーと各オペレーティングシステムのユーザのためにKerberos管理者にprincipalを尋ねてください。
        もし独自のKerberosをインストールしている場合は、以下のコマンドを使ってそれらのprincipalを作成する必要があるでしょう:
                sudo /usr/sbin/kadmin.local -q 'addprinc -randkey kafka/{hostname}@{REALM}'
                sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}"
      3. 全てのホストがホスト名を使って到達可能であるようにしてください - それらのFQDNを使って全てのホストが解決可能であることがKerberosの要求です。
    2. Kafkaブローカーの設定
      1. 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう (各ブローカーは独自のkeytabを持つ必要があることに注意してください):
                KafkaServer {
                    com.sun.security.auth.module.Krb5LoginModule required
                    useKeyTab=true
                    storeKey=true
                    keyTab="/etc/security/keytabs/kafka_server.keytab"
                    principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
                };
        
                // Zookeeper client authentication
                Client {
                com.sun.security.auth.module.Krb5LoginModule required
                useKeyTab=true
                storeKey=true
                keyTab="/etc/security/keytabs/kafka_server.keytab"
                principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
                };
      2. JAASファイル内のKafkaServerセクションはブローカーにどのprincipalを使用するか、このprincipalが格納されているkeytabの場所を伝えます。それによりブローカーはこのセクションで指定されたkeytabを使ってログインすることができます。Zookeeper SASL設定の詳細についてはnotes を見てください。
      3. 各KafkaサーバにJAASと任意にkerb5ファイルの場所をJVMパラメータとして渡します (詳細は ここ を見てください):
            -Djava.security.krb5.conf=/etc/kafka/krb5.conf
                -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
      4. JAASファイル内で設定されたkeytabがkafkaブローカーを開始するオペレーティングシステムのユーザに読み込み可能であるようにしてください:
      5. ここで説明されるようにserver.properties内でSASLポートとSASL機構を設定します。例えば:
            listeners=SASL_PLAINTEXT://host.name:port
                security.inter.broker.protocol=SASL_PLAINTEXT
                sasl.mechanism.inter.broker.protocol=GSSAPI
                sasl.enabled.mechanisms=GSSAPI
                    
      6. server.properties 内でサービス名を設定する必要もあります。これはkafkaブローカーのprincipal名と一致しなければなりません。上の例では、principalは "kafka/kafka1.hostname.com@EXAMPLE.com"です。つまり:
            sasl.kerberos.service.name=kafka
    3. Kafkaクライアントの設定
      クライアント上でSASL認証を設定するには:
      1. クライアント (プロデューサ、コンシューマ、コネクト ワーカーなど)は独自のprincipal (通常はクライアントを実行するユーザと同じ名前と一緒に)を使ってクラスタを認証するでしょう。ですので必要に応じてこれらのprincipalを取得あるいは生成してください。そして、各クライアントについてJAAS設定プロパティを設定します。JVM内の子となるクライアントは異なるprincipalを指定することで異なるゆーあとして実行するかもしれません。producer.propertiesあるいはconsumer.properties内のプロパティsasl.jaas.configは、プロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続するかを説明します。以下はkeytab(長く実行するプロセスにお勧めです)を使ったクライアントのための設定例です:
            sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
                useKeyTab=true \
                storeKey=true  \
                keyTab="/etc/security/keytabs/kafka_client.keytab" \
                principal="kafka-client-1@EXAMPLE.COM";
        kafka-console-consumer あるいは kafka-console-producer のようなコマンドラインのユーティリティについては、"useTicketCache=true"と一緒にkinitを使うことができます:
            sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
                useTicketCache=true;
        別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。
      2. JAAS設定内で設定されたkeytabがkafkaクライアントを開始するオペレーティングシステムのユーザに読み込み可能であるようにしてください:
      3. 任意でkrb5ファイルの場所をJVMパラメータとして各クライアントJVMに渡します (詳細はここを見てください):
            -Djava.security.krb5.conf=/etc/kafka/krb5.conf
      4. 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
            security.protocol=SASL_PLAINTEXT (or SASL_SSL)
            sasl.mechanism=GSSAPI
            sasl.kerberos.service.name=kafka
  • SASL/PLAIN を使った認証

    SASL/PLAIN は安全な認証を実装するためのTLSで一般的に使われる暗号化のための単純な ユーザ名/パスワード 認証です。Kafkaはここで説明されるようにプロダクションでの使用のために拡張可能なSASL/PLAINのためのデフォルトの実装です。

    ユーザ名はACLなどの設定のための認証されたPrincipalとして使われます。
    1. Kafkaブローカーの設定
      1. 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
                KafkaServer {
                    org.apache.kafka.common.security.plain.PlainLoginModule required
                    username="admin"
                    password="admin-secret"
                    user_admin="admin-secret"
                    user_alice="alice-secret";
                };
        この設定は2つのユーザを定義します (adminalice)。KafkaServer セクション内のプロパティ usernamepasswordはブローカーによって他のブローカーへの接続を開始するために使われます。この例では、adminは内部ブローカー接続のためのユーザです。プロパティ user_userName のセットはブローカーへ接続する全てのユーザのためのパスワードを定義し、ブローカーはこれらのプロパティを使って他のブルーカーからの全てのクライアント接続を検証します。
      2. JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
            -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
      3. ここで説明されるようにserver.properties内でSASLポートとSASL機構を設定します。例えば:
            listeners=SASL_SSL://host.name:port
                security.inter.broker.protocol=SASL_SSL
                sasl.mechanism.inter.broker.protocol=PLAIN
                sasl.enabled.mechanisms=PLAIN
    2. Kafkaクライアントの設定
      クライアント上でSASL認証を設定するには:
      1. 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はPLAIN機構についてのクライアントのための設定例です:
            sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
                username="alice" \
                password="alice-secret";

        オプションusernamepassword はクライアント接続のためのユーザを設定するためにクライアントによって使われます。この例では、クライアントはブローカーにユーザ alice として接続します。JVM内の子となるクライアントはsasl.jaas.config内で異なるユーザ名とパスワードを指定することで、異なるユーザとして接続するかもしれません。

        別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。

      2. 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
            security.protocol=SASL_SSL
            sasl.mechanism=PLAIN
    3. プロダクションでの SASL/PLAIN の使用
      • SASL/PLAIN は明白なパスワードが暗号化無しに回線上を転送されないようにするために、トランスポート層としてSSLのみが使われるべきです。
      • KafkaでのSASL/PLAINのデフォルトの実装はここで示されるようにJAAS設定ファイル内でユーザ名とパスワードを指定します。Kafkaバージョン 2.0以降、設定オプション sasl.server.callback.handler.classsasl.client.callback.handler.class を使って外部ソースからユーザ名とパスワードを取得する独自のコールバック ハンドラを構成することで、ディスク上に平文のパスワードを格納することを避けることができます。
      • プロダクションのシステムでは、外部認証サーバがパスワード認証を実装するかもしれません。Kafkaバージョン 2.0以降、sasl.server.callback.handler.classを設定することでパスワード検証のための外部認証サーバを使う独自のコールバック ハンドラを差し込むことができます。
  • SASL/SCRAM を使った認証

    Salted Challenge Response Authentication Mechanism (SCRAM) はPLAINおよびDIGEST-MD5のようなユーザ名/パスワード認証を実施する伝統的な仕組みでのセキュリティの懸念を解消する一群のSASL機構です。仕組みはRFC 5802で定義されます。Kafkaは安全な認証を行うためにTLSと一緒に使うことができるSCRAM-SHA-256 と SCRAM-SHA-512 をサポートします。ユーザ名はACLなどの設定のための認証されたPrincipalとして使われます。KafkaでのデフォルトのSCRAM実装はZookeeper内にSCRAM認証を格納し、Zookeeperがプライベートネットワーク上にあるKafkaインストレーション内で使うのに適しています。詳細は セキュリティの考慮を参照してください。

    1. SCRAM 証明書の作成

      KafkaでのSCRAM 実装は証明書のストアとしてZookeeperを使います。証明書はkafka-configs.shを使ってZookeeper内で生成することができます。各SCRAM機構を有効にするために、証明書は機構名を持つ設定を追加することで生成されなければなりません。内部ブローカーの通信のための証明書はKafkaブローカーが開始される前に生成されなければなりません。クライアントの証明書は動的に生成および更新され、更新された証明書は新しい接続の認証のために使われるでしょう。

      パスワードalice-secretを持つユーザaliceのためのSCRAM証明書の作成:

          > bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=alice-secret],SCRAM-SHA-512=[password=alice-secret]' --entity-type users --entity-name alice
              

      iterationが指定されない場合は、デフォルトの繰り返しカウントの4096が使われます。ランダムなsaltが生成され、salt, iterations, StoredKey と ServerKey から成るSCRAM証明がZookeeperに格納されます。SCRAM証明と個々のフィールドについての詳細はRFC 5802 を見てください。

      以下の例は、以下を使って作成することができる内部ブローカー通信のためのユーザadminも必要とします:

          > bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[password=admin-secret],SCRAM-SHA-512=[password=admin-secret]' --entity-type users --entity-name admin
              

      既存の証明書は--describe オプションを使ってリスト化することができます:

          > bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-type users --entity-name alice
              

      証明書は--delete オプションを使って1つ以上のSCRAM機構について削除することができます:

          > bin/kafka-configs.sh --zookeeper localhost:2181 --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name alice
              
    2. Kafkaブローカーの設定
      1. 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
            KafkaServer {
                org.apache.kafka.common.security.scram.ScramLoginModule required
                username="admin"
                password="admin-secret";
            };
        KafkaServerセクション内のプロパティ usernamepasswordはブローカーによって他のブローカーへの接続を始めるために使われます。この例では admin が内部ブローカー通信のためのユーザです。
      2. JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
            -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
      3. ここで説明されるようにserver.properties内でSASLポートとSASL機構を設定します。 例えば:
            listeners=SASL_SSL://host.name:port
            security.inter.broker.protocol=SASL_SSL
            sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256 (あるいは SCRAM-SHA-512)
            sasl.enabled.mechanisms=SCRAM-SHA-256 (あるいは SCRAM-SHA-512)
    3. Kafkaクライアントの設定
      クライアント上でSASL認証を設定するには:
      1. 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はSCRAM機構のためのクライアントのための設定の例です:
           sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
                username="alice" \
                password="alice-secret";

        オプションusernamepassword はクライアント接続のためのユーザを設定するためにクライアントによって使われます。この例では、クライアントはブローカーにユーザ alice として接続します。JVM内の子となるクライアントはsasl.jaas.config内で異なるユーザ名とパスワードを指定することで、異なるユーザとして接続するかもしれません。

        別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。

      2. 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
            security.protocol=SASL_SSL
            sasl.mechanism=SCRAM-SHA-256 (あるいは SCRAM-SHA-512)
    4. Security Considerations for SASL/SCRAM
      • Kafkaでの SASL/SCRAM のデフォルトの実装はSCRAM証明をZookeeperに格納します。これはZookeeperが安全でプライベートネットワーク上にあるインストレーション内でのプロダクションの使用に適しています。
      • Kafkaは最小繰り返しカウントが4096の強いハッシュ関数 SHA-256 と SHA-512 のみをサポートします。強いパスワードと高い繰り返しカウントとの強いハッシュ関数の組み合わせは、Zookeeperのセキュリティが損なわれた場合でもブルートフォースアタックに対抗します。
      • SCRAMはSCRAMの交換の妨害を避けるためにTLS暗号化と一緒の場合のみ使われるべきです。これは辞書攻撃あるいはブルートフォースアタックから保護し、Zookeeperが損なわれたとしても成り済ましから保護します。
      • Kafkaバージョン 2.0以降、ZooKeeperが安全では無いインストレーション内でsasl.server.callback.handler.class を設定することで、独自のコールバック ハンドラを使ってデフォルトのSASL/SCRAM証明ストアを上書きすることができます。
      • セキュリティの考慮についての詳細はRFC 5802を参照してください。
  • SASL/OAUTHBEARER を使った認証

    OAuth 2 Authorization Framework " は、リソースの所有者とHTTPサービスの間の認証のやり取りを調整することでリソースの所有者の代わりに、あるいはサードパーティアプリケーションが代理のアクセス権限を取得できるようにすることのどちらかで、サードパーティアプリケーションがHTTPサービスへの制限付きアクセスを取得することができます。" SASL OAUTHBEARERの仕組みはSASL(つまり非-HTTP)コンテキスト内でフレームワークを使用することができます; それは RFC 7628 で定義されています。Kafkaでのデフォルトの OAUTHBEARER の実装はUnsecured JSON Web Tokens を生成および検証し、プロダクションではないKafkaインストレーションでの使用にのみ適しています。詳細は セキュリティの考慮を参照してください。

    1. Kafkaブローカーの設定
      1. 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
            KafkaServer {
                org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required
                unsecuredLoginStringClaim_sub="admin";
            };
        KafkaServerのセクションのプロパティunsecuredLoginStringClaim_subは、ブローカが他のブローカーに接続を始める時にブローカーによって使われます。この例では、adminは件名 (sub) 要求に現れ、ブローカー間の通信のためのユーザになるでしょう。
      2. JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
            -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
      3. ここで説明されるようにserver.properties内でSASLポートとSASL機構を設定します。 例えば:
            listeners=SASL_SSL://host.name:port (or SASL_PLAINTEXT if non-production)
            security.inter.broker.protocol=SASL_SSL (or SASL_PLAINTEXT if non-production)
            sasl.mechanism.inter.broker.protocol=OAUTHBEARER
            sasl.enabled.mechanisms=OAUTHBEARER
    2. Kafkaクライアントの設定
      クライアント上でSASL認証を設定するには:
      1. 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はOAUTHBEARER機構のためのクライアントのための設定の例です:
           sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
                unsecuredLoginStringClaim_sub="alice";

        オプションunsecuredLoginStringClaim_subは件名 (sub) 要求を設定するためにクライアントによって使われます。これはクライアント接続のためのユーザを定義します。この例では、クライアントはブローカーにユーザ alice として接続します。JVM内の異なるクライアントはsasl.jaas.config内で異なる件名 (sub) 要求を指定することで異なるユーザとして接続することができます。

        別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。

      2. 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
            security.protocol=SASL_SSL (or SASL_PLAINTEXT if non-production)
            sasl.mechanism=OAUTHBEARER
      3. SASL/OAUTHBEARER のデフォルトの実装は jackson-databind ライブラリに依存します。それは任意の依存のため、ユーザはそれらのビルドツールを使って依存としてそれを設定する必要があります。
    3. SASL/OAUTHBEARERのための安全では無いトークンの作成オプション
      • Kafkaでの SASL/OAUTHBEARER のデフォルトの実装は、Unsecured JSON Web Tokensを作成し検証します。非プロダクションの使用にのみ適していますが、開発あるいはテスト環境で任意のトークンを作成するための柔軟性を提供します。
      • これらはクライアント側 (そしてもし OAUTHBEARER が内部ブローカー プロトコルの場合ブローカー側)での様々なサポートされるJAASモジュールオプションです:
        安全では無いトークンの作成のためのJAASモジュールオプション ドキュメント
        unsecuredLoginStringClaim_<claimname>="value" 指定された名前と値の文字列の要求を作成します。'iat' と 'exp' (これらは自動的に生成されます)を除く任意の有効な要求名を指定することができます。
        unsecuredLoginNumberClaim_<claimname>="value" 指定された名前と値の Number 要求を作成します。'iat' と 'exp' (これらは自動的に生成されます)を除く任意の有効な要求名を指定することができます。
        unsecuredLoginListClaim_<claimname>="value" 最初の文字がデリミタとして取られる指定された値からパースされた名前と値を持つ String List 要求を作成します。例えば: unsecuredLoginListClaim_fubar="|value1|value2". 'iat' と 'exp' (これらは自動的に生成されます)を除く任意の有効な要求名を指定することができます。
        unsecuredLoginPrincipalClaimName プリンシパル名が 'sub'以外の何かであるString 要求の名前を望む場合、独自の要求名を設定してください。
        unsecuredLoginLifetimeSeconds トークンの有効期限をデフォルトの値である3600秒(これは1時間)以外の何かに設定する場合、整数値を設定してください。'exp' 要求は祐くお起源を反映するために設定されるでしょう。
        unsecuredLoginScopeClaimName 任意のトークンスコープが'scope'以外の何かである String あるいは String List 要求の名前を望む場合、独自の要求名を設定してください。
    4. SASL/OAUTHBEARERのための安全では無いトークンの検証オプション
      • これらはUnsecured JSON Web Token検証のためのブローカー側での様々なサポートされるJAASモジュールオプションです:
        安全では無いトークンの検証のためのJAASモジュールオプション ドキュメント
        unsecuredValidatorPrincipalClaimName="value" プリンシパル名を保持する特定の String 要求が存在することを調べたい場合は、空では無い値を設定します; デフォルトは'sub' 要求の存在をチェックします。
        unsecuredValidatorScopeClaimName="value" 任意のトークンスコープが'scope'以外の何かである String あるいは String List 要求の名前を望む場合、独自の要求名を設定してください。
        unsecuredValidatorRequiredScope="value" トークン スコープを保持する String/String List 要求が特定の値が含むことを確認したい場合は、スコープの値の空白区切りのリストを設定します。
        unsecuredValidatorAllowableClockSkewMs="value" 正の数ミリ秒のクロック スキューを許容したい場合は、正の整数値を設定します(デフォルトは0です)。
      • デフォルトの安全では無い SASL/OAUTHBEARER 実装は、独自のログインおよびSASLサーバ コールバック ハンドラを使って上書きすることができます(そしてプロダクションでは上書きされるべきです)。
      • セキュリティの考慮についての詳細は RFC 6749, Section 10を参照してください。
    5. SASL/OAUTHBEARER のためのトークンのリフレッシュ
      Kafkaはクライアントがブローカーに接続を続けることができるように、期限切れになる前に定期的に全てのトークンをリフレッシュします。リフレッシュアルゴリズムがどのように操作するかに影響を与えるパラメータは プロデューサ/コンシューマ/ブローカー設定の一部として指定され、以下の通りです。See the documentation for these properties elsewhere for details. デフォルトの値は通常は妥当です。その場合、これらの設定パラメータを明示的に設定する必要はないでしょう。
      プロデューサ/コンシューマ/ブローカー 設定プロパティ
      sasl.login.refresh.window.factor
      sasl.login.refresh.window.jitter
      sasl.login.refresh.min.period.seconds
      sasl.login.refresh.min.buffer.seconds
    6. SASL/OAUTHBEARER の セキュア/プロダクションの使用
      プロダクションの使用例ではorg.apache.kafka.common.security.oauthbearer.OAuthBearerTokenCallbackのインスタンスを処理することができるorg.apache.kafka.common.security.auth.AuthenticateCallbackHandlerの実装を書き、それを非ブローカークライアントについてはsasl.login.callback.handler.class 設定オプションまたはブローカー(SASL/OAUTHBEARERが内部ブローカープロトコルの場合)については listener.name.sasl_ssl.oauthbearer.sasl.login.callback.handler.class設定オプションのどちらかを使って宣言する必要があるでしょう。

      プロダクションの使用例ではorg.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackのインスタンスを処理することができるorg.apache.kafka.common.security.auth.AuthenticateCallbackHandlerの実装を書き、それをlistener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class ブローカー設定オプションを使って宣言する必要もあるでしょう。

    7. SASL/OAUTHBEARER のセキュリティの考慮
      • Kafkaでの SASL/OAUTHBEARER のデフォルトの実装は、Unsecured JSON Web Tokensを作成し検証します。これは非プロダクションの使用のためのみに適しています。
      • OAUTHBEARER はプロダクション環境ではトークンの傍受を避けるためにTLS-encryptionと一緒にのみ使われるべきです。
      • デフォルトの安全では無いSASL/OAUTHBEARER 実装は上で説明したように独自のloginおよびSASLサーバ コールバック ハンドラを使って上書きすることができます (そしてプロダクション環境では上書きされるべきです)。
      • 一般的なOAuth 2 セキュリティの考慮についての詳細は RFC 6749, Section 10を参照してください。
  • ブローカー内での複数のSASL機構を有効化

    1. JAAS設定ファイルのKafkaServerセクション内の全ての有効にされた仕組みのログインモジュールのための構成を指定します。例えば:
              KafkaServer {
                  com.sun.security.auth.module.Krb5LoginModule required
                  useKeyTab=true
                  storeKey=true
                  keyTab="/etc/security/keytabs/kafka_server.keytab"
                  principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
      
                  org.apache.kafka.common.security.plain.PlainLoginModule required
                  username="admin"
                  password="admin-secret"
                  user_admin="admin-secret"
                  user_alice="alice-secret";
              };
    2. server.properties内のSASL機構を有効にする:
          sasl.enabled.mechanisms=GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512,OAUTHBEARER
    3. 必要であればserver.properties内の内部ブローカー通信のためのSASLセキュリティプロトコルと仕組みを指定します:
          security.inter.broker.protocol=SASL_PLAINTEXT (あるいは SASL_SSL)
          sasl.mechanism.inter.broker.protocol=GSSAPI (あるいは他の有効にされた仕組みのうちの1つ)
    4. 有効にされた機構のためのSASLを設定するためにGSSAPI (Kerberos), PLAIN, SCRAM および OAUTHBEARER内の仕組みに固有のステップに従います。
  • 実行中のクラスタ内のSASL機構を修正する

    以下の手順を使って実行中のクラスタ内のSASL機構を修正することができます:

    1. 各ブローカーについて仕組みをserver.properties内のsasl.enabled.mechanismsに追加することで新しいSASL機構を有効にします。ここで説明される両方の仕組みを含めるためにJASS設定ファイルを更新します。クラスタのノードを逐次的にバウンスします。
    2. 新しい仕組みを使ってクライアントを再起動します。
    3. (必要であれば)内部ブローカー通信の仕組みを変更するために、server.properties内のsasl.mechanism.inter.broker.protocolを新しい仕組みに設定し、再びクラスタを逐次的にバウンスします。
    4. (必要であれば)古い仕組みを削除するために、古い仕組みをserver.properties内のsasl.enabled.mechanismsから削除し、JAAS設定ファイルから古い仕組みのためのエントリーを削除します。再び逐次的にクラスタをバウンスします。
  • 移譲トークンを使った認証

    移譲トークン ベースの認証は既存のSASL/SSLメソッドを補完するための軽量な認証機構です。移譲トークンはkafkaブローカーとクライアント間の共有秘密鍵です。移譲トークンは2方向SSLが使われる時にKerberos TGT/keytabあるいはキーストアの分散の追加の負荷無しに安全な環境内の利用可能なワーカーへ作業を分散するためのフレームワークの処理を助けるでしょう。詳細はKIP-48 を見てください。

    移譲トークンの使用法の一般的なステップは:

    1. ユーザはSASLあるいはSSLを経由してKafkaクラスタを認証し、移譲トークンを取得します。これはAdminClient APIあるいはkafka-delegation-token.sh スクリプトを使って行うことができます。
    2. Kafkaクラスタとの認証のために、ユーザは安全に移譲トークンをKafkaクライアントに渡します。
    3. Token owner/renewer は移譲トークンを renew/expire することができます。
    1. トークンの管理

      マスター キー/秘密鍵は移譲トークンを生成および検証するために使われます。これは設定オプションdelegation.token.master.keyを使って提供されます。同じ秘密鍵のキーが全てのブローカーに渡って設定される必要があります。秘密鍵が設定されないか空の文字列に設定された場合、ブローカーは移譲トークン認証を無効にするでしょう。

      現在の実装では、トークンの詳細はZookeeperに格納され、Zookeeperがプライベートネットワーク上にあるKafkaインストレーションでの使用に適しています。また、現在のところ、マスター key/secretは server.properties 設定ファイル内に平文として格納されます。これらの設定を将来のKafkaリリースで設定可能にするつもりです。

      トークンは現在の寿命と最大の更新可能な寿命を持ちます。デフォルトでは、トークンは各24時間ごとに7日まで更新されなければなりません。これらはdelegation.token.expiry.time.msdelegation.token.max.lifetime.ms設定オプションを使って設定可能です。

      トークンも明示的に取り消すことができます。トークンが期限切れにより更新あるいはトークンが最大生存時間を超えた場合、全てのブローカーのキャッシュとzookeeperから削除されるでしょう。

    2. 移譲トークンの作成

      トークンは AdminClient API あるいは kafka-delegation-token.sh スクリプトを使って作成することができます。移譲トークンのリクエスト (create/renew/expire/describe) はSASLあるいはSSL認証されたチャンネル上で発行されなければなりません。もし初期の認証が移譲トークンを使って行われた場合は、トークンは要求されないかもしれません。kafka-delegation-token.sh スクリプトの例は以下で与えられます。

      移譲トークンの作成:

          > bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --create   --max-life-time-period -1 --command-config client.properties --renewer-principal User:user1
              

      移譲トークンの更新:

          > bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --renew    --renew-time-period -1 --command-config client.properties --hmac ABCDEFGHIJK
              

      移譲トークンの期限切れ:

          > bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --expire   --expiry-time-period -1   --command-config client.properties  --hmac ABCDEFGHIJK
              

      既存のトークンは --describe オプションを使って説明することができます:

          > bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 --describe --command-config client.properties  --owner-principal User:user1
              
    3. トークンの認証

      移譲トークンの認証は現在のSASL/SCRAM認証機構と抱き合わせです。ここで説明されるようにKafkaクラスタ上でSASL/SCRAM機構を有効にしなければなりません。

      Kafkaクライアントの設定:

      1. 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はトークン認証についてのクライアントのための設定例です:
           sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
                username="tokenID123" \
                password="lAYYSFmLs4bTjf+lTZ1LCHR/ZZFNA==" \
                tokenauth="true";

        オプション usernamepassword はクライアントによってトークンidとトークンHMACを設定するために使われます。そして、オプション tokenauth はサーバにトークン認証を示すために使われます。この例では、クライアントはトークンid: tokenID123 を使ってブローカーに接続します。JVM内の異なるクライアントはsasl.jaas.config内で詳述される異なるトークンを指定することで異なるトークンを使って接続することができます。

        別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。

    4. 手動で秘密鍵をローテートする手順:

      秘密鍵がローテートされる必要がある場合、再デプロイが必要です。このプロセスの間、既に接続したクライアントは動作し続けるでしょう。しかし古いトークンを持つどのような新しい接続リクエストおよび更新/期限切れのリクエストは失敗するでしょう。手順は以下で与えられます。

      1. 全ての既存のトークンを期限切れにする。
      2. ローリング更新によって秘密鍵をローテートする。そして
      3. 新しいトークンを生成する

      将来のKafkaのリリースでこれを自動化するつもりです。

    5. 移譲トークンの注意
      • 現在のところ、ユーザはそのユーザだけの移譲トークンを作成することだけができます。所有者/更新者はトークンを更新あるいは期限切れにすることができます。所有者/更新者は常にそれらの独自のトークンを表示することができます。他のトークンを表示するには、トークンのリソースに DESCRIBE パーミッションを追加する必要があります。
  • 7.4認証とACL

    Kafkaは差し込み可能なオーソライザと、全てのaclを格納するためにzookeeperを使う取り出したままで使えるオーソライザの実装を同梱します。オーソライザはserver.properties内でauthorizer.class.nameを設定することで構成できます。取り出したままで使える実装を有効にするには、以下を使います:
    authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
    Kafkaのaclは一般的な形式 "Principal P はホストHからのリソースパターン RPに合致する任意のリソース R のオペレーション O が [許可される/拒否される]" で定義されます。KIP-11上のacl構造およびKIP-290上のリソースパターンについてもっと読むことができます。aclを追加、削除あるいはリスト化するために、kafkaオーソライザ CLIを使うことができます。デフォルトでは、もしリソースパターンが特定のリソース R に合致しなければ、R がaclに関係がなくなり、従ってsuperユーザ以外の誰もRにアクセスすることができません。その挙動を変えたい場合は、以下をserver.propertiesに含めることができます。
    allow.everyone.if.no.acl.found=true
    以下のようにしてserver.propertiesにsuperユーザを追加することもできます (SSLのユーザ名はカンマを含むかもしれないため、デリミタはセミコロンであることに注意してください)。
    super.users=User:Bob;User:Alice
    デフォルトでは、SSLのユーザ名は "CN=writeuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown"の形式でしょう。server.properties内で以下のようにカスタマイズ化された PrincipalBuilder を設定することで変更することができます。
    principal.builder.class=CustomizedPrincipalBuilderClass
    デフォルトでは、SASLユーザ名はkerberos principalの最初の部分でしょう。server.properties内でsasl.kerberos.principal.to.local.rulesを独自のルールに設定することで変更することができます。sasl.kerberos.principal.to.local.rulesの形式は、Kerberos configuration file (krb5.conf)内でauth_to_localが動作するのと同じ方法で各ルールが動作するリストです。変換された結果が全て小文字になるように強制するために、追加の小文字化ルールもサポートします。これはルールの最後に "/L" を追加することで行われます。構文については以下の形式を調べてください。各ルールはRULEで始まります: そして以下の形式の表現を含みます。詳細についてはkerberosのドキュメントを見てください。
            RULE:[n:string](regexp)s/pattern/replacement/
            RULE:[n:string](regexp)s/pattern/replacement/g
            RULE:[n:string](regexp)s/pattern/replacement//L
            RULE:[n:string](regexp)s/pattern/replacement/g/L
        
    デフォルトのルールも適切な位置に保持しながら、user@MYDOMAIN.COM を適切にユーザに変換するルールを追加する例:
    sasl.kerberos.principal.to.local.rules=RULE:[1:$1@$0](.*@MYDOMAIN.COM)s/@.*//,DEFAULT

    コマンドライン インタフェース

    Kafka認証管理CLIは他の全てのCLIと一緒にbinディレクトリの下で見つけることができます。CLIスクリプトは kafka-acls.shと呼ばれます。以下はスクリプトがサポートする全てのオプションのリストです:

    オプション 説明 デフォルト オプションの型
    --add スクリプトにユーザがaclを追加しようとしていることを伝える。 アクション
    --remove スクリプトにユーザがaclを削除しようとしていることを伝える。 アクション
    --list スクリプトにユーザがaclをリスト化しようとしていることを伝える。 アクション
    --authorizer オーソライザの完全修飾クラス名。 kafka.security.auth.SimpleAclAuthorizer 設定
    --authorizer-properties 初期化のためにオーソライザに渡されるだろう key=val ペア。デフォルトのオーソライザについて、値の例は: zookeeper.connect=localhost:2181 設定
    --cluster スクリプトに、ユーザが単一のクラスタリソース上のaclとやり取りしようとしていることを伝えます。 ResourcePattern
    --topic [topic-name] スクリプトに、ユーザがトピックリソース パターン(s)のaclとやり取りしようとしていることを伝えます。 ResourcePattern
    --group [group-name] スクリプトに、ユーザがコンシューマ-グループ リソース パターン(s)のaclとやり取りしようとしていることを伝えます。 ResourcePattern
    --resource-pattern-type [pattern-type] スクリプトに、ユーザが使用したいリソースパターンの型 (--add)、あるいはリソース パターンのフィルタ (--list and --remove) を伝えますaclを追加する場合は、これは特定のパターンの型でなければなりません。例えば 'literal' または 'prefixed'。
    When listing or removing acls, a specific pattern type filter can be used to list or remove acls from a specific type of resource pattern, or the filter values of 'any' or 'match' can be used, where 'any' will match any pattern type, but will match the resource name exactly, and 'match' will perform pattern matching to list or remove all acls that affect the supplied resource(s).
    警告: '--remove' スイッチと組み合わせて使う時は、'match'を使うには注意しなければなりません。
    literal 設定
    --allow-principal PrincipalはAllowパーミッションを使ってACLに追加されるだろう PrincipalType:name 形式です。
    複数の --allow-principal を1つのコマンドで指定することができます。
    Principal
    --deny-principal PrincipalはDenyパーミッションを使ってACLに追加されるだろう PrincipalType:name 形式です。
    複数の --deny-principal を1つのコマンドで指定することができます。
    Principal
    --allow-host --allow-principal にリスト化されているプリンシパルからのIPあぢれsyがアクセスできるでしょう。 もし --allow-principal がデフォルトに * を指定される場合は、"all hosts" に翻訳されます ホスト
    --deny-host --deny-principal にリスト化されているプリンシパルからのIPアドレスはアクセスを拒否されるでしょう。 もし --deny-principal がデフォルトに * を指定される場合は、"all hosts" に翻訳されます ホスト
    --operation 許可あるいは拒否されるだろうオペレーション。
    有効な値 : Read, Write, Create, Delete, Alter, Describe, ClusterAction, All
    All オペレーション
    --producer プロデューサの役割についてaclを add/remove するための便利なオプション。これはトピックに WRITE, DESCRIBE および CREATE を許可するaclを生成するでしょう。 便利なもの
    --consumer コンシューマの役割についてaclを add/remove するための便利なオプション。これはトピックに READ, DESCRIBE を、コンシューマグループに READ を許可するaclを生成するでしょう。 便利なもの
    --force 全ての質問に対してyesを想定し、入力を促さないための便利なオプション。 便利なもの

    • Aclの追加
      acl "Principals User:Bob と User:Alice がIP 198.51.100.0 と IP 198.51.100.1からのTOPIC Test-Topicへの Operation Read と Write の実施が許可されている" を追加したいとします。以下のオプションを使ってCLIを実行することでこれを行うことができます:
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --allow-principal User:Alice --allow-host 198.51.100.0 --allow-host 198.51.100.1 --operation Read --operation Write --topic Test-topic
      デフォルトでは、オペレータがリソースにアクセスを許可するaclを明示的に持たない全てのprincipalは拒否されます。幾つかのprincipalを除いてアクセスを許可するallow aclを定義したい場合は、--deny-principal と --deny-host オプションを使う必要があるでしょう。例えば、Test-topicからのReadを全てのユーザに許可し、IP 198.51.100.3からの User:BadBob だけのみ拒否する場合には、以下のコマンドを使ってそれを行うことができます。
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:* --allow-host * --deny-principal User:BadBob --deny-host 198.51.100.3 --operation Read --topic Test-topic
      ``--allow-host`` と ``deny-host`` はIPアドレスのみをサポートすることに注意してください (ホスト名はサポートされません)。上の例はリソース パターン オプションとして--topic [topic-name] を指定することでtopicにaclを追加します。同様に、ユーザは --cluster と指定することでクラスタに、 --group [group-name] を指定することでコンシューマグループ aclを追加することができます。特定のタイプのリソースにaclを追加することができます。例えば、acl "Principal User:Peter is allowed to produce to any Topic from IP 198.51.200.0" を追加したいとします。ワイルドカード リソース '*' を使って行うことができます。例えば、以下のオプションを使ってCLIを実行します:
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Peter --allow-host 198.51.200.1 --producer --topic *
      プリフィックスのリソースパターンにaclを追加することができます。例えば、acl "Principal User:Jane is allowed to produce to any Topic whose name starts with 'Test-' from any host" を追加したいとします。以下のオプションを使ってCLIを実行することでこれを行うことができます:
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Jane --producer --topic Test- --resource-pattern-type prefixed
      --resource-pattern-type のデフォルトは 'literal' であることに注意してください。これはまったく同じ名前を持つリソースのみ、あるいはワイルドカード リソース名 '*' の場合はどのような名前を持つリソースに影響します。
    • Acl の削除
      aclの削除はとても似ています。唯一の違いは --add オプションの代わりに、--remove オプションを指定しなければならないでしょう。上の最初の例で追加されたaclを削除するために、以下のオプションを使ってCLIを実行することができます:
       bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --remove --allow-principal User:Bob --allow-principal User:Alice --allow-host 198.51.100.0 --allow-host 198.51.100.1 --operation Read --operation Write --topic Test-topic 
      上のプリフィックスのリソースパターンを追加したaclを削除したい場合は、以下のオプションを使ってCLIを実行することができます:
       bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --remove --allow-principal User:Jane --producer --topic Test- --resource-pattern-type Prefixed
    • aclのリスト化
      リソースと一緒に --list オプションを指定することでリソースのためのaclをリスト化することができます。文字 リソース パターン Test-topicについての全てのaclをリスト化するために、以下のオプションを使ってCLIを実行することができます。
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --list --topic Test-topic
      ただし、これはこの正確なリソースパターンに追加されたaclのみを返すでしょう。トピックへのアクセスに影響する他のaclが存在するかもしれません。例えば、トピック ワイルドカード '*' 上のacl、あるいはプリフィックスのリソースパターン上のacl。ワイルドカード リソース パターン上のaclは明示的に問い合わせることができます:
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --list --topic *
      しかし、Test-topicに一致するプリフィックスのリソースパターン上のaclについて明示的に問い合わせることは、そのようなパターンの名前が分からないため、必ずしも可能ではありません。'--resource-pattern-type match' を使ってTest-topicに影響する 全ての aclをリスト化することができます。例えば、
      bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --list --topic Test-topic --resource-pattern-type match
      これは全ての文字通り、ワイルドカード、およびプリフィックス リソースパターンに合致するaclをリスト化するでしょう。
    • プロデューサあるいはコンシューマとしてprincipalを追加あるいは削除
      acl管理の最も一般的な使用法はプロデューサあるいはコンシューマとしてprincipalを追加/削除することです。そこでこれらを処理するために簡単なオプションを追加しました。User:Bob をTest-topicのプロデューサとして追加するために、以下のコマンドを実行することができます:
       bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --producer --topic Test-topic
      AliceをTest-topicのコンシューマとしてコンシューマグループ Group-1と一緒に追加するのに似て、単純に --consumer optionを渡す必要があります:
       bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Bob --consumer --topic Test-topic --group Group-1 
      コンシューマ オプションについては、コンシューマグループを指定する必要もあることに注意してください。プロデューサあるいはコンシューマの役割からprincipalを削除するには、単純に --remove オプションを渡す必要があります。

    7.5実行中のクラスタでの重要なセキュリティ機能

    以前に議論されたサポートされるプロトコルの1つ以上を使って実行中のクラスタを安全にすることができます。これは段階的に行われます:

    • 追加の安全なポート(s)を開くために、逐次的にクラスタノードをバウンスします。
    • PLAINTEXTポートではなく安全なものを使ってクライアントを再起動 (クライアント-ブローカーの接続を安全にしていると仮定)。
    • (必要であれば)ブローカー to ブローカーの安全を有効にするために、再び逐次的にクラスタをバウンスします
    • PLAINTEXT ポートを閉じるために最後の逐次的なバウンス。

    SSLとSASLを設定するための固有のステップは、セクション7.27.3 で説明されます。望ましいプロトコル(s)のセキュリティを有効にするためには、これらのステップに従ってください。

    セキュリティの実装によりブローカー-クライアントとブローカー-ブローカー通信の両方について異なるプロトコルを設定します。これらは別個のバウンスの中で有効にされる必要があります。PLAINTEXT ポートは全体に渡って開いたままにされなければなりません。つまりブローカー および/あるいは クライアントは通信し続けることができます。

    増加するバウンスを実行すると、ブローカーはSIGTERMを介して正常に停止します。次のノードに移動する前に再起動したレプリカがISRリストに返されるのを待つことも良い練習です。

    例として、ブローカー-クライアントとブローカー-ブローカー通信の両方でSSLを使って暗号化したいとします。最初の逐次的なバウンスの中で、SSLポートがそれぞれのノード上で開かれます:
                listeners=PLAINTEXT://broker1:9091,SSL://broker1:9092
                
    そして、クライアントの設定が新しく開かれた安全なポートを示すように変更して、クライアントを再起動します:
                bootstrap.servers = [broker1:9092,...]
                security.protocol = SSL
                ...etc
                
    2つ目の増加サーバのバウンスで、Kafkaにブローカー-ブローカープロトコルとしてSSLを使うように指示します (同じSSLポートを使うでしょう):
                listeners=PLAINTEXT://broker1:9091,SSL://broker1:9092
                security.inter.broker.protocol=SSL
                
    最後のバウンスの中で、PLAINTEXTポートを閉じることでクラスタが安全になります:
                listeners=SSL://broker1:9092
                security.inter.broker.protocol=SSL
                
    別のやり方として、ブローカー-ブローカーおよびブローカー-クライアント通信のために異なるプロトコルが使えるように複数のポートを開くことができます。全体に渡って(つまりブローカー-ブローカーおよびブローカー-クライアント通信)SSL暗号を使いたいが、ブローカー-クライアント通信にSASL認証も追加したいとしましょう。最初のバウンス時に2つの追加のポートを開くことでこれを行うことができます:
                listeners=PLAINTEXT://broker1:9091,SSL://broker1:9092,SASL_SSL://broker1:9093
                
    そしてクライアントを再起動し、それらの設定が新しく開かれたSASL&SSLの安全なポートを指すように変更します:
                bootstrap.servers = [broker1:9093,...]
                security.protocol = SASL_SSL
                ...etc
                
    2つ目のサーバのバウンスはクラスタが前にポート9092で開いたSSLポートを使って暗号化されたブローカー-ブローカー通信を使うように切り替えるでしょう。
                listeners=PLAINTEXT://broker1:9091,SSL://broker1:9092,SASL_SSL://broker1:9093
                security.inter.broker.protocol=SSL
                
    最後のバウンスはPLAINTEXTポートを閉じることでクラスタを安全にします。
            listeners=SSL://broker1:9092,SASL_SSL://broker1:9093
            security.inter.broker.protocol=SSL
                
    ZooKeeperはKakfaクラスタとは関係なく安全にすることができます。これを行うステップはセクション7.6.2でカバーされます。

    7.6ZooKeeper 認証

    7.6.1新しいクラスタ

    ブローカー上でZooKeeperを有効にするには、2つの必要なステップがあります:
    1. JAASログインファイルを作成し、上で説明されたように適切なシステムプロパティがそれを指すように設定します
    2. 各ブローカー内で構成プロパティzookeeper.set.aclをtrueに設定する
    KafkaクラスタのためにZooKeeperに格納されたメタデータは全世界から読み込み可能ですが、ブローカーによってのみ修正することができます。この決定の背後にある原理は、ZooKeeperに格納されたデータは感度は良くないですが、不適切なデータの走査はクラスタの崩壊を起こすかもしれないということです。ネットワーク分割によってZooKeeperへのアクセスを制限することもお勧めします (もし新しいJavaコンシューマとプロデューサのクライアントが使われる場合、ブローカーと幾つかの管理ツールだけがZooKeeperにアクセスする必要があります)。

    7.6.2クラスタの移設

    セキュリティをサポートしないバージョンのKafkaを実行しているか、単純にセキュリティを無効にしていて、クラスタを安全にしたい場合、オペレーションへの最小の混乱をもってZooKeeperの認証を有効にするために以下のステップを実行する必要があります:
    1. JAASログインファイルを設定してローリング リスタートを実施します。これはブローカーに認証を可能にします。ローリング リスタートの最後に、ブローカーは厳密なACLを持つznodeを操作することができますが、それらはこれらのACLを持つznodeを作成しないでしょう。
    2. 今度は設定zookeeper.set.aclをtrueに設定して、パラメータブローカーの2つ目のローリング リスタートを実施します。これはznodeを生成する時に安全なACLを使うことを可能にします
    3. ZkSecurityMigrator ツールを実行します。ツールを実行するために、このスクリプトがあります: zookeeper.aclをsecureに設定した./bin/zookeeper-security-migration.sh。このツールはznodeのACLを変更する対応する副木を横断します

    安全なクラスタ内で認証を止めることもできます。そうするには、以下のステップに従います:

    1. JAASログインファイルを設定しているブローカーのローリング リスタートを実施します。これはブローカーの認証を有効にしますが、zookeeper.set.aclをfalseに設定します。ローリング リスタートの最後に、ブローカーは安全なACLを持つznodeの生成を停止しますが、まだ認証し全てのznodeを操作することができます。
    2. ZkSecurityMigrator ツールを実行します。ツールを実行するには、zookeeper.aclをunsecureに設定したこのスクリプト./bin/zookeeper-security-migration.shを実行します。このツールはznodeのACLを変更する対応する副木を横断します
    3. 今度はJAASログインファイルを設定するシステム プロパティを省略した、ブローカーの2つ目のローリング リスタートを実行します。
    移設ツールを実行する方法の例です:
        ./bin/zookeeper-security-migration.sh --zookeeper.acl=secure --zookeeper.connect=localhost:2181
        

    パラメータの完全なリストを見るために、これを実行します:

        ./bin/zookeeper-security-migration.sh --help
        

    7.6.3ZooKeeperアンサンブルの移設

    ZooKeeperアンサンブル上での認証を有効にする必要もあります。これを行うには、サーバのローリング リスタートの実施と2,3のプロパティの設定が必要です。詳細はZooKeeperのドキュメントを参照してください:
    1. Apache ZooKeeperのドキュメント
    2. Apache ZooKeeperのwiki

    8. Kafka接続

    KafkaコネクトはApache Kafkaと他のシステム間のスケーラブルで信頼できるストリーミングデータのためのツールです。データの大きなコレクションをKafkaへ、あるいは から、移動するコネクタを素早く定義することを簡単にします。Kafkaコネクタはデータベース全体を取り込み、あるいは全てのアプリケーションサーバからKafkaトピックへ、低レンテンシのストリームの処理が可能なデータを作りながら、メトリクスを集めることができます。抽出ジョブはデータをKafkaトピックから2次のストレージとクエリシステムへ、あるいはオフラインの解析のためにバッチシステムへ配送することができます。

    Kafkaコネクトの機能は以下を含みます:

    • Kafkaコネクタのための共通のフレームワーク - Kafkaコネクトはコネクタの開発、配備および管理を単純化し、Kafkaを使って他のデータシステムの統合を標準化します。
    • 分散およびスタンドアローン モード - 大規模、組織全体をサポートする集中的に管理されたサービスのためにスケールアップ、あるいは開発、テスト、小規模な運用配備のためにスケールダウン
    • REST インタフェース - 使いやすいREST APIを使って、Kafkaコネクト クラスタへのコネクタをサブミットおよび管理する
    • 自動オフセット管理 - コネクタからのほんの少しの情報を使って、Kafkaコネクタはオフセットのコミットプロセスを自動的に管理するので、コネクタの開発者はこのエラーが起きがちなコネクタの開発の部分について心配する必要がありません。
    • デフォルトで分散およびスケーラブル - Kafka コネクタは既存のグループ管理のプロトコルを土台にします。Kafkaコネクタ クラスタをスケールアップするために、より多くのワーカーを追加することができます。
    • ストリーミング/バッチの統合 - Kafkaの既存の機能を利用することで、Kafkaコネクトはストリーミングとバッチデータシステムの間を埋める理想的な解決法です。

    8.2ユーザガイド

    クリックスタートはKafkaコネクトのスタンドアローン バージョンを実行する方法の短い例を提供します。この章はKafkaコネクトをもっと詳細に設定、実行および管理する方法を説明します。

    Kafka コネクトの実行

    Kafkaコネクトは現在のところ2つの実行のモードをサポートします: スタンドアローン (1つのプロセス) および 分散。

    スタンドアローン モードでは、全ての仕事が1つのプロセスの中で実施されます。この設定はセットアップと開始するのがより簡単で、ただ1つのワーカーだけが意味がある状況で有用かもしれません (例えば、ログファイルの収集)。しかしそれは耐障害性のようなKafkaコネクトの幾つかの機能からの恩恵を受けません。T以下のコマンドを使ってスタンドアローンプロセスを開始することができます:

        > bin/connect-standalone.sh config/connect-standalone.properties connector1.properties [connector2.properties ...]
        

    最初のパラメータはワーカーのための設定です。これはKafkaコネクトパラメータ、シリアライズ化形式、およびオフセットをどれだけの頻度でコミットするかのような設定を含みます。提供される例は config/server.propertiesで提供されるデフォルトの設定で実行中のローカルクラスタと良く連携する筈です。異なる設定あるいはプロダクションの配備で使うには調整する必要があるでしょう。全てのワーカー(スタンドアローンおよび分散の両方)は2,3の設定を必要とします:

    • bootstrap.servers - Kafkaへの起動接続に使われるKafkaサーバのリスト
    • key.converter - Kafkaコネクトの形式と、Kafkaへ書き込まれるシリアライズ化された形式の間で変換するために使われるConverterクラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるキーの形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。
    • value.converter - Kafkaコネクトの形式と、Kafkaへ書き込まれるシリアライズ化された形式の間で変換するために使われるConverterクラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれる値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。

    スタンドアローンモードに固有の重要な設定オプションは以下の通りです:

    • offset.storage.file.filename - オフセットデータを格納するファイル

    ここで設定されたパラメータはKafkaコネクトによって使われるプロデューサおよびコンシューマが設定、オフセットおよび状態トピックスにアクセスすることを目的としています。KafkaソースおよびKafkaシンク タスクの設定については、同じパラメータを使うことができますが、それぞれconsumer.producer.のプリフィックスを付ける必要があります。ワーカーの設定から引き継がれる唯一のパラメータはbootstrap.serversです。同じクラスタが全ての目的のためにしばしば使われるため、これはほとんどの場合において十分でしょう。注目に値する例外はセキュアなクラスタで、これは接続を許可するために特別なパラメータを必要とします。これらのパラメータはワーカーの設定の中で3回まで設定する必要があるでしょう。1つはアクセスの管理のため、1つはKafkaシンクのため、1つはKafkaソースのためです。

    残りのパラメータはコネクタの設定ファイルです。欲しいだけ含めることができますが、全ては同じプロセス内(の異なるスレッド上)で実行されるでしょう。

    分散モードは作業の自動的なバランシングを処理し、動的にスケールアップ(あるいはダウン)することができ、アクティブなタスクと設定およびオフセットコミットデータの両方に耐障害性を提供します。実行はスタンドアローンモードにとても似ています:

        > bin/connect-distributed.sh config/connect-distributed.properties
        

    違いは、開始されるクラスと、Kafka コネクトプロセスがどこに設定を格納し、どのように作業を割り当て、オフセットとタスクの状態をどこに格納するのかを決定する方法を変更する構成パラメータです。分散モードでは、Kafkaコネクトはオフセット、設定およびタスクの状態をKafkaトピックの中に格納します。望ましい数のパーティションとリプリケーションファクターを達成するために、手動でオフセット、設定およびステータスのためのトピックを作成することをお勧めします。Kafkaコネクトが開始した時にトピックがまだ生成されていない場合、トピックはデフォルトの数のパーティションとレプリケーション ファクターで自動的に生成されるでしょう。これは使用目的に合致しないかもしれません。

    特に上で述べられた一般的な設定に加えて以下の設定パラメータは、クラスタを開始する前に設定することが重要です:

    • group.id (デフォルト connect-cluster) - クラスタのためのユニークな名前。コネクト クラスタグループを生成する時に使用される; これはコンシューマグループのIDと衝突してはいけないことに注意してください。
    • config.storage.topic (デフォルト connect-configs) - コネクタとタスクの設定を格納するために使われるトピック。これは1つのパーティション、高度にレプリケート、圧縮されたトピックでなければなりません。自動生成されたトピックが複数のパーティションを持つか、圧縮よりも削除のための自動的な設定をされているかもしれないため、正しい設定がされるように手動でトピックを生成する必要があるかもしれません。
    • offset.storage.topic (デフォルト connect-offsets) - オフセットを格納するために使われるトピック; このトピックは多くのパーティションを持ち、リプリケートされ、圧縮のための設定をされていなければなりません。
    • status.storage.topic (デフォルト connect-status) - 状態を格納するために使われるトピック; このトピックは複数のパーティションを持つかもしれません。レプリケートされ、圧縮のための設定をされていなければなりません。

    分散モードでは、コネクタの設定はコマンドライン上で渡されないことに注意してください。コネクタを生成、修正および破棄するために、以下で説明するREST APIを代わりに使ってください。

    コネクタの設定

    コネクタの設定は単純なキー-値マッピングです。スタンドアローンモードについては、これらはプロパティファイルの中で定義され、コマンドリアン上でコネクタ プロセスに渡されます。分散モードでは、それらはコネクタを作成(あるいは修正)するリクエストのためのJSONペイロード内に含まれるでしょう。

    ほとんどの設定はコネクタに依存しますので、ここでは概略を説明されないでしょう。しかし、2,3の共通のオプションがあります:

    • name - コネクタのためのユニークな名前。同じ名前をもう一度登録しようとすると失敗するでしょう。
    • connector.class - コネクタのためのJavaクラス
    • tasks.max - このコネクタのために生成されなければならないタスクの最大数。もしこのレベルの並行度を実現できないなら、コネクタはより少ないタスクを生成するかもしれません。
    • key.converter - (任意) ワーカーによって設定されるデフォルトのキー コンバータを上書きします。
    • value.converter - (任意) ワーカーによって設定されるデフォルトの値コンバータを上書きします。

    connector.class設定はいくつかの形式をサポートします: このコネクタのためのクラスの完全な名前あるいはエイリアス。もしコネクタが org.apache.kafka.connect.file.FileStreamSinkConnector なら、設定を少し短くするために、この完全な名前を指定するかあるいはFileStreamSinkConnectorを使うことができます。

    シンク コネクタも入力を制御するための2,3の追加のオプションを持ちます。各シンク コネクタは以下のうちの1つを設定する必要があります:

    • topics - このコネクタに関して入力として使うトピックのカンマ区切りのリスト
    • topics.regex - このコネクタに関して入力として使うトピックのJavaの正規表現

    他のオプションについては、コネクタのためのドキュメントを参考にする必要があります。

    変換

    コネクタは軽量の1度に1つのメッセージ修正を行うために変換と一緒に設定することができます。それれはデータメッセージングとイベントルーティングをするのに便利かもしれません。

    変換のチェーンはコネクタの設定の中で指定することができます。

    • transforms - どの変換が適用されるかの順番を指定する、変換のためのエイリアスのリスト。
    • transforms.$alias.type - 変換のための完全修飾クラス名。
    • transforms.$alias.$transformationSpecificConfig 変換のためのプロパティの設定

    例えば、組み込みのファイルソースのコネクタを取り上げ、静的なフィールドを追加するための変換を使います。

    例の至る所でスキーマレスのJSONデータ形式を使うつもりです。スキーマレス形式を使うために、connect-standalone.properties内の以下の2行をtrueからfalseに変更しました。

            key.converter.schemas.enable
            value.converter.schemas.enable
        

    ファイル ソース コネクタは文字列として各行を読みます。各行をMap内にラップし、イベントの元を識別するために2つ目のフィールドを追加しましょう。これを行うには、2つの変換を使います:

    • Map内に入力行を配置するためにHoistField
    • 静的フィールドを追加するためにInsertFieldこの例では、レコードがファイル コネクタから来ると示します。

    変換を追加した後で、connect-file-source.properties ファイルは以下のように見えます:

            name=local-file-source
            connector.class=FileStreamSource
            tasks.max=1
            file=test.txt
            topic=connect-test
            transforms=MakeMap, InsertSource
            transforms.MakeMap.type=org.apache.kafka.connect.transforms.HoistField$Value
            transforms.MakeMap.field=line
            transforms.InsertSource.type=org.apache.kafka.connect.transforms.InsertField$Value
            transforms.InsertSource.static.field=data_source
            transforms.InsertSource.static.value=test-file-source
        

    transformsから始まる全ての行は変換のために追加されました。2つの作成した変換を見つけることができます: "InsertSource" と "MakeMap" は変換を与えると選択したエイリアスです。変換の型は以下で分かるように組み込みの変換のリストに基づいています。各変換の型は追加の設定を持ちます: HoistField は "field" と呼ばれる設定を必要とします。これはファイルからの元の文字列を含むmap内のフィールド名です。InsertFieldにより追加した変換フィールド名と値を指定することができます。

    変換無しにサンプルのファイル上でそのファイル ソース コネクタを実行し、それらを kafka-console-consumer.sh を使って読み込んだ時、結果は以下の通りでした:

            "foo"
            "bar"
            "hello world"
       

    そして、新しいファイル コネクタを作成し、今度は設定ファイルに変換を追加します。今度は結果は以下の通りになるでしょう:

            {"line":"foo","data_source":"test-file-source"}
            {"line":"bar","data_source":"test-file-source"}
            {"line":"hello world","data_source":"test-file-source"}
        

    読んだ行が今ではJSON mapの一部で、指定した静的な値を持つ追加のフィールドがあることが分かります。これが変換を使って行うことができることの1つの例です。

    幾つかのより広く適用可能なデータとルーティングの変換がKafkaコネクトに含まれています:

    • InsertField - 静的なデータあるいはレコードのメタデータのどちらかを使ってフィールドを追加する
    • ReplaceField - フィールドをフィルターあるいはリネームする
    • MaskField - フィールドを型にとって有効なnull値に置き換える (0, 空文字など)
    • ValueToKey
    • HoistField - イベント全体を1つのフィールドとしてStructあるいはMap内にラップする
    • ExtractField - StructおよびMapから特定のフィールドを抽出し、このフィールドだけを結果に含める
    • SetSchemaMetadata - スキーマ名あるいはバージョンを修正する
    • TimestampRouter - 元のトピックおよびタイムスタンプに基づいてレコードのトピックを修正する。タイムスタンプに基づいて異なるテーブルあるいはインデックスに書き込む必要があるシンクを使う時に便利です
    • RegexRouter - 元のトピック、置換文字および正規表現に基づいてレコードのトピックを修正する

    各変換を設定する方法の詳細は以下でリスト化されます:

    org.apache.kafka.connect.transforms.InsertField
    レコードのメタデータあるいは設定された静的な値から属性を使ってフィールド(s)を挿入します。

    レコードキー(org.apache.kafka.connect.transforms.InsertField$Key) あるいは値 (org.apache.kafka.connect.transforms.InsertField$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    offset.fieldKafkaオフセットのためのフィールド名 - シンク コネクタへのみ適用可能。
    これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。
    文字列nullmedium
    partition.fieldKafkaパーティションのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。文字列nullmedium
    static.field静的なデータフィールドのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。文字列nullmedium
    static.valueフィールド名が設定された場合、静的なフィールド値。文字列nullmedium
    timestamp.fieldレコードのタイムスタンプのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。文字列nullmedium
    topic.fieldKafkaトピックのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。文字列nullmedium

    org.apache.kafka.connect.transforms.ReplaceField
    フィールドをフィルターあるいはリネームする

    レコードキー(org.apache.kafka.connect.transforms.ReplaceField$Key) あるいは値 (org.apache.kafka.connect.transforms.ReplaceField$Value)のために設計された具体的な変換型を使います

    名前 説明 種類 デフォルト 有効な値 重要性
    blacklist除外するフィールド。これはホワイトリストに優先されます。list""medium
    renamesフィールドのリネーム マッピング。list""カンマで区切られたペアのリスト。例えば foo:bar,abc:xyzmedium
    whitelist含むフィールド。指定された場合、これらのフィールドだけが使われるでしょう。list""medium

    org.apache.kafka.connect.transforms.MaskField
    指定されたフィールドをフィールド型にとって有効なnull値にマスクする (つまり、0, false, 空文字 など)。

    レコードキー (org.apache.kafka.connect.transforms.MaskField$Key) あるいは値 (org.apache.kafka.connect.transforms.MaskField$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    fieldsマスクするフィールドの名前。list空では無いリストhigh

    org.apache.kafka.connect.transforms.ValueToKey
    レコードキーをレコードの値のフィールドの部分集合から形成された新しいキーで置き換える。

    名前 説明 種類 デフォルト 有効な値 重要性
    fieldsレコードキーとして抽出するためのレコード値上のフィールド名。list空では無いリストhigh

    org.apache.kafka.connect.transforms.HoistField
    スキーマが存在する時に、Struct内の指定したフィールド名を使ってデータをラップ、あるいはスキーマレスのデータの場合はMapします。

    レコードキー (org.apache.kafka.connect.transforms.HoistField$Key) あるいは値 (org.apache.kafka.connect.transforms.HoistField$Value)のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    フィールド結果のStructあるいはMap内で生成されろうだろう1つのフィールドのフィールド名。文字列medium

    org.apache.kafka.connect.transforms.ExtractField
    スキーマが存在する時にStructから指定されたフィールドを抽出、あるいはスキーマレスのデータの場合はMapします。null値は修正無しに渡されます。

    レコードキー (org.apache.kafka.connect.transforms.ExtractField$Key) あるいは値 (org.apache.kafka.connect.transforms.ExtractField$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    フィールド抽出するフィールド名。文字列medium

    org.apache.kafka.connect.transforms.SetSchemaMetadata
    スキーマ名、バージョン あるいは両方をレコードのキー (org.apache.kafka.connect.transforms.SetSchemaMetadata$Key) あるいは値 (org.apache.kafka.connect.transforms.SetSchemaMetadata$Value) スキーマに設定します。

    名前 説明 種類 デフォルト 有効な値 重要性
    schema.name設定するスキーマ名。文字列nullhigh
    schema.version設定するスキーマのバージョン。intnullhigh

    org.apache.kafka.connect.transforms.TimestampRouter
    レコードのトピック フィールドを元のトピックの値とレコードのタイムスタンプの関数として更新します。

    トピックフィールドはしばしば宛先のシステム(例えばデータベーステーブルあるいは検索インデックス名)の中の等価なエンティティ名を決定するために使われるため、これは主にシンク コネクタに便利です。

    名前 説明 種類 デフォルト 有効な値 重要性
    timestamp.formatjava.text.SimpleDateFormatと互換性のあるタイムスタンプのためのフォーマット文字列。文字列yyyyMMddhigh
    topic.formatトピックとタイムスタンプのそれぞれのプレースホルダーとして ${topic}${timestamp} を含むことができるフォーマット文字列。文字列${topic}-${timestamp}high

    org.apache.kafka.connect.transforms.RegexRouter
    設定された正規表現と置き換え文字列を使ってレコードのトピックを更新します。

    背後では、正規表現は java.util.regex.Patternにコンパイルされます。パターンが入力トピックに一致する場合、新しいトピックを取得するためにjava.util.regex.Matcher#replaceFirst() が置き換え文字列と一緒に使われます。

    名前 説明 種類 デフォルト 有効な値 重要性
    regex一致に使われる正規表現。文字列有効な正規表現high
    replacement置換文字列文字列high

    org.apache.kafka.connect.transforms.Flatten
    設定可能なデリミタ文字を使って各レベルのフィールド名を結合することで、各フィールドについて名前を生成することで、入れ子になったデータ構造を平らにします。スキーマが存在する時はStructに、スキーマレスのデータの場合はMapを適用します。デフォルトのデリミタは '.' です。

    レコードキー (org.apache.kafka.connect.transforms.Flatten$Key) あるいは値 (org.apache.kafka.connect.transforms.Flatten$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    デリミタ出力レコードのためのフィールド名を生成する時に、入力レコードからのフィールド名間に挿入するためのデリミタ文字列.medium

    org.apache.kafka.connect.transforms.Cast
    特定の型へフィールドまたは、キーあるいは値をキャストします。例えば、整数フィールドをもっと小さな幅に。単純なプリミティブな型だけがサポートされます -- 整数、浮動小数点数、真偽値 および文字列。

    レコードキー (org.apache.kafka.connect.transforms.Cast$Key) あるいは値 (org.apache.kafka.connect.transforms.Cast$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    specList of fields and the type to cast them to of the form field1:type,field2:type to cast fields of Maps or Structs. A single type to cast the entire value. 有効な型は、int8, int16, int32, int64, float32, float64, boolean および string です。listカンマで区切られたペアのリスト。例えば foo:bar,abc:xyzhigh

    org.apache.kafka.connect.transforms.TimestampConverter
    Unix epoch, 文字列 およびコネクト Date/Timestamp型のような異なる形式間でタイムスタンプを変換します。個々のフィールドあるいは値全体へ適用します。

    レコードキー (org.apache.kafka.connect.transforms.TimestampConverter$Key) あるいは値 (org.apache.kafka.connect.transforms.TimestampConverter$Value) のために設計された具体的な変換型を使います。

    名前 説明 種類 デフォルト 有効な値 重要性
    target.type望ましいタイムスタンプの表現: string, unix, Date, Time あるいは Timestamp文字列high
    フィールドタイムスタンプを含むフィールド、あるいは値全体がタイムスタンプの場合は空文字列""high
    formatタイムスタンプのための SimpleDateFormat互換の形式。type=string の場合は出力を生成するために使われます。あるいは入力が文字列の場合は入力をパースするために使われます。文字列""medium

    REST API

    Kafkaコネクトはサービスとして動作することを目的としているため、コネクタを管理するためにREST APIも提供します。REST APIサーバはlisteners 設定オプションを使って設定することができます。このフィールドは以下の形式でlistenerのリストを含まなければなりません: protocol://host:port,protocol2://host2:port2. 現在のところサポートされるプロトコルは httphttpsです。例えば:

            listeners=http://localhost:8080,https://localhost:8443
        

    デフォルトでは、listenersが指定されない場合、RESTサーバがHTTPプロトコルを使ってポート8083で動きます。HTTPSを使う場合は、設定にSSL設定が含まれなければなりません。デフォルトでは、ssl.* 設定を使うでしょう。Kafkaブローカーへの接続ではなくREST APIのための異なる設定を使う必要がある場合、フィールドは listeners.httpsを前に付けることができます。プリフィックスを使う場合は、前に置かれたオプションのみが使われ、プリフィックスを持たないssl.*オプションは無視されるでしょう。以下のフィールドはREST APIのためのHTTPSを設定するために使うことができます:

    • ssl.keystore.location
    • ssl.keystore.password
    • ssl.keystore.type
    • ssl.key.password
    • ssl.truststore.location
    • ssl.truststore.password
    • ssl.truststore.type
    • ssl.enabled.protocols
    • ssl.provider
    • ssl.protocol
    • ssl.cipher.suites
    • ssl.keymanager.algorithm
    • ssl.secure.random.implementation
    • ssl.trustmanager.algorithm
    • ssl.endpoint.identification.algorithm
    • ssl.client.auth

    REST APIはユーザによってKakfaコネクトを監視/管理するためだけに使われるわけではありません。Kafkaコネクトのクラスタ間の通信にも使われます。フォロワーのノードのREST API上で受信されたリクエストは、リーダーノードのREST APIに転送されるでしょう。In case the URI under which is given host reachable is different from the URI which it listens on, the configuration options rest.advertised.host.name, rest.advertised.port and rest.advertised.listener can be used to change the URI which will be used by the follower nodes to connect with the leader. HTTPとHTTPSの両方のlistenerを使う場合、どのlistenerがクラスタを横断する通信のために使われるかを定義するためにrest.advertised.listenerオプションも使うことができます。ノード間の通信のためにHTTPSを使う場合、HTTPSクライアントを設定するために同じssl.* あるいは listeners.https オプションが使われるでしょう。

    以下は現在ところサポートされるREST APIのエンドポイントです:

    • GET /connectors - アクティブなコネクタのリストを返します
    • POST /connectors - 新しいコネクタを返します; リクエストのボディは文字列name フィールドと、コネクタの設定パラメータを持つ config フィールドを含むJSONオブジェクトでなければなりません。
    • GET /connectors/{name} - 特定のコネクタについての情報を取得します
    • GET /connectors/{name}/config - 特定のコネクタのための設定パラメータを取得します
    • PUT /connectors/{name}/config - 特定のコネクタのための設定パラメータを更新します
    • GET /connectors/{name}/status - 実行中、失敗、中止など、どのワーカーに割り当てられているか、失敗した場合はエラー情報、全てのタスクの状態を含む、現在のコネクタの情報を取得する
    • GET /connectors/{name}/tasks - 現在のところコネクタのために動作しているタスクのリストを取得します
    • GET /connectors/{name}/tasks/{taskid}/status - 実行中、失敗、中止など、どのワーカーに割り当てられているか、失敗した場合はエラー情報を含む、タスクの現在の状態を取得する
    • PUT /connectors/{name}/pause - コネクタとそのタスクを休止します。これはコネクタが再開されるまでメッセージの処理を停止します
    • PUT /connectors/{name}/resume - 休止されたコネクタを再開します (あるいはコネクタが休止されていない場合は何もしません)
    • POST /connectors/{name}/restart - コネクタを再開します (一般的にそれが失敗したからです)
    • POST /connectors/{name}/tasks/{taskId}/restart - 個々のタスクを再開します (一般的にそれが失敗したからです)
    • DELETE /connectors/{name} - 全てのタスクを停止しその設定を削除して、コネクタを削除します

    Kafka コネクトはコネクタのプラグインについての情報を取得するREST APIも提供します:

    • GET /connector-plugins- Kafkaコネクト クラスタ内にインストールされているコネクタ プラグインのリストを返します。APIはリクエストを処理するワーカー上のコネクタのみをチェックします。新しいコネクタのjarを追加した場合特にrollingアップグレードの間に一貫性の無い結果を見るかもしれないことを意味します
    • PUT /connector-plugins/{connector-type}/config/validate - 設定の定義に対して提供された設定値を検証します。このAPIは設定の検証ごとに実施し、示唆される値と検証中のエラーメッセージを返します。

    8.3コネクタ開発ガイド

    このガイドは開発者がKafkaコネクタがKafkaと他のシステム間でデータを移動するために新しいコネクタを書く方法を説明します。2,3の主要な概念を簡単に復習し、それから簡単なコネクタを生成する方法を説明します。

    中核となる概念とAPI

    コネクタとタスク

    データをKafkaと他のシステム間でコピーするには、ユーザはデータをpullあるいはpushするシステムのためのコネクタを作成します。コネクタは2つの持ち味で供給されます: SourceConnectors は他のシステムからデータをインポートします (たとえば JDBCSourceConnector はリレーショナル データベースをKafkaにインポートするでしょう)、そしてSinkConnectors はデータをエクスポートします (たとえば HDFSSinkConnector はKafka トピックの内容をHDFSファイルにエクスポートするでしょう)。

    コネクタ はそれら自身のデータのコピーを行いません: それらの設定はコピーされるデータを記述します。コネクタ はジョブをワーカーに分散することができる タスク のセットへ分割する責任があります。これらのタスクも2つの対応する持ち味で提供されます: SourceTaskSinkTask

    手持ちの割り当てを使って、各タスク データのサブセットをKafkaへ、あるいはKafkaからコピーしなければなりません。Kafka コネクトでは、これらの割り当てを一貫性のあるスキーマを持つレコードから成る入力と出力ストリームのセットとして常に構成できる必要があります。このマッピングは時には明白です: ログファイルのセット中の各ファイルは、ファイル内のバイトのオフセットとして格納された同じスキーマとオフセットを使ってレコードを形成する各パースされた行を持つストリームと見なすことができます。他の場合では、このモデルにマップするためにより努力が求められるかもしれません: JDBC コネクタは各テーブルをストリームにマップすることができますが、オフセットはより不明確です。1つの可能なマッピングは、逐次的に新しいデータを返すクエリを生成するためにタイムスタンプのカラムを使い、最後にクエリされたタイムスタンプはオフセットとして使うことができます。

    ストリームとレコード

    各ストリームはキー-値 レコードの系列でなければなりません。キーと値の両方は複雑な構造を持つかもしれません -- 多くのprimitiveな型が提供されますが、配列、オフジェクト および入れ子の構造も同様に表現されるかもしれません。実行時のデータ形式は特定のシリアライズ化形式を仮定しません; この変換はフレームワークによって内部的に処理されます。

    キーと値に加えて、レコード(ソースによって生成され、シンクに配送されるものの両方)は関連するストリームIDとオフセットを持ちます。障害時に不必要な再処理とイベントの複製を避けながら、処理が最後のコミットされたオフセットから再開できるように、処理されたデータのオフセットを定期的にコミットするためにフレームワークによってそれらが使われます。

    動的なコネクタ

    全てのジョブが静的ではないため、コネクタの実装は再設定が必要になるかもしれない全ての変更のために外部システムを監視する責任もあります。例えば、JDBCSourceConnectorの例では、Connector は各Taskにテーブルのセットを割り当てるかもしれません。新しいテーブルが生成される時、設定を更新することで新しいテーブルをTasksの1つに割り当てることができるように、これを発見する必要があります。再設定を必要とする変更(あるいはTasksの数の変更)に気づいた時、それはフレームワークに通知し、フレームワークは全ての対応するTasksを更新します。

    簡単なコネクタの開発

    コネクタの開発は2つのインタフェースの実装のみを必要とします。ConnectorTaskfile パッケージ内にKafkaのためのソースコードと一緒に簡単な例が含まれます。このコネクタはスタンドアローン モードで使うことを想定されていて、ファイルの各行を読み込みそれをレコードとして発行するためにSourceConnector/SourceTaskと、各レコードをファイルに書き込むSinkConnector/SinkTaskの実装を持ちます。

    この章の残りはコネクタを作成するための主要なステップを実演するためにいくつかのコードを渡り歩くつもりですが、簡潔さのために詳細が省略されているため開発者は完全な例のソースコードも参照すべきです。

    コネクタの例

    簡単な例としてSourceConnectorをカバーするつもりです。SinkConnector 実装はとても似ています。SourceConnector から継承したクラスを生成することで開始し、パースされた設定情報(読み込むファイル名とデータを送信するトピック)を格納する2,3のフィールドを追加します。

        public class FileStreamSourceConnector extends SourceConnector {
            private String filename;
            private String topic;
        

    代理をするための最も簡単なメソッドはtaskClass()です。これはデータを実際に読み込むためにワーカープロセス内でインスタンス化されるべきクラスを定義します:

        @Override
        public Class<? extends Task> taskClass() {
            return FileStreamSourceTask.class;
        }
        

    以下でFileStreamSourceTask クラスを定義するつもりです。次に、いくつかの標準的なライフサイクル メソッド start()stop() を追加します

    :
        @Override
        public void start(Map<String, String> props) {
            // 完全なバージョンはエラーハンドリングも含みます。
            filename = props.get(FILE_CONFIG);
            topic = props.get(TOPIC_CONFIG);
        }
    
        @Override
        public void stop() {
            // バックグランドの監視が必要では無いため、何もしません。
        }
        

    最後に、実装の実際の核心は taskConfigs() にあります。この場合、1つのファイルを処理しているだけです。つまりmaxTasks 引数によってより多くのタスクを生成することが許されているかもしれませんが、1つのエントリだけを持つリストを返します:

        @Override
        public List<Map<String, String>> taskConfigs(int maxTasks) {
            ArrayList<Map<String, String>> configs = new ArrayList<>();
            // ただ1つの入力ストリームだけが意味を為します。
            Map<String, String> config = new HashMap<>();
            if (filename != null)
                config.put(FILE_CONFIG, filename);
            config.put(TOPIC_CONFIG, topic);
            configs.add(config);
            return configs;
        }
        

    例では使われていませんが、SourceTask もソース システム内のオフセットをコミットするための2つAPIを提供します: commitcommitRecord。APIはメッセージのための通知の仕組みを持つソース システムのために提供されます。これらのメソッドを上書きすることにより、一度メッセージがKafkaに書き込まれると、ソースコネクタはソース システムにまとめてあるいは個々にメッセージを通知することができます。commit API はソースシステム内にpollによって返されたオフセットまでオフセットを格納します。このAPIの実装はコミットが完了するまでブロックしなければなりません。Kafkaに書き込まれた後で、commitRecord API は各SourceRecord についてソース システム内のオフセットを保存します。Kafkaコネクトは自動的にオフセットを記録するため、SourceTaskはそれらを実装する必要はありません。コネクタがソースシステム内のメッセージを通知する必要が無い場合、APIのうちの1つだけが一般的に必要とされます。

    複数のタスクであっても、このメソッドの実装は通常とても単純です。単に入力タスクの数を決定する必要があります。これはデータを取り出してきたリモートのサービスへの連絡を必要とするかも知れず、従ってそれらを分け合います。作業をタスクに分割する幾つかのパターンはとても一般的なため、これらの問題を単純にするためにいくつかのユーティリティがConnectorUtilsで提供されます。

    この単純な例は動的な入力を含まないことに注意してください。タスクの設定への更新がどうやって起動するかについては次の章の議論をみてください。

    タスクの理恵 - ソース タスク

    次に、対応する SourceTaskの実装を説明するつもりです。実装は短いですが、このガイド内で完全にカバーするにはあまりに長いです。実装のほとんどを説明するために疑似コード使うつもりですが、完全な例についてはソースコードを参照することができます。

    コネクタの時と全く同じように、適切な基本Task クラスから継承しているクラスを作成する必要があります。それも幾つかの標準的なライフサイクルのメソッドを持ちます:

        public class FileStreamSourceTask extends SourceTask {
            String filename;
            InputStream stream;
            String topic;
    
            @Override
            public void start(Map<String, String> props) {
                filename = props.get(FileStreamSourceConnector.FILE_CONFIG);
                stream = openOrThrowError(filename);
                topic = props.get(FileStreamSourceConnector.TOPIC_CONFIG);
            }
    
            @Override
            public synchronized void stop() {
                stream.close();
            }
        

    これらはわずかに単純化されたバージョンですが、これらのメソッドが比較的単純でなければならず、それらが実施すべき唯一の仕事はリソースの割り当てあるいは解放であることを示します。この実装について注意する2つのポイントがあります。最初に、start() メソッドはまだ以前のオフセットからの再開を処理しません。これは後の章で説明されるでしょう。次に、stop() メソッドは同期されます。SourceTasks は無期限にブロックすることができる専用スレッドが与えられているため、これが必要でしょう。つまり、それらはワーカー内の別のスレッドからの呼び出しを使って停止される必要があります。

    次に、タスクの主要な機能を実装します。入力システムからイベントを取得し、List<SourceRecord>を返すpoll()メソッド:

        @Override
        public List<SourceRecord> poll() throws InterruptedException {
            try {
                ArrayList<SourceRecord> records = new ArrayList<>();
                while (streamValid(stream) && records.isEmpty()) {
                    LineAndOffset line = readToNextLine(stream);
                    if (line != null) {
                        Map<String, Object> sourcePartition = Collections.singletonMap("filename", filename);
                        Map<String, Object> sourceOffset = Collections.singletonMap("position", streamOffset);
                        records.add(new SourceRecord(sourcePartition, sourceOffset, topic, Schema.STRING_SCHEMA, line));
                    } else {
                        Thread.sleep(1);
                    }
                }
                return records;
            } catch (IOException e) {
                // Underlying stream was killed, probably as a result of calling stop. Allow to return
                // null, and driving thread will handle any shutdown if necessary.
            }
            return null;
        }
        

    また幾つかの詳細を省略しましたが、重要なステップを見ることができます: poll() メソッドは繰り返し呼ばれ、各呼び出しについてファイルからレコードを読み込みを繰り返すでしょう。読み込む各行について、ファイルのオフセットも追跡します。情報の4つの構成要素を持つ出力SourceRecord を生成するためにこの情報を使います: ソース パーティション (1つだけ存在し、読み込まれる1つのファイル)、ソース オフセット (ファイル内のバイトのオフセット)、出力トピック名、そして出力値 (行。この値が常に文字列であることを示すスキーマを含みます)。SourceRecordコンストラクタの他の変種も特定の出力パーティション、キーおよびヘッダを含むことができます。

    この実装は通常のJava InputStream インタフェースを使用し、データが利用可能ではない場合はsleepするかもしれないことに注意してください。Kafkaコネクトは専用のスレッドを使って各タスクを提供するため、これは許容されます。タスクの実装は基本的なpoll()インタフェースに準拠する必要がありますが、それらがどのように実装されるかについて多くの柔軟性を持ちます。この場合、NIOに基づいた実装は最も効果的でしょうが、この単純なやり方は動作し、実装が速く、Javaの古いバージョンと互換性があります。

    シンク タスク

    以前の章は単純な SourceTaskを実装する方法を説明しました。SourceConnectorSinkConnectorとは異なり、SourceTask はpullインタフェースを使用しSinkTask はpushインタフェースを使用するため、SourceTaskSinkTask はとても異なるインタフェースを持ちます。両方とも共通のライフサイクル メソッドを共有しますが、SinkTask インタフェースはとても異なります:

        public abstract class SinkTask implements Task {
            public void initialize(SinkTaskContext context) {
                this.context = context;
            }
    
            public abstract void put(Collection<SinkRecord> records);
    
            public void flush(Map<TopicPartition, OffsetAndMetadata> currentOffsets) {
            }
        

    SinkTask ドキュメントは完全な詳細を含みますが、このインタフェースはSourceTaskとよく似て単純です。put() メソッドは、SinkRecordsのセットを受け付け、必要な全ての変換を行い、宛先のシステム内にそれらを格納する実装のほとんどを含む必要があります。このメソッドは返す前にデータが完全に宛先のシステムに書き込まれることを確実にする必要はありません。実際、多くの場合で内部的なバッファリングは便利なため、レコードの全体のバッチは一度に送ることができ、イベントをダウンストリームのデータストアに挿入するオーバーヘッドを減らします。SinkRecordsSourceRecordsとして本質的に同じ情報を含みます: Kafkaトピック, パーティション, オフセット, イベント キーと値、および任意のヘッダ。

    flush() メソッドはオフセットのコミット処理の間に使われます。これによりイベントが紛失されないようにタスクは障害から回復しセーフポイントから回復することができます。メソッドは未解決の全てのデータを宛先のシステムにpushする必要があり、書き込みが通知されるまでブロックします。offsets パラメータはしばしば無視することができますが、確実に1回の配送を提供するために宛先のストア内のオフセット情報を格納したい実装の場合は便利です。例えば、HDFSコネクタはこれを行い、flush()オペレーションが自動的にデータとHDFS内の最終的な場所へのオフセットをコミットするようにするためにatomicな移動オペレーションを使うことができます。

    以前のオフセットからの回復

    SourceTaskの実装は各レコードを使ってストリームID (入力ファイル名)とオフセット(ファイル内の位置)を含みます。フレームワークは障害時にタスクが回復し、再処理され、ひょっとすると重複するイベントの数を最小化できるように (あるいは、例えばスタンドアローンモード、あるいはジョブの再設定のために、Kafkaコネクトが穏やかに停止した場合は最も最近のオフセットから再開)、オフセットを定期的にコミットするためにこれを使います。このコミット プロセスはフレームワークよって完全に自動化されますが、コネクタのみが位置から回復するために入力ストリーム内の正しい位置への戻りを探す方法を知っています。

    開始時に正しく回復するために、タスクはオフセットデータへアクセスするためのinitialize()メソッドに渡されたSourceContextを使うことができます。initialize()の中で(存在するのであれば)オフセットを読み込み、その位置を探すために少し多くのコードを追加するでしょう:

            stream = new FileInputStream(filename);
            Map<String, Object> offset = context.offsetStorageReader().offset(Collections.singletonMap(FILENAME_FIELD, filename));
            if (offset != null) {
                Long lastRecordedOffset = (Long) offset.get("position");
                if (lastRecordedOffset != null)
                    seekToOffset(stream, lastRecordedOffset);
            }
        

    もちろん、入力ストリームのそれぞれについて多くのキーを読み込む必要があるかもしれません。OffsetStorageReader インタフェースにより、効率的に全てのオフセットを読み込むためにbulk読み込みを発行し、そして各入力ストリームを調べることで適切な位置に適用することができます。

    動的な 入力/出力ストリーム

    Kafkaコネクトは、各テーブルを個々にコピーするために多くのジョブを生成するよりデータベース全体をコピーするようなbulkデータのコピージョブを定義することを目的としています。この設計の1つの帰結は、コネクタのための入力あるいは出力ストリームのセットが時間が経てば変わるかもしれないということです。

    ソース コネクタは変更のためにソースシステムを監視する必要があります。例えばデータベース内のテーブルの追加/削除。変更を捕らえた時に、それらは再構成が必要なConnectorContext オブジェクトを使ってフレームワークに知らせる必要があります。例えば、SourceConnectorの中で:

            if (inputsChanged())
                this.context.requestTaskReconfiguration();
        

    フレームワークはタスクを再構成する前にそれらの進捗をgracefullyにコミットしながら、すぐに新しい設定情報を要求しタスクを更新するでしょう。SourceConnectorの中でこの監視は現在のところコネクタの実装に任されていることに注意してください。この監視に余分なスレッドが必要とされる場合、コネクタは自身でそれを割り当てる必要があります。

    理想的には変化の監視のためのこのコードはConnectorに隔離されていて、タスクはそれらについて心配する必要は無いでしょう。しかし、最も一般的に入力ストリームのうちの1つが入力ストリーム内で破棄、例えばもしテーブルがデータベースから削除される場合された時に、変更はタスクにも影響するかもしれません。TaskConnectorの前に問題に遭遇した場合、これはConnector が変更のためにpollする必要がある場合には一般的です、 Task はその後のエラーを処理する必要があるでしょう。ありがたいことに、これは通常単純に適切な例外をキャッチおよび処理することで処理することができます。

    SinkConnectorsは通常ストリームの追加のみを処理する必要があります。これはそれらの出力(例えば、新しいデータベース テーブル)への新しいエントリに翻訳するでしょう。フレームワークは、入力トピックのセットが正規表現の購読のために変更になる場合などの、Kafkaの入力への全ての変更を管理します。SinkTasks は新しい入力ストリームを期待すべきです。入力ストリームはデータベース内の新しいテーブルのようなダウンストリーム内の新しいリソースの生成を必要とするかもしれません。これらの問題で最もやりにくい状況は、始めて新しい入力ストリームを見て同時に新しいリソースを生成しようとする複数のSinkTasks間で衝突するかもしれません。一方で、SinkConnectorsは一般的にストリームの動的なセットを処理するための特別なコードを必要としないでしょう。

    コネクトの設定の検証

    Kafkaコネクトを使って、実行されるコネクタをサブミットする前にコネクタの設定を検証することができ、Kafkaコネクトはエラーについてフィードバックと推奨される値を提供することができます。これを利用するために、コネクタの開発者は設定定義をフレームワークに公開するためのconfig()の実装を提供する必要があります。

    FileStreamSourceConnector内の以下のコードは設定を定義し、それをフレームワークに公開します。

            private static final ConfigDef CONFIG_DEF = new ConfigDef()
                .define(FILE_CONFIG, Type.STRING, Importance.HIGH, "Source filename.")
                .define(TOPIC_CONFIG, Type.STRING, Importance.HIGH, "The topic to publish data to");
    
            public ConfigDef config() {
                return CONFIG_DEF;
            }
        

    ConfigDef クラスは予想される設定のセットを指定するために使われます。各設定について、名前、型、デフォルトの値、ドキュメント、グループ情報、グループ内の順番、設定値の幅 およびUIでの表示に適した名前を指定することができます。それに加えて、Validator クラスを上書きすることで1つの設定の検証に使われる特別な検証ロジックを提供することができます。更に、設定間で設定間で依存があるかもしれません。例えば有効な値と設定の可視性が他の設定の値に応じて変更されるかもしれません。これを扱うために、ConfigDefを使って設定の依存を指定し、有効な値を取得し現在の設定値に与えられた設定の可視性を設定するために Recommender の実装を提供することができます。

    また、Connector内のvalidate()メソッドは各設定について設定エラーと推奨値と一緒に許される設定のリストを返すデフォルトの検証実装を提供します。しかし、設定の検証のために推奨された値を使わないでしょう。カスタマイズされた設定検証のためのデフォルトの実装を上書きを提供するかもしれません。これは推奨値を使うかもしれません。

    スキーマとの連携

    FileStream コネクタは単純なため良い例ですが、つまらない構造化データも持ちます -- 各行は単なる文字列です。ほとんどすべての現実的なコネクタはもっと複雑なデータ形式を持つスキーマを必要とするでしょう。

    もっと複雑なデータを作成するには、Kafkaコネクトdata APIと連携する必要があるでしょう。ほとんどの構造化レコードはprimitiveな型に加えて2つのクラスとやり取りをする必要があるでしょう: SchemaStruct

    APIドキュメントは完全な参照を提供しますが、ここでは SchemaStructを生成する簡単な例です:

        Schema schema = SchemaBuilder.struct().name(NAME)
            .field("name", Schema.STRING_SCHEMA)
            .field("age", Schema.INT_SCHEMA)
            .field("admin", new SchemaBuilder.boolean().defaultValue(false).build())
            .build();
    
        Struct struct = new Struct(schema)
            .put("name", "Barbara Liskov")
            .put("age", 75);
        

    ソース コネクタを実装している場合、いつそしてどうやってスキーマを作成するかを決める必要があるでしょう。可能であれば、可能な限りそれらを再計算することを避けるべきです。例えば、もしコネクタが固定のスキーマを持つことを保証される場合、それを静的に作成し1つのシングルトンを再利用します。

    しかし、多くのコネクタは動的なスキーマを持つでしょう。これの簡単な例の1つはデータベース コネクタです。たった一つのテーブルだけでも考えると、(テーブルからテーブルに変わるため)スキーマはコネクタ全体について事前定義されないでしょう。しかし、ユーザは ALTER TABLE コマンドを実行するかもしれないため、コネクタのライフタイムを超えて1つのテーブルについて固定されないかもしれません。コネクタはこれらの変更を検知し適切に反応しなければなりません。

    シンク コネクタはデータを消費し従ってスキーマを生成する必要がないため、通常は単純です。しかし、受信したスキーマが期待する形式を持っているかを検証するために十分注意する必要があります。スキーマが一致しない場合 -- 通常はアップストリーム プロデューサを示すものが宛先のシステムへ正しく翻訳することができない無効なデータを生成します -- シンク コネクタはこのエラーをシステムに示すために例外を投げるべきです。

    Kafka コネクタの管理

    Kafka コネクタの REST layer はクラスタの管理を有効にするAPIのセットを提供します。これはコネクタの設定とそれらのタスクの状態を表示し、それらの現在の挙動を変更する(例えば設定の変更とタスクの再起動)ためのAPIを含みます。

    コネクタがクラスタに最初にサブミットされる時、ワーカーは各ワーカーが適切に同じ量の仕事を持つようにクラスタ内のコネクタの完全なセットとそれらのタスクをリバランスします。コネクタが取得するタスクの数を増加あるいは減少する時、あるいはコネクタの設定が変更される時に、この同じリバランスの手順も使われます。ワーカーが割り当てられたワーカーのidを含む、コネクタとそのタスクの現在の状態を見るためにREST APIを使うことができます。例えば、(GET /connectors/file-source/statusを使った)ファイル ソースの状態のクエリは以下のような出力を生成するかもしれません:

        {
        "name": "file-source",
        "connector": {
            "state": "RUNNING",
            "worker_id": "192.168.1.208:8083"
        },
        "tasks": [
            {
            "id": 0,
            "state": "RUNNING",
            "worker_id": "192.168.1.209:8083"
            }
        ]
        }
        

    コネクタとそれらのタスクはステータスの更新をクラスタ内の全てのワーカーが監視する共有トピック(status.storage.topicを使って設定されます)に公開します。ワーカーはこのトピックを非同期に消費するため、状態の変更が状態APIを使って見える前に一般的に(短い)遅延があります。コネクタあるいはそのタスクの1つについて、以下の状態があり得ます:

    • UNASSIGNED: コネクタ/タスクはまだワーカーに割り当てられていない。
    • RUNNING: コネクタ/タスクが実行中。
    • PAUSED: コネクタ/タスクが管理上停止されている。
    • FAILED: コネクタ/タスクが失敗した(通常は例外を上げることで行われます。これは状態出力の中で報告されます)。

    ほとんどの場合において、コネクタとタスクの状態は一致しますが、それらは変更が発生している時、あるいはタスクが失敗した場合に、短い時間の間異なるかもしれません。例えば、コネクタが最初に開始された時、コネクタとそのタスクが全てRUNNING状態に遷移する前に知覚可能な遅延があるかもしれません。コネクタは自動的に失敗したタスクを再起動しないため、タスクが失敗した時にも状態が分岐するでしょう。コネクタ/タスクを手動で再起動するために、上でリスト化された再起動APIを使うことができます。リバランスが発生している間にタスクを再起動しようとすると、コネクタは409(衝突)状態コードを返すだろうことに注意してください。リバランスが完了した後で再試行することができますが、リバランスは効率的にクラスタ内の全てのコネクタとタスクを再起動するため、必要無いかもしれません。

    一時的にコネクタのメッセージ処理を停止するために時には便利です。例えば、もしリモートシステムがメンテナンス中の場合、ログを例外のスパムで一杯にする代わりにソースコネクタが新しいデータのためにpollするのを停止することが望ましいでしょう。このユースケースのために、コネクトは休止/再開APIを提供します。ソース コネクタが休止している間、コネクタは追加のレコードのためのpollを停止するでしょう。シンク コネクタが休止している間、コネクタは新しいメッセージをpushすることを停止するでしょう。休止状態は永続的なもので、もしクラスタを再起動したとしても、コネクタはタスクが再開されるまでメッセージの処理を開始しないでしょう。休止される時に途中の処理が完了するまで時間が掛かるため、コネクタのタスクの全てがPAUSED状態に遷移する前に遅延があることに注意してください。更に、失敗したタスクはそれらが再起動されるまでPAUSED状態に遷移されないでしょう。

    9. Kafka ストリーム

    Kafka Streams はKafka内に格納されているデータの処理と解析のためのクライアントライブラリです。それは、イベント時間と処理時間の間の適切な区別、ウィンドウのサポート、確実に一回の処理セマンティクス、およびアプリケーション状態の単純だが効率的な管理などのような、重要なストリーム処理の概念に基づいています。

    Kafkaストリームは敷居が低いです: 1つのマシーン上で小さな規模の概念実装を素早く書いて実行することができます; そして大容量のプロダクションの作業へスケールアップするために複数のマシーン上でアプリケーションの追加のインスタンスを実行する必要があるだけです。KafkaストリームはKafkaの並行モデルを利用することで同じアプリケーションの複数のインスタンスのロードバランシングを透過的に処理します。

    Kafkaストリームについての詳細はこの 章を読んでください。

    TOP
    inserted by FC2 system