ドキュメント
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。1. 開始
1.1はじめに
. それは正確に何を意味するのか?ストリーミングプラットフォームは3つの主要な機能があります:
- メッセージキューあるいはエンタープライズのメッセージングシステムに似て、レコードのストリームへ発行および購読します。
- レコードのストリームを耐障害性のある方法で格納します。
- 発生した順にレコードのストリームを処理します。
Kafkaは一般的に2つのアプリケーションの大きなクラスのために使われます:
- システムあるいはアプリケーション間でデータを信頼して取得できるリアルタイム ストリーミング データ パイプラインの構築
- データのストリームの変換あるいは反応をするリアルタイム ストリーミング アプリケーションの構築
Kafkaがどのようにこれらのことを行うのかを理解するために、試してみてKafkaの能力を上から下まで調査してみましょう。
最初に2,3の概念:
- Kafkaは複数のデータセンタに跨るかもしれない1つ以上のサーバ上でクラスタとして実行されます。
- Kafkaのクラスタはトピックと呼ばれるカテゴリ内にレコードのストリームを格納します。
- 各レコードはキー、値とタイムスタンプから成ります。
Kafka には4つの主要なAPIがあります:
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 Storm とApache 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 7564Windowsでの使い方:
> 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 での注目すべき変更を見直してください。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2, 0.9.0, 0.10.0, 0.10.1, 0.10.2, 0.11.0, 1.0, 1.1)。
- log.message.format.version=CURRENT_MESSAGE_FORMAT_VERSION (この設定が何をするかについての詳細は、アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (0.11.0, 1.0, 1.1).
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、
inter.broker.protocol.version
を編集し 2.0 に設定することでプロトコルのバージョンを上げることができます。 - 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 2.0 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは 0.11で導入された新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。
アップグレードの追加の注意:
- ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
- プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
- Kafkaストリームコード内でJava8のメソッドのリファレンスを使っている場合は、メソッドの曖昧さを解決するためにコードを更新する必要があるかもしれません。jarファイルのホット スワップだけではうまく行かないかもしれません。
- クラスタ内の全てのブローカーが更新されるまで、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-5674 は
max.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.converter
とinternal.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はブロックするかもしれない
KafkaConsumer
APIのために使われるデフォルトのタイムアウトを指定するために新しいコンシューマ設定default.api.timeout.ms
を追加します。そのKIPはdefault.api.timeout.ms
によって設定されるデフォルトのタイムアウトを使用する代わりに、それらのそれぞれについて使う特定のタイムアウトの指定をサポートするためにそのようなブロッキングAPIに負荷も掛けます。特に、動的なパーティションの割り当てのためにブロックしない新しいpoll(Duration)
API が追加されました。古いpoll(long)
は非推奨になり、将来のバージョンで削除されるでしょう。Overloads have also been added for otherKafkaConsumer
methods likepartitionsFor
,listTopics
,offsetsForTimes
,beginningOffsets
,endOffsets
andclose
that take in aDuration
. - 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.enable
とlog.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 での注目すべき変更を見直してください。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2, 0.9.0, 0.10.0, 0.10.1, 0.10.2, 0.11.0, 1.0)。
- log.message.format.version=CURRENT_MESSAGE_FORMAT_VERSION (この設定が何をするかについての詳細は、アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (0.11.0 あるいは 1.0)。
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、
inter.broker.protocol.version
を編集し 1.1 に設定することでプロトコルのバージョンを上げることができます。 - 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 1.1 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは 0.11で導入された新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。
アップグレードの追加の注意:
- ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
- プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
- 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オプションを設定します。
新しいプロトコルのバージョン
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 での注目すべき変更を見直してください。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は使用している現在のメッセージフォーマットを参照します。以前に上書きされたメッセージ形式のバージョンを持っている場合は、それを現在の値に維持する必要があります。別のやり方として、もし 0.11.0.x より前のバージョンからアップグレードする場合は、CURRENT_KAFKA_VERSION に合致するように CURRENT_MESSAGE_FORMAT_VERSION が設定される必要があります。
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2, 0.9.0, 0.10.0, 0.10.1, 0.10.2, 0.11.0)。
- log.message.format.version=CURRENT_MESSAGE_FORMAT_VERSION (この設定が何をするかについての詳細は、アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- inter.broker.protocol.version=0.11.0
- log.message.format.version=0.11.0
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、
inter.broker.protocol.version
を編集し 1.0 に設定することでプロトコルのバージョンを上げることができます。 - 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- 上で支持されたようにメッセージ形式のバージョンを上書きした場合、それを最新のバージョンにアップグレードするためにもう一度ローリング リスタートをする必要があります。一度全て(あるいはほとんど)のコンシューマが 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.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.enable
をfalse
に設定してください。トピックの削除はデータを削除しオペレーションが可逆ではないことに注意してください (つまり、"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-rate
はrecords-consumed-total
という名前の対応するメトリックを持ちます。 - Mx4j はシステム プロパティ
kafka_mx4jenable
がtrue
に設定された場合にのみ有効にされるでしょう。論理の反転バグにより、以前はデフォルトで有効で、もしkafka_mx4jenable
がtrue
に設定された場合には無効でした。 - クライアントの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.11.0.3 のために設定
- 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 とそれより新しいクライアントをサポートします。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties を更新し、以下のプロパティを追加します。CURRENT_KAFKA_VERSION はアップグレード元のバージョンを参照します。CURRENT_MESSAGE_FORMAT_VERSION は現在使用している現在のメッセージフォーマットを参照します。以前にメッセージフォーマットを上書きしていない場合は、CURRENT_MESSAGE_FORMAT_VERSION は CURRENT_KAFKA_VERSION に一致しなければなりません。
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2, 0.9.0, 0.10.0, 0.10.1 or 0.10.2)。
- log.message.format.version=CURRENT_MESSAGE_FORMAT_VERSION (この設定が何をするかについての詳細は、アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、
inter.broker.protocol.version
を編集し 0.10.0.0 に設定します。しかしまだlog.message.format.version
を変更してはいけません。 - 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- 一度全て(あるいはほとんど)のコンシューマが 0.11.0 以上にアップグレードされると、各ブローカー上で log.message.format.version を 0.11.0 に変更し、それらを1つずつ再起動します。古いScalaのコンシューマは新しいメッセージフォーマットをサポートしないため、down-conversionのパフォーマンスコストを避ける(あるいは (確実に一回のセマンティクスを利用する)には、新しいJavaコンシューマが使われなければならないことに注意してください。
アップグレードの追加の注意:
- ダウンタイムを喜んで許容する場合は、単純に全てのブローカーをダウンし、コードを更新し、それらをバックアップします。それらはデフォルトで新しいプロトコルを使って開始するでしょう。
- プロトコルのバージョンアップと再起動はブローカーがアップグレードされた後でいつでも行うことができます。すぐにしなければならないことはありません。メッセージのフォーマットのバージョンと同じです。
- グローバル設定
log.message.format.version
を更新する前に、トピック管理ツール(bin/kafka-topics.sh
) を使って個々のトピック上で 0.11.0 メッセージフォーマットを有効にすることも可能です。 - 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.11.0.3 のために設定
- 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.enable
をtrue
に設定してください。 - プロデューサの設定
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を有効にする必要はなく、使わない場合はブローカーの挙動には影響がないことに注意してください。
- 新しいJavaプロデューサとコンシューマのみが確実に1回のセマンティクスをサポートします。
- これらの機能は 0.11.0 メッセージ フォーマットに決定的に依存します。古いフォーマットでそれらを使おうとすると、サポートされないバージョンのエラーになるでしょう。
- トランザクションの状態は新しい内部的なトピック
__transaction_state
に格納されます。個のトピックは最初にトランザクション的なリクエストAPIを使おうとするまで生成されません。コンシューマのオフセット トピックに似て、トピックの設定を制御する幾つかの設定があります。例えば、transaction.state.log.min.isr
はこのトピックのための最小のISRを制御します。オプションの完全なリストについてはユーザガイド内の設定の章を見てください。 - 安全なクラスタのために、トランザクション的なAPIは
bin/kafka-acls.sh
を使って有効にすることができる新しいACLを必要とします。tool. - 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 とそれより新しいクライアントをサポートします。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2, 0.9.0, 0.10.0 or 0.10.1)。
- log.message.format.version=CURRENT_KAFKA_VERSION (この設定が何をするかについての詳細は アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.2 に設定することでプロトコルのバージョンを上げることができます。
- 以前のメッセージフォーマットが 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 以降に変更された後で変更されるべきです。
- 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- もし 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.2.2 のために設定
- 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 ブローカーも古いクライアントをサポートします)。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば 0.8.2.0, 0.9.0.0 or 0.10.0.0)。
- log.message.format.version=CURRENT_KAFKA_VERSION (この設定が何をするかについての詳細は アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- 一度にブローカーをアップグレードします: ブローカーをシャットダウンし、コードを更新し、再起動します。
- クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.1.0 に設定することでプロトコルのバージョンを上げることができます。
- 以前のメッセージフォーマットが 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 以降に変更された後で変更されるべきです。
- 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- もし 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.1.2 のために設定
- 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.FetchRequest
とkafka.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 クライアントの場合には必要ありません。
ローリングアップグレードに関して:
- 全てのブローカーの server.properties ファイルを更新し、以下のプロパティを追加します:
- inter.broker.protocol.version=CURRENT_KAFKA_VERSION (例えば、0.8.2 または 0.9.0.0)。
- log.message.format.version=CURRENT_KAFKA_VERSION (この設定が何をするかについての詳細は アップグレードに伴う潜在的なパフォーマンスの影響を見てください。)
- ブローカーのアップグレード。単純にブローカーをダウンし、コードを更新し、再起動することで一度に行うことができます。
- クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.10.0.0 に設定することでプロトコルのバージョンを上げることができます。注意: まだ log.message.format.version に触れるべきではありません - このパラメータはいったん全てのコンシューマが 0.10.0.0 にアップグレードされてからのみ変更されるべきです。
- 新しいプロトコルのバージョンが効果を現すようにブローカーを1つずつ再起動します。
- 一度全てのコンシューマが 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 ダウンストリームを使っている場合は、クラスタも同様に最初にアップグレードされるべきです。ローリングアップグレードに関して:
- 全てのブローカー上の server.properties ファイルを更新し、以下のプロパティを追加します : inter.broker.protocol.version=0.8.2.X
- ブローカーのアップグレード。単純にブローカーをダウンし、コードを更新し、再起動することで一度に行うことができます。
- クラスタ全体がアップグレードされると、inter.broker.protocol.version を編集し 0.9.0.0 に設定することでプロトコルのバージョンを上げることができます。
- 新しいプロトコルのバージョンが効果を現すようにブローカーを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クラスタのトピックに送信することができます。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.connect | Zookeeper ホスト文字列 | 文字列 | high | read-only | ||
advertised.host.name | 非推奨: `advertised.listeners` または `listeners` が設定されていない場合にのみ使われます。代わりに `advertised.listeners`を使ってください。クライアントが使うためにZooKeeperに公開されるホスト名。IaaS 環境では、これはブローカーがバインドするインタフェースとは異なる必要があるかも知れません。これが設定されない場合、設定されていれば`host.name` の値が使われるでしょう。そうでなければ、java.net.InetAddress.getCanonicalHostName() から返される値を使うでしょう。 | 文字列 | null | high | read-only | |
advertised.listeners | `リスナー`設定プロパティと異なる場合、クライアントが使用するZooKeeperに公開されるリスナー。IaaS 環境では、これはブローカーがバインドするインタフェースとは異なる必要があるかも知れません。これが設定されない場合は、`listeners`の値が使われるでしょう。`listeners` と異なり、それは 0.0.0.0 メタ-アドレスを通知するのは正しくありません。 | 文字列 | null | high | per-broker | |
advertised.port | 非推奨: `advertised.listeners` または `listeners` が設定されていない場合にのみ使われます。代わりに `advertised.listeners`を使ってください。クライアントが使用するZooKeeperへ公開されるポート。IaaS 環境では、これはブローカーがバインドするポートとは異なる必要があるかも知れません。設定されない場合は、ブローカーがバインドする同じポートを公開するでしょう。 | int | null | high | read-only | |
auto.create.topics.enable | サーバ上でのトピックの自動生成を有効 | boolean | true | high | read-only | |
auto.leader.rebalance.enable | 自動リーダーバランシングを有効にする。通常の間隔でもし必要であれば、バックグランドスレッドはリーダーのバランスをチェックし起動します。 | boolean | true | high | read-only | |
background.threads | 様々なバックグラウンド処理タスクが使うスレッドの数 | int | 10 | [1,...] | high | cluster-wide |
broker.id | このサーバのためのブローカーid。設定しない場合はユニークなブローカーidが生成されるでしょう。zookeeperが生成したブローカーidとユーザ定義のブローカーidが衝突することを避けるために、生成されるブローカーidは reserved.broker.max.id + 1 から始まります。 | int | -1 | high | read-only | |
compression.type | 指定されたトピックのための最終的な圧縮タイプを指定する。この設定は標準的な圧縮コーディック('gzip', 'snappy', 'lz4')を受け付けます。更に、非圧縮に相当する 'uncompressed'; プロデューサによって設定された元の圧縮コーディックを保持することを意味する'producer' を受け付けます。 | 文字列 | producer | high | cluster-wide | |
delete.topic.enable | トピックの削除を有効にする。この設定が切られている場合は管理ツールを使ったトピックの削除は何も効果が無いでしょう。 | boolean | true | high | read-only | |
host.name | 非推奨: `listeners` が設定されていない場合にのみ使われます。代わりに `listeners` を使ってください。ブローカーのホスト名。これが設定されている場合は、このアドレスへのみバインドするでしょう。これが設定されていない場合は、全てのインタフェースにバインドするでしょう。 | 文字列 | "" | high | read-only | |
leader.imbalance.check.interval.seconds | コントローラによって起動されるパーティションのリバランスの調査の頻度 | long | 300 | high | read-only | |
leader.imbalance.per.broker.percentage | ブローカーあたりに許可されるリーダーの非バランスの割合。ブローカー毎にこの値を超えた場合は、コントローラーはリーダーのバランスを開始するでしょう。値はパーセンテージで指定されます。 | int | 10 | high | read-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 | 文字列 | null | high | per-broker | |
log.dir | ログデータが保持されるディレクトリ (log.dirs プロパティの補足) | 文字列 | /tmp/kafka-logs | high | read-only | |
log.dirs | ログデータが保持されるディレクトリ。設定しない場合は、log.dirの値が使われます | 文字列 | null | high | read-only | |
log.flush.interval.messages | メッセージがディスクにフラッシュされる前にログパーティション上で集約されるメッセージの数 | long | 9223372036854775807 | [1,...] | high | cluster-wide |
log.flush.interval.ms | メモリ内に保持されたメッセージがディスクにフラッシュされるまでの最大ms。設定されていない場合は、log.flush.scheduler.interval.ms の値が使われます。 | long | null | high | cluster-wide | |
log.flush.offset.checkpoint.interval.ms | ログの回復ポイントとして振舞う最後のフラッシュの永続レコードを更新する頻度 | int | 60000 | [0,...] | high | read-only |
log.flush.scheduler.interval.ms | ログがディスクにフラッシュされる必要があるかどうかをログのフラッシャーがチェックする頻度 | long | 9223372036854775807 | high | read-only | |
log.flush.start.offset.checkpoint.interval.ms | ログの開始オフセットの永続レコードを更新する頻度 | int | 60000 | [0,...] | high | read-only |
log.retention.bytes | ログが削除されるまでの最大サイズ。 | long | -1 | high | cluster-wide | |
log.retention.hours | ログを削除するまで保持する時間の数(時間単位)、log.retention.ms プロパティの3つめのパラメータ | int | 168 | high | read-only | |
log.retention.minutes | ログを削除するまで保持する分の数(分単位)、log.retention.ms プロパティの2つめのパラメータ設定しない場合は、log.retention.hours の値が使われます。 | int | null | high | read-only | |
log.retention.ms | ログファイルが削除されるまでに保持されるミリ秒数。設定されない場合は、log.retention.minutes の値が使われます。 | long | null | high | cluster-wide | |
log.roll.hours | 新しいログのセグメントがロールアウトされるまでの最大時間(時間単位)、log.roll.ms プロパティの2つ目のパラメータ | int | 168 | [1,...] | high | read-only |
log.roll.jitter.hours | logRollTimeMillis から差し引く最大のジッター (時間単位)、log.roll.jitter.ms プロパティの2つ目のパラメータ | int | 0 | [0,...] | high | read-only |
log.roll.jitter.ms | logRollTimeMillis から差し引く最大のジッター (ミリ秒)。設定しない場合は、log.roll.jitter.hours の値が使われます | long | null | high | cluster-wide | |
log.roll.ms | 新しいログの断片がロールアウトされるまでの最大時間(ミリ秒)。設定しない場合は、log.roll.hours の値が使われます | long | null | high | cluster-wide | |
log.segment.bytes | 1つのログファイルの最大サイズ | int | 1073741824 | [14,...] | high | cluster-wide |
log.segment.delete.delay.ms | ファイルシステムからファイルを削除するまでの総待ち時間 | long | 60000 | [0,...] | high | cluster-wide |
message.max.bytes | Kafkaで可能な最も大きなレコードのバッチサイズ。これが増え、0.10.2より古いコンシューマがある場合、コンシューマがこの大きさのレコードバッチを取得できるようにコンシューマの取得サイズも増やす必要があります。 最新のメッセージフォーマットのバージョンでは、効率化のためにレコードは常にバッチにグループ化されます。以前のメッセージフォーマットのバージョンでは、圧縮されていないレコードはバッチにグループ化されず、この制限は1つのレコードにのみ適用されます。 トピックごとにトピックレベルの | int | 1000012 | [0,...] | high | cluster-wide |
min.insync.replicas | プロデューサがackを "all" (あるいは "-1") に設定する場合、min.insync.replicasは書き込みが成功したと見なされるように書き込みを知らせる必要があるレプリカの最小数を指定します。この最小限に一致しない場合、プロデューサは例外(NotEnoughReplicas あるいは NotEnoughReplicasAfterAppendのどちらか)を上げるでしょう。 一緒に使った場合、min.insync.replicas と acks は素晴らしい耐久性の保証を強化することができます。典型的なシナリオは、3つのレプリケーション ファクターを持つトピックを生成し、min.insync.replicas を 2 に設定し、"all" のackを使って生成します。これは、もしレプリカの過半数が書き込みを受け取らなかった場合にプロデューサが例外を上げることを保証するでしょう。 | int | 1 | [1,...] | high | cluster-wide |
num.io.threads | サーバがリクエストの処理のために使用するスレッド数。ディスク I/Oが含まれるかもしれません。 | int | 8 | [1,...] | high | cluster-wide |
num.network.threads | サーバがネットワークからリクエストを受け取り、応答をネットワークに送信するために使われるスレッドの数。 | int | 3 | [1,...] | high | cluster-wide |
num.recovery.threads.per.data.dir | 起動時のログの回復とシャットダウン時にフラッシュするために使われるデータディレクトリあたりのスレッドの数。 | int | 1 | [1,...] | high | cluster-wide |
num.replica.alter.log.dirs.threads | レプリカをログディレクトリ間で移動できるスレッド数。ディスク I/Oが含まれるかもしれません。 | int | null | high | read-only | |
num.replica.fetchers | ソースブローカーからメッセージをリプリケートするために使われるフェッチスレッドの数。この値を増加することで追随するブローカーのI/O並行度の度合いを増やすことができます。 | int | 1 | high | cluster-wide | |
offset.metadata.max.bytes | オフセット コミットに関連するメタデータ エントリのための最大サイズ。 | int | 4096 | high | read-only | |
offsets.commit.required.acks | コミットが受け付けられるまでに必要とされるack。通常はデフォルト(-1)を上書くべきではありません | short | -1 | high | read-only | |
offsets.commit.timeout.ms | オフセット トピックのための全てのレプリカがコミットを受け取るか、このタイムアウトに達するまで、オフセットコミットは遅延するでしょう。これはプロデューサのリクエストタイムアウトに似ています。 | int | 5000 | [1,...] | high | read-only |
offsets.load.buffer.size | オフセットをキャッシュにロードする時にオフセット セグメントから読み込むためのバッチサイズ。 | int | 5242880 | [1,...] | high | read-only |
offsets.retention.check.interval.ms | stale オフセットをチェックする頻度 | long | 600000 | [1,...] | high | read-only |
offsets.retention.minutes | この保持期間より古いオフセットは捨てられるでしょう。 | int | 10080 | [1,...] | high | read-only |
offsets.topic.compression.codec | オフセットトピックのための圧縮コーディック - 圧縮は "atomic" コミットを実現するために使われるかも知れません | int | 0 | high | read-only | |
offsets.topic.num.partitions | オフセット コミット トピックのためのパーティション数 (配備の後で変更すべきではありません) | int | 50 | [1,...] | high | read-only |
offsets.topic.replication.factor | オフセット トピックのためのリプリケーション要素 (可用性を保証するするために高く設定します)。クラスタのサイズがこのリプリケーション要素の要請に合うまで、内部的な自動トピックの生成は失敗するでしょう。 | short | 3 | [1,...] | high | read-only |
offsets.topic.segment.bytes | ログの圧縮とキャッシュのロードを速くし易いように、オフセットトピックのセグメントのバイトは比較的小さくすべきです。 | int | 104857600 | [1,...] | high | read-only |
port | 非推奨: `listeners` が設定されていない場合にのみ使われます。代わりに `listeners` を使ってください。接続をlistenし、そして受け付けるポート | int | 9092 | high | read-only | |
queued.max.requests | ネットワークスレッドをブロックするまでに許容されるリクエストのキューの数 | int | 500 | [1,...] | high | read-only |
quota.consumer.default | 非推奨: 動的なデフォルトのクォートがZookeeprのために | long | 9223372036854775807 | [1,...] | high | read-only |
quota.producer.default | 非推奨: 動的なデフォルトのクォートがZookeeprのために | long | 9223372036854775807 | [1,...] | high | read-only |
replica.fetch.min.bytes | 各フェッチ応答に期待される最小バイト。十分なバイト数でなければ、replicaMaxWaitTimeMs まで待機します | int | 1 | high | read-only | |
replica.fetch.wait.max.ms | 随行するレプリカによって発行された各フェッチリクエストの最大待ち時間。この値は低いスループットのトピックについてISRの縮小を避けるために常にreplica.lag.time.max.ms より少ない必要があります。 | int | 500 | high | read-only | |
replica.high.watermark.checkpoint.interval.ms | 高いウォーターマークがディスクに保存される頻度 | long | 5000 | high | read-only | |
replica.lag.time.max.ms | もしフォロワーが何も取得リクエストを送信していないか、少なくともこの時までリーダーログの終了オフセットまで消費をしていない場合、リーダーはisrからフォロワーを削除するでしょう。 | long | 10000 | high | read-only | |
replica.socket.receive.buffer.bytes | ネットワークリクエストのためのソケット受信バッファ | int | 65536 | high | read-only | |
replica.socket.timeout.ms | ネットワークリクエストのためのソケットタイムアウト。値は少なくとも replica.fetch.wait.max.ms でなければなりません。 | int | 30000 | high | read-only | |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。 | int | 30000 | high | read-only | |
socket.receive.buffer.bytes | ソケットサーバのソケットの SO_RCVBUF バッファ値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 102400 | high | read-only | |
socket.request.max.bytes | ソケットリクエスト内の最大バイト数 | int | 104857600 | [1,...] | high | read-only |
socket.send.buffer.bytes | ソケットサーバのソケットの SO_SNDBUF バッファ値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 102400 | high | read-only | |
transaction.max.timeout.ms | トランザクションに許されるタイムアウトの最大。クライアントがリクエストしたトランザクション時間がこれを超えると、ブローkーアは InitProducerIdRequest 内でエラーを返すでしょう。これによりクライアントはあまりに大きいタイムアウトを避けることができます。これはトランザクションに含まれるトピックからのコンシューマの読み込みを立ち往生させるかもしれません。 | int | 900000 | [1,...] | high | read-only |
transaction.state.log.load.buffer.size | プロデューサidとトランザクションをキャッシュにロードする時のトランザクションログ セグメントから読み込むバッチサイズ。 | int | 5242880 | [1,...] | high | read-only |
transaction.state.log.min.isr | トランザクション トピックのための min.insync.replicas 設定を上書きします。 | int | 2 | [1,...] | high | read-only |
transaction.state.log.num.partitions | トランザクション トピックのためのパーティション数 (配備の後で変更すべきではありません) | int | 50 | [1,...] | high | read-only |
transaction.state.log.replication.factor | トランザクション トピックのためのリプリケーション要素 (可用性を保証するするために高く設定します)。クラスタのサイズがこのリプリケーション要素の要請に合うまで、内部的な自動トピックの生成は失敗するでしょう。 | short | 3 | [1,...] | high | read-only |
transaction.state.log.segment.bytes | ログの圧縮とキャッシュのロードを速くし易いように、トランザクション トピックのセグメントのバイトは比較的小さくすべきです。 | int | 104857600 | [1,...] | high | read-only |
transactional.id.expiration.ms | トランザクションのコーディネーターがトランザクションの状態の更新を受け取ることなく積極的にプロデューサのトランザクションidを待つms単位での最大総時間。 | int | 604800000 | [1,...] | high | read-only |
unclean.leader.election.enable | データの喪失に繋がるとしても、最後の手段としてリーダーとして選出されるように設定されたISRに無いレプリカを有効にするかどうかを示す。 | boolean | false | high | cluster-wide | |
zookeeper.connection.timeout.ms | クライアントがzookeeperに接続を確立するまで待つ最大時間。設定しない場合は、zookeeper.session.timeout.ms の値が使われます | int | null | high | read-only | |
zookeeper.max.in.flight.requests | クライアントがブロックの前にZookeeperに送信するだろう返事の無いリクエストの最大数。 | int | 10 | [1,...] | high | read-only |
zookeeper.session.timeout.ms | Zookeeper セッション タイムアウト | int | 6000 | high | read-only | |
zookeeper.set.acl | クライアントにsecure ACLを使うように設定します | boolean | false | high | read-only | |
broker.id.generation.enable | サーバ上で自動ブローカーid生成を有効にする有効にされた場合、reserved.broker.max.id に設定された値は再調査されるべきです。 | boolean | true | medium | read-only | |
broker.rack | ブローカーのラック。これはラックを気にするリプリケーションアサインメントで耐障害性のために使われます。例: `RACK1`, `us-east-1d` | 文字列 | null | medium | read-only | |
connections.max.idle.ms | アイドル接続タイムアウト: サーバソケットプロセッサ スレッドはこれより多いアイドルの接続を閉じます | long | 600000 | medium | read-only | |
controlled.shutdown.enable | サーバの制御されたシャットダウンを有効にする | boolean | true | medium | read-only | |
controlled.shutdown.max.retries | 制御されたシャットダウンは複数の理由で失敗するかも知れません。これはそのような障害が起きた時の再試行の数を決定します | int | 3 | medium | read-only | |
controlled.shutdown.retry.backoff.ms | 各再試行の前に、システムは以前の障害(コントローラのフェイルオーバー、ログのリプリカ)を起こす状態から回復するための時間が必要です。この設定は再試行の前に待つ総時間を決定します。 | long | 5000 | medium | read-only | |
controller.socket.timeout.ms | コントローラ-ブローカー チャンネルのためのソケットタイムアウト | int | 30000 | medium | read-only | |
default.replication.factor | 自動的に生成されたトピックのためのデフォルトのリプリケーション要素 | int | 1 | medium | read-only | |
delegation.token.expiry.time.ms | トークンが新しくされる必要があるまでのトークンの有効時間の秒数。デフォルトの値は1日です。 | long | 86400000 | [1,...] | medium | read-only |
delegation.token.master.key | 移譲トークンを生成および検証するためのマスター/秘密キー。全てのブローカーに渡って同じキーが設定されなければなりません。もしキーが設定されていないか空の文字列に設定される場合、ブローカーは移譲トークンのサポートを無効にするでしょう。 | password | null | medium | read-only | |
delegation.token.max.lifetime.ms | トークンがもう新しくされることが無いような最大の生存期間を持ちます。デフォルトの値は7日です。 | long | 604800000 | [1,...] | medium | read-only |
delete.records.purgatory.purge.interval.requests | レコード削除のリクエストのパージの間隔(リクエストの数) | int | 1 | medium | read-only | |
fetch.purgatory.purge.interval.requests | 取得リクエストのパージ間隔(リクエストの数) | int | 1000 | medium | read-only | |
group.initial.rebalance.delay.ms | グループコーディネーターが最初のリバランスを実施する前にもっと多くのコンシューマが新しいグループに入るのを待つ総時間。より大きな遅延は潜在的にリバランスが少ないことを意味しますが、処理が始まるまでの時間が増加します。 | int | 3000 | medium | read-only | |
group.max.session.timeout.ms | 登録されたカスタマのための最大許可セッションタイムアウト。タイムアウトを長くすることでコンシューマは障害の検知までの長い時間を代償にハートビート間のメッセージの処理時間を長くします。 | int | 300000 | medium | read-only | |
group.min.session.timeout.ms | 登録されたカスタマのための最小許可セッションタイムアウト。タイムアウトを短くするとコンシューマーのハートビートの高頻度という代償を払って障害の検知が速くなります。これはブローカーのリソースを圧倒するかもしれません。 | int | 6000 | medium | read-only | |
inter.broker.listener.name | ブローカー間の通信に使われるリスナー名。これが設定されない場合、リスナー名は security.inter.broker.protocol によって定義されます。これを設定して同時に security.inter.broker.protocol プロパティを設定するのは間違いです。 | 文字列 | null | medium | read-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-IV1 | medium | read-only | |
log.cleaner.backoff.ms | 掃除するログが無い場合にスリープする総時間 | long | 15000 | [0,...] | medium | cluster-wide |
log.cleaner.dedupe.buffer.size | 全てのクリーナースレッドを通じてログのデュプリケーションに使われる総メモリ | long | 134217728 | medium | cluster-wide | |
log.cleaner.delete.retention.ms | どれだけの期間削除されたレコードを保持するか? | long | 86400000 | medium | cluster-wide | |
log.cleaner.enable | ログクリーナープロセスをサーバ上で実行することを有効にする。内部オフセットトピックを含む cleanup.policy=compact を使ってトピックを使う場合は有効にしなければなりません。無効にするとそれらのトピックはコンパクト化されずサイズが増加し続けるでしょう。 | boolean | true | medium | read-only | |
log.cleaner.io.buffer.load.factor | Log cleaner dedupe buffer load factor. The percentage full the dedupe buffer can become. 値を高くすると一度にもっと多くのログを掃除することができますが、もっと多くのハッシュの衝突に繋がるでしょう。 | double | 0.9 | medium | cluster-wide | |
log.cleaner.io.buffer.size | 全てのクリーナースレッドを通じてログ クリーナーのI/Oバッファに使われる総メモリ | int | 524288 | [0,...] | medium | cluster-wide |
log.cleaner.io.max.bytes.per.second | ログのクリーナーは読み込みおよび書き込みi/oがこの値より平均で小さくなるように絞るでしょう。 | double | 1.7976931348623157E308 | medium | cluster-wide | |
log.cleaner.min.cleanable.ratio | ログが掃除されるようになる総ログに対するダーティログの最小割合 | double | 0.5 | medium | cluster-wide | |
log.cleaner.min.compaction.lag.ms | メッセージがログ内で圧縮されずにいる最小時間。圧縮されているログについてのみ適用可能です。 | long | 0 | medium | cluster-wide | |
log.cleaner.threads | ログの掃除に使われるバックグラウンドスレッドの数 | int | 1 | [0,...] | medium | cluster-wide |
log.cleanup.policy | 保持ウィンドウを超えたセグメントのデフォルトの掃除ポリシー有効なポリシーのカンマ区切りのリスト。有効なポリシーは : "delete" および "compact" | list | delete | [compact, delete] | medium | cluster-wide |
log.index.interval.bytes | オフセット インデックスにエントリを追加する間隔 | int | 4096 | [0,...] | medium | cluster-wide |
log.index.size.max.bytes | オフセット インデックスの最大バイト数 | int | 10485760 | [4,...] | medium | cluster-wide |
log.message.format.version | ブローカーがログにメッセージを追加する時に使うメッセージフォーマットを指定します。値は有効なApiVersionでなければなりません。いくつかの例: 0.8.2, 0.9.0.0, 0.10.0, 詳細はApiVersionを調べてください。特定のメッセージフォーマットバージョンを指定することで、ユーザはディスク上の既存の全てのメッセージが指定のバージョン以下であることを保証します。この値を間違って設定すると、古いバージョンのコンシューマが理解できないフォーマットを使ってメッセージを受信するため、それらは壊してしまうでしょう。 | 文字列 | 2.0-IV1 | medium | read-only | |
log.message.timestamp.difference.max.ms | ブローカーがメッセージを付け取った時のタイムスタンプと、その中で指定されたタイムスタンプとの間で許される最大の差異。log.message.timestamp.type=CreateTime であれば、タイムスタンプの違いがこの閾値を超えた場合にメッセージは却下されるでしょう。もし log.message.timestamp.type=LogAppendTime であればこの設定は無視されます。不必要な頻度のログのローリングを避けるために、許される最大のタイムスタンプの差異は log.retention.ms より小さくなければなりません。 | long | 9223372036854775807 | medium | cluster-wide | |
log.message.timestamp.type | メッセージ内のタイムスタンプが、メッセージが生成された時間か、ログが追加された時間かどうかを定義します。値は `CreateTime` あるいは `LogAppendTime` のどちらかでなければなりません。 | 文字列 | CreateTime | [CreateTime, LogAppendTime] | medium | cluster-wide |
log.preallocate | 新しいセグメントを作る場合にあらかじめファイルを割り当てるべきか?Windows上でKafkaを使う場合は、たぶんtrueに設定する必要があります。 | boolean | false | medium | cluster-wide | |
log.retention.check.interval.ms | ログクリーナーがいずれかのログが削除される対象かどうかをチェックする頻度のミリ秒 | long | 300000 | [1,...] | medium | read-only |
max.connections.per.ip | 各ipアドレスから接続可能な最大数。max.connections.per.ip.overrides プロパティを使って設定された上書きがある場合、これは0に設定することができます | int | 2147483647 | [0,...] | medium | read-only |
max.connections.per.ip.overrides | 接続のデフォルトの最大数を上書きする ip またはホスト名ごとのカンマ区切りのリスト。値の例は "hostName:100,127.0.0.1:200" です | 文字列 | "" | medium | read-only | |
max.incremental.fetch.session.cache.slots | 私たちが維持するだろう逐次取得セッションの最大数。 | int | 1000 | [0,...] | medium | read-only |
num.partitions | トピック毎のログパーティションのデフォルトの数 | int | 1 | [1,...] | medium | read-only |
password.encoder.old.secret | 設定されたパスワードを動的に符号化するために使われた古いsecret。これはsecretが更新される時にのみ必要です。もし指定された場合、全ての動的に符号化されたパスワードはこの古いsecretを使って使って複合化され、ブローカーが起動する時に password.encoder.secret を使って再符号化されます。 | password | null | medium | read-only | |
password.encoder.secret | このブローカーについて設定されたパスワードを動的に符号化するために使われるsecret。 | password | null | medium | read-only | |
principal.builder.class | KafkaPrincipalBuilder インタフェースを実装するクラスの完全修飾名。これは認証の間に使われる KafkaPrincipal オブジェクトを構築するために使われます。この設定は以前にSSL上でクライアントの認証のために使われていた非推奨のPrincipalBuilderインタフェースもサポートします。principal ビルダーが定義されない場合、デフォルトの挙動は使用するセキュリティ プロトコルに依存します。SSL認証については、principal名が提供されない場合はクライアントの証明書から識別された名前が使われるでしょう; そうでなければ、クライアント認証が必要では無い場合、principal名はANONYMOUSになるでしょう。SASL 認証については、principalはGSSAPIが使われている場合はsasl.kerberos.principal.to.local.rules で定義されるルールを使って取り出され、他の機構についてはSASL認証IDが使われるでしょう。PLAINTEXT については、principalは ANONYMOUS になるでしょう。 | クラス | null | medium | per-broker | |
producer.purgatory.purge.interval.requests | プロデューサのリクエストのパージ間隔(リクエストの数) | int | 1000 | medium | read-only | |
queued.max.request.bytes | リクエストがもう読まれなくなるまでに許可されるキューのバイト数 | long | -1 | medium | read-only | |
replica.fetch.backoff.ms | 取得パーティションエラーが起きた時の総sleep時間。 | int | 1000 | [0,...] | medium | read-only |
replica.fetch.max.bytes | 各パーティションについてフェッチしようとするメッセージのバイト数。これは絶対的な最大ではありません。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、進めることができるようにレコードのバッチはまだ返されるでしょう。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。 | int | 1048576 | [0,...] | medium | read-only |
replica.fetch.response.max.bytes | フェッチ応答全体に期待される最大バイト。レコードはバッチ内で取得されます。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、進めることができるようにレコードのバッチはまだ返されるでしょう。このように、これは絶対的な最大ではありません。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。 | int | 10485760 | [0,...] | medium | read-only |
reserved.broker.max.id | broker.idのために使うことができる最大の数 | int | 1000 | [0,...] | medium | read-only |
sasl.client.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。 | クラス | null | medium | read-only | |
sasl.enabled.mechanisms | Kafkaサーバ内で利用可能なSASL機構のリスト。リストにはセキュリティプロバイダが利用可能な任意の機構が含まれるかも知れません。デフォルトではGSSAPIだけが有効です。 | list | GSSAPI | medium | per-broker | |
sasl.jaas.config | JAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*; '。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です; | password | null | medium | per-broker | |
sasl.kerberos.kinit.cmd | Kerberos kinit コマンドライン パス。 | 文字列 | /usr/bin/kinit | medium | per-broker | |
sasl.kerberos.min.time.before.relogin | リフレッシュ試行間のログインスレッドのスリープ時間。 | long | 60000 | medium | per-broker | |
sasl.kerberos.principal.to.local.rules | プリンシパル名からショート名(一般的にオペレーティングシステムのユーザ名)へのマッピングのルールのリスト。ルールは順番に評価され、プリンシパル名に合致する最初のルールがショート名にマップするために使われます。リスト内の後のどのようなルールも無視されます。デフォルトでは、{username}/{hostname}@{REALM} の形式のプリンシパル名は {username} にマップされます。形式についての詳細は、 セキュリティ認証とaclを見てください。KafkaPrincipalBuilderの拡張がprincipal.builder.class 設定によって提供されない場合、この設定は無視されることに注意してください。 | list | デフォルト: | medium | per-broker | |
sasl.kerberos.service.name | Kafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。 | 文字列 | null | medium | per-broker | |
sasl.kerberos.ticket.renew.jitter | 更新時間に追加されるランダムなジッターのパーセンテージ。 | double | 0.05 | medium | per-broker | |
sasl.kerberos.ticket.renew.window.factor | 最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。 | double | 0.8 | medium | per-broker | |
sasl.login.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandler | クラス | null | medium | read-only | |
sasl.login.class | Loginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLogin | クラス | null | medium | read-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 にのみ適用されます。 | short | 300 | medium | per-broker | |
sasl.login.refresh.min.period.seconds | 証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。 | short | 60 | medium | per-broker | |
sasl.login.refresh.window.factor | ログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.8 | medium | per-broker | |
sasl.login.refresh.window.jitter | ログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.05 | medium | per-broker | |
sasl.mechanism.inter.broker.protocol | 内部ブローカー通信に使われるSASL機構。デフォルトは GSSAPI です。 | 文字列 | GSSAPI | medium | per-broker | |
sasl.server.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL サーバ コールバック ハンドラ クラスの完全修飾名。サーバのコールバックハンドラはlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.plain.sasl.server.callback.handler.class=com.example.CustomPlainCallbackHandler。 | クラス | null | medium | read-only | |
security.inter.broker.protocol | ブローカー間で通信するために使われるセキュリティプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。これを設定して同時に inter.broker.listener.name プロパティを設定するのは間違いです。 | 文字列 | PLAINTEXT | medium | read-only | |
ssl.cipher.suites | cipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。 | list | "" | medium | per-broker | |
ssl.client.auth | クライアント認証をリクエストするためのKafkaブローカーを設定します。以下の設定が一般的です:
| 文字列 | none | [required, requested, none] | medium | per-broker |
ssl.enabled.protocols | SSL接続のために有効にされるプロトコルのリスト。 | list | TLSv1.2,TLSv1.1,TLSv1 | medium | per-broker | |
ssl.key.password | キーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。 | password | null | medium | per-broker | |
ssl.keymanager.algorithm | SSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。 | 文字列 | SunX509 | medium | per-broker | |
ssl.keystore.location | キーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。 | 文字列 | null | medium | per-broker | |
ssl.keystore.password | キーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 | password | null | medium | per-broker | |
ssl.keystore.type | キーストアファイルのファイル形式。これはクライアントについては任意です。 | 文字列 | JKS | medium | per-broker | |
ssl.protocol | SSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。 | 文字列 | TLS | medium | per-broker | |
ssl.provider | SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。 | 文字列 | null | medium | per-broker | |
ssl.trustmanager.algorithm | SSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。 | 文字列 | PKIX | medium | per-broker | |
ssl.truststore.location | トラストストアーファイルの場所。 | 文字列 | null | medium | per-broker | |
ssl.truststore.password | トラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。 | password | null | medium | per-broker | |
ssl.truststore.type | トラストストアファイルのファイル形式。 | 文字列 | JKS | medium | per-broker | |
alter.config.policy.class.name | 検証のために使われるべき代替の設定ポリシークラス。クラスはorg.apache.kafka.server.policy.AlterConfigPolicy インタフェースを実装しなければなりません。 | クラス | null | low | read-only | |
alter.log.dirs.replication.quota.window.num | 別のログディレクトリのリプリケーションのクォートのためのメモリ内に保持する標本の数 | int | 11 | [1,...] | low | read-only |
alter.log.dirs.replication.quota.window.size.seconds | 別のログディレクトリのリプリケーションのクォートのための各標本内の時間間隔 | int | 1 | [1,...] | low | read-only |
authorizer.class.name | 認証のために使われるべき認証クラス | 文字列 | "" | low | read-only | |
client.quota.callback.class | ClientQuotaCallback インタフェースを実装するクラスの完全修飾名。これはクライアントのリクエストに適用されるクォータ制限を決定するために使われます。デフォルトでは、 | クラス | null | low | read-only | |
create.topic.policy.class.name | 検証に使われる必要がある トピック生成ポリシークラス。クラスは org.apache.kafka.server.policy.CreateTopicPolicy インタフェースを実装しなければなりません。 | クラス | null | low | read-only | |
delegation.token.expiry.check.interval.ms | 期限切れの移譲トークンを削除するための走査間隔。 | long | 3600000 | [1,...] | low | read-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_SSL | low | per-broker | |
log.message.downconversion.enable | この設定はコンシューマのリクエストを満たすためにメッセージ形式のダウン-コンバージョンが有効にされるかどうかを制御します。false に設定された場合、ブローカーは古いメッセージ形式を期待するコンシューマのためのダウン-コンバージョンを行わないでしょう。そのような古いクライアントからのコンシューマリクエストについては、ブローカーはUNSUPPORTED_VERSION エラーで応答します。この設定はフォロワーへのレプリケーションに必要とされるかもしれないメッセージ形式の変換に適用されません。 | boolean | true | low | cluster-wide | |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | low | cluster-wide | |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low | read-only |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | low | read-only | |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [1,...] | low | read-only |
password.encoder.cipher.algorithm | 設定されたパスワードを動的に符号化するために使われたCipherアルゴリズム。 | 文字列 | AES/CBC/PKCS5Padding | low | read-only | |
password.encoder.iterations | 設定されたパスワードを動的に符号化するために使われた繰り返しカウント。 | int | 4096 | [1024,...] | low | read-only |
password.encoder.key.length | 設定されたパスワードを動的に符号化するために使われたキーの長さ。 | int | 128 | [8,...] | low | read-only |
password.encoder.keyfactory.algorithm | 設定されたパスワードを動的に符号化するために使われたSecretKeyFactoryアルゴリズム。デフォルトは利用可能であれば PBKDF2WithHmacSHA512、そうでなければ PBKDF2WithHmacSHA1。 | 文字列 | null | low | read-only | |
quota.window.num | クライアントのクォートのためのメモリ内に保持する標本の数 | int | 11 | [1,...] | low | read-only |
quota.window.size.seconds | クライアントのクォートのための各標本内の時間間隔 | int | 1 | [1,...] | low | read-only |
replication.quota.window.num | リプリケーションのクォートのためのメモリ内に保持する標本の数 | int | 11 | [1,...] | low | read-only |
replication.quota.window.size.seconds | リプリケーションのクォートのための各標本内の時間間隔 | int | 1 | [1,...] | low | read-only |
ssl.endpoint.identification.algorithm | サーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 | 文字列 | https | low | per-broker | |
ssl.secure.random.implementation | SSL暗号化操作のために使われる SecureRandom PRNG 実装。 | 文字列 | null | low | per-broker | |
transaction.abort.timed.out.transaction.cleanup.interval.ms | タイムアウトしたトランザクションをロールバックする間隔 | int | 60000 | [1,...] | low | read-only |
transaction.remove.expired.transaction.cleanup.interval.ms | transactional.id.expiration.ms | int | 3600000 | [1,...] | low | read-only |
zookeeper.sync.time.ms | ZKリーダーからどれだけZKフォロワーが遅れることができるか | int | 2000 | low | read-only |
ブローカー設定についての詳細はscalaクラスkafka.server.KafkaConfig
の中で見つけることができます。
3.1.1ブローカー設定の更新
Kafka バージョン 1.1 から、ブローカーの設定の幾つかがブローカーの再起動無しに更新することができます。各ブローカーの設定の更新モードについては、ブローカー設定の動的更新モード
のカラムを見てください。
read-only
: 更新のためにブローカーの再起動を必要としますper-broker
: 各ブローカーについて動的に更新することができますcluster-wide
: クラスタ全体のデフォルトとして動的に更新することができます。テストのためにブローカー毎の値として更新することもできます。
> 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のSSL トラストストアの更新
ブローカーのトラストストアは証明書の追加あるいは削除のためのブローカーの再起動無しに動的に更新することができます。更新されたトラストストアは新しいクライアント接続を認証するために使われるでしょう。設定名は特定のlistenerのトラストストア設定だけが更新されるようにlistenerのプリフィックスlistener.name.{listenerName}.
を使って前置されなければなりません。以下の設定はブローカー毎のレベルで1つの更新リクエストの中で更新されるかもしれません:
ssl.truststore.type
ssl.truststore.location
ssl.truststore.password
デフォルトのトピックの設定の更新
ブローカーによって使われるデフォルトのトピックの設定オプションはブローカーの再起動無しに更新されるかもしれません。設定はトピック毎の設定と同等のトピックの設定の上書き無しに適用されます。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
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
を更新するためにローリング再起動が必要とされます。
リスナー
advertised.listeners
listener.security.protocol.map
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 のコンパクション を有効にするでしょう。 | list | delete | [compact, delete] | log.cleanup.policy | medium |
compression.type | 指定されたトピックのための最終的な圧縮タイプを指定する。この設定は標準的な圧縮コーディック('gzip', 'snappy', 'lz4')を受け付けます。更に、非圧縮に相当する 'uncompressed'; プロデューサによって設定された元の圧縮コーディックを保持することを意味する'producer' を受け付けます。 | 文字列 | producer | [uncompressed, snappy, lz4, gzip, producer] | compression.type | medium |
delete.retention.ms | log compacted トピックのための削除の墓石の目印を維持するための総時間。もし最終のステージの有効なスナップショットを取得するためにオフセット0から始める場合は、この設定はコンシューマが読み込みを完了させる時間の境界も与えます (そうでなければ、削除の墓石はそれらが走査を完了する前に集められるかもしれません)。 | long | 86400000 | [0,...] | log.cleaner.delete.retention.ms | medium |
file.delete.delay.ms | ファイルシステムからファイルを削除するまでの待ち時間 | long | 60000 | [0,...] | log.segment.delete.delay.ms | medium |
flush.messages | この設定はログに書かれるデータのfsyncを強制する間隔を指定することができます。例えば、もしこれが1に設定された場合、各メッセージの後にfsyncされるでしょう; もし5であれば各5メッセージ毎にfsyncするでしょう。一般的には、これを使わずに、耐久性のためにリプリケーションを使い、オペレーティングシステムのバックグラウンドフラッシュ機能のほうがもっと効率的なためそれにさせることをお勧めします。この設定はトピック毎ベースで上書きすることができます(トピック毎の設定の章を見てください)。 | long | 9223372036854775807 | [0,...] | log.flush.interval.messages | medium |
flush.ms | この設定はログに書かれるデータのfsyncを強制する時間を指定することができます。例えば、これが1000に設定された場合、1000ms過ぎた後でfsyncするでしょう。一般的には、これを使わずに、耐久性のためにリプリケーションを使い、オペレーティングシステムのバックグラウンドフラッシュ機能のほうがもっと効率的なためそれにさせることをお勧めします。 | long | 9223372036854775807 | [0,...] | log.flush.interval.ms | medium |
follower.replication.throttled.replicas | ログのリプリケーションがフォロワー側で絞られなければならないレプリカのリスト。リストは [PartitionId]:[BrokerId],[PartitionId]:[BrokerId]:... の形式のレプリカのセットを表さなければなりません。あるいはこのトピックについての全てのレプリカを絞るためにワイルドカード '*' を使うことができます。 | list | "" | [partitionId],[brokerId]:[partitionId],[brokerId]:... | follower.replication.throttled.replicas | medium |
index.interval.bytes | この設定はKafkaがオフセットインデックスにエントリを追加する頻度を制御します。デフォルトの設定はおおよそ各4096バイトごとにメッセージをインデックスすることを保証します。もっとインデックスを増やすことでログの正確な場所の近くに読み込みをジャンプすることができますが、インデックスが大きくなります。おそらくこれを変更する必要はないでしょう。 | int | 4096 | [0,...] | log.index.interval.bytes | medium |
leader.replication.throttled.replicas | ログのリプリケーションがリーダー側で絞られなければならないレプリカのリスト。リストは [PartitionId]:[BrokerId],[PartitionId]:[BrokerId]:... の形式のレプリカのセットを表さなければなりません。あるいはこのトピックについての全てのレプリカを絞るためにワイルドカード '*' を使うことができます。 | list | "" | [partitionId],[brokerId]:[partitionId],[brokerId]:... | leader.replication.throttled.replicas | medium |
max.message.bytes | Kafkaで可能な最も大きなレコードのバッチサイズ。これが増え、0.10.2より古いコンシューマがある場合、コンシューマがこの大きさのレコードバッチを取得できるようにコンシューマの取得サイズも増やす必要があります。 最新のメッセージフォーマットのバージョンでは、効率化のためにレコードは常にバッチにグループ化されます。以前のメッセージフォーマットのバージョンでは、圧縮されていないレコードはバッチにグループ化されず、この制限は1つのレコードにのみ適用されます。 | int | 1000012 | [0,...] | message.max.bytes | medium |
message.format.version | ブローカーがログにメッセージを追加する時に使うメッセージフォーマットを指定します。値は有効なApiVersionでなければなりません。いくつかの例: 0.8.2, 0.9.0.0, 0.10.0, 詳細はApiVersionを調べてください。特定のメッセージフォーマットバージョンを指定することで、ユーザはディスク上の既存の全てのメッセージが指定のバージョン以下であることを保証します。この値を間違って設定すると、古いバージョンのコンシューマが理解できないフォーマットを使ってメッセージを受信するため、それらは壊してしまうでしょう。 | 文字列 | 2.0-IV1 | log.message.format.version | medium | |
message.timestamp.difference.max.ms | ブローカーがメッセージを付け取った時のタイムスタンプと、その中で指定されたタイムスタンプとの間で許される最大の差異。message.timestamp.type=CreateTime であれば、タイムスタンプの違いがこの閾値を超えた場合にメッセージは却下されるでしょう。もし message.timestamp.type=LogAppendTime であれば、この設定は無視されます。 | long | 9223372036854775807 | [0,...] | log.message.timestamp.difference.max.ms | medium |
message.timestamp.type | メッセージ内のタイムスタンプが、メッセージが生成された時間か、ログが追加された時間かどうかを定義します。値は `CreateTime` あるいは `LogAppendTime` のどちらかでなければなりません。 | 文字列 | CreateTime | [CreateTime, LogAppendTime] | log.message.timestamp.type | medium |
min.cleanable.dirty.ratio | この設定はログの圧縮機がログを掃除しようとする頻度を制御します(log compaction が有効であると仮定)。デフォルトでは、ログの50%以上がコンパクト化された場所にあるログを掃除することを避けるでしょう。この率はデュープリケートによってログ内で消費される領域の最大を制限します(50%ではログの最大50%がデュープリケートされるかも知れません)。率を高くすることは、より少なく、より効率的な掃除を意味しますが、ログ内のより多くの消費される領域を意味するでしょう。 | double | 0.5 | [0,...,1] | log.cleaner.min.cleanable.ratio | medium |
min.compaction.lag.ms | メッセージがログ内で圧縮されずにいる最小時間。圧縮されているログについてのみ適用可能です。 | long | 0 | [0,...] | log.cleaner.min.compaction.lag.ms | medium |
min.insync.replicas | プロデューサがackを "all" (あるいは "-1") に設定する場合、この設定は書き込みが成功したと見なされるように書き込みを知らせる必要があるレプリカの最小数を指定します。この最小限に一致しない場合、プロデューサは例外(NotEnoughReplicas あるいは NotEnoughReplicasAfterAppendのどちらか)を上げるでしょう。 一緒に使った場合、min.insync.replicas と acks は素晴らしい耐久性の保証を強化することができます。典型的なシナリオは、3つのレプリケーション ファクターを持つトピックを生成し、min.insync.replicas を 2 に設定し、"all" のackを使って生成します。これは、もしレプリカの過半数が書き込みを受け取らなかった場合にプロデューサが例外を上げることを保証するでしょう。 | int | 1 | [1,...] | min.insync.replicas | medium |
preallocate | 新しいログのセグメントを生成する時にディスク上にファイルをあらかじめ割り当てる必要がある場合はTrue。 | boolean | false | log.preallocate | medium | |
retention.bytes | この設定は、"delete" 維持ポリシーを使う場合は空間を解放するために古いログのセグメントを削除する前までのパーティション(ログのセグメントからなります)が成長する最大のサイズを制御します。デフォルトでは時間の制限だけでサイズの制限はありません。この制限はパーティションレベルで強制されるため、トピックの維持をバイトで計算するにはそれにパーティションの数を掛けてください。 | long | -1 | log.retention.bytes | medium | |
retention.ms | この設定は、"delete" 維持ポリシーを使う場合は空間を解放するために古いログのセグメントを削除する前にログを保持するだろう最大の時間を制御します。これはコンシューマがデータをどれだけ早く読まなければならないかのSLAを表します。-1に設定される場合、時間の制限無しが適用されます。 | long | 604800000 | log.retention.ms | medium | |
segment.bytes | この設定はログのためのセグメントファイルサイズを制御します。維持と掃除は常にファイルに一度に行われます。つまり、大きなセグメントサイズは少ないファイルを意味しますが、維持の制御の粒度が小さくなります。 | int | 1073741824 | [14,...] | log.segment.bytes | medium |
segment.index.bytes | この設定はオフセットをファイルの場所にマップするインデックスのサイズを制御します。このインデックスファイルはあらかじめ割り当てられていて、ログがロールした後でのみ縮小されます。通常この設定を変更する必要はありません。 | int | 10485760 | [0,...] | log.index.size.max.bytes | medium |
segment.jitter.ms | 立て続けのセグメントのローリングを避けるためにスケジュールされたセグメントロール時間から引かれるランダムなズレの最大 | long | 0 | [0,...] | log.roll.jitter.ms | medium |
segment.ms | この設定は、保持の仕組みが古いデータを削除あるいは圧縮できるように、セグメントファイルが一杯では無い場合でもKafkaがログをロールするまでの時間を制御します。 | long | 604800000 | [1,...] | log.roll.ms | medium |
unclean.leader.election.enable | データの喪失に繋がるとしても、最後の手段としてリーダーとして選出されるように設定されたISRに無いレプリカを有効にするかどうかを示す。 | boolean | false | unclean.leader.election.enable | medium | |
message.downconversion.enable | この設定はコンシューマのリクエストを満たすためにメッセージ形式のダウン-コンバージョンが有効にされるかどうかを制御します。false に設定された場合、ブローカーは古いメッセージ形式を期待するコンシューマのためのダウン-コンバージョンを行わないでしょう。そのような古いクライアントからのコンシューマリクエストについては、ブローカーはUNSUPPORTED_VERSION エラーで応答します。この設定はフォロワーへのレプリケーションに必要とされるかもしれないメッセージ形式の変換に適用されません。 | boolean | true | log.message.downconversion.enable | low |
3.3プロデューサの設定
以下はJavaプロデューサの設定です:名前 | 説明 | 種類 | デフォルト | 有効な値 | 重要性 |
---|---|---|---|---|---|
key.serializer | org.apache.kafka.common.serialization.Serializer インタフェースを実装するキーのためのシリアライザ クラス。 | クラス | high | ||
value.serializer | org.apache.kafka.common.serialization.Serializer インタフェースを実装する値のためのシリアライザ クラス。 | クラス | high | ||
acks | リクエストが完了したと見なす前にリーダーが受け取ることをプロデューサが要求する通知の数。これは送信されたレコードの持続性を制御します。以下の設定が可能です:
| 文字列 | 1 | [all, -1, 0, 1] | high |
bootstrap.servers | Kafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,... の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@7cd62f43 | high |
buffer.memory | プロデューサがサーバに送られるのを待っているレコードをバッファするために使うことができるメモリの総バイト数。サーバに配送することができるより早くレコードが送信された場合、プロデューサは例外を投げた後で max.block.ms の間ブロックするでしょう。この設定は大まかにプロデューサが利用しようとする総メモリに対応しますが、プロデューサが使用する全てのメモリがバッファリングに使われるわけではないためハードバウンドではありません。いくつかの追加のメモリが圧縮(圧縮が有効な場合)と、やってきているリクエストを保持するために使われるでしょう。 | long | 33554432 | [0,...] | high |
compression.type | プロデューサによって生成された全てのデータのための圧縮タイプ。デフォルトは none (つまり、非圧縮)。有効な値は、none , gzip , snappy あるいは lz4 です。圧縮はデータの完全なバッチです。つまりバッチの効果は圧縮率にも影響するでしょう (多くのバッチ化はより良い圧縮を意味します)。 | 文字列 | none | high | |
retries | 0より大きい値を設定すると、クライアントは一時的なエラーによる障害による送信の全てのレコードを再送信するでしょう。この再試行はクライアントがエラーを受け取る時にレコードを再送するのと変わらないことに注意してください。max.in.flight.requests.per.connection を1に設定せずに再試行を許すと、もし2つのバッチが1つのパーティションに送信され、最初が失敗して2つ目が成功したが再試行し、2つ目のバッチのレコードが最初に現れるかもしれないため、レコードの順番が変わるかもしれません。 | int | 0 | [0,...,2147483647] | high |
ssl.key.password | キーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。 | password | null | high | |
ssl.keystore.location | キーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。 | 文字列 | null | high | |
ssl.keystore.password | キーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 | password | null | high | |
ssl.truststore.location | トラストストアーファイルの場所。 | 文字列 | null | high | |
ssl.truststore.password | トラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。 | password | null | high | |
batch.size | 多数のレコードが同じパーティションに送信される時はいつもプロデューサはバッチのレコードをより少ないリクエストにまとめようとするでしょう。これはクライアントとサーバの両方でパフォーマンスを助けます。この設定はデフォルトのバッチサイズをバイトで制御します。 このサイズより大きいバッチレコードには何も試行されないでしょう。 ブローカーに送信されるリクエストは複数のバッチを含むでしょう。各パーティションについて1つの送信することが可能なデータを持つバッチです。 小さなバッチサイズはバッチ化を一般的でなくし、スループットを下げるかもしれません(バッチサイズ 0はバッチ化を完全に無効にするでしょう)。大きなバッチサイズは追加のレコードに備えて指定されたバッチサイズのバッチを常に割り当てるため、メモリを幾分贅沢に使うかもしれません。 | int | 16384 | [0,...] | medium |
client.id | リクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。 | 文字列 | "" | medium | |
connections.max.idle.ms | この設定によって指定されるミリ秒後にアイドルの接続を閉じます。 | long | 540000 | medium | |
linger.ms | プロデューサグループはリクエストの転送間に到着した全てのレコードを1つのバッチリクエストにまとめます。通常、これはレコードが送信できるように早く到着した時に負荷を受けてのみ起こります。しかし、ある状況では、クライアントは控えめな負荷の場合でもリクエストの数を減らしたいと思うかも知れません。この設定は少しの人為的な遅延によってこれを成し遂げます - つまり、すぐにレコードを送信するのではなく、プロデューサは一緒にバッチ化されることができるように他のレコードが送信されるように指定された遅延まで待つでしょう。これはTCPでのNagleアルゴリズムへの相似として考えることができます。この設定ではバッチ処理の遅延の上限が与えられます: パーティションについて一旦batch.size 分のレコードを取得すると、それはこの設定に関係なく即座に送信されるでしょう。しかしもしこのパーティションについて集約されたバイトがこれより少ない場合、より多くのレコードが現れるまで指定された時間だけ'残る'でしょう。この設定のデフォルトは 0 です (つまり、遅延はありません)。例えば、linger.ms=5 に設定すると、送信されるリクエストの数を減らす効果がありますが、負荷が無い時にレコードの送信に5msのレイテンシを追加するでしょう。 | long | 0 | [0,...] | medium |
max.block.ms | 設定はどれだけ長くKafkaProducer.send() とKafkaProducer.partitionsFor() がブロックするかを制御します。これらのメソッドはバッファがいっぱいあるいはメタデータを利用できないことのどちらかでブロックされるかもしれません。ユーザが指定したシリアライザあるいはパーティショナーの中でのブロックはこのタイムアウトに対してカウントされないでしょう。 | long | 60000 | [0,...] | medium |
max.request.size | リクエストの最大バイトサイズ。この設定は大きなリクエストを送信することを避けるためにプロデューサが1つのリクエスト内で送信するレコードのバッチの数を制限するでしょう。これは最大レコードバッチサイズの効果的なキャップでもあります。サーバはこれとは異なるかも知れないレコードバッチサイズ上の独自のキャップを持つことに注意してください。 | int | 1048576 | [0,...] | medium |
partitioner.class | org.apache.kafka.clients.producer.Partitioner インタフェースを実装するパーティショナークラス。 | クラス | org.apache.kafka.clients.producer.internals.DefaultPartitioner | medium | |
receive.buffer.bytes | データを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 32768 | [-1,...] | medium |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。不必要なプロデューサの再試行によるメッセージの重複の可能性を減らすために、これは replica.lag.time.max.ms (ブローカーの設定) より大きくなければなりません。 | int | 30000 | [0,...] | medium |
sasl.client.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。 | クラス | null | medium | |
sasl.jaas.config | JAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*; '。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です; | password | null | medium | |
sasl.kerberos.service.name | Kafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。 | 文字列 | null | medium | |
sasl.login.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandler | クラス | null | medium | |
sasl.login.class | Loginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLogin | クラス | null | medium | |
sasl.mechanism | クライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。 | 文字列 | GSSAPI | medium | |
security.protocol | ブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。 | 文字列 | PLAINTEXT | medium | |
send.buffer.bytes | データを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 131072 | [-1,...] | medium |
ssl.enabled.protocols | SSL接続のために有効にされるプロトコルのリスト。 | list | TLSv1.2,TLSv1.1,TLSv1 | medium | |
ssl.keystore.type | キーストアファイルのファイル形式。これはクライアントについては任意です。 | 文字列 | JKS | medium | |
ssl.protocol | SSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。 | 文字列 | TLS | medium | |
ssl.provider | SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。 | 文字列 | null | medium | |
ssl.truststore.type | トラストストアファイルのファイル形式。 | 文字列 | JKS | medium | |
enable.idempotence | 'true' に設定されると、プロデューサは各メッセージの確実に1回のコピーがストリームに書かれることを保証するでしょう。'false' の場合、プロデューサはブローカーの障害などによる再試行でストリーム内に再試行のメッセージの重複を書き込むかもしれません。等冪を有効にするには max.in.flight.requests.per.connection を5以下に設定する必要があり、retries は0より大きく、ackは 'all' でなければならないことに注意してください。これらの値がユーザによって明示的に設定されない場合、適切な値が選択されるでしょう。互換性の無い値が設定された場合、ConfigException が投げられるでしょう。 | boolean | false | low | |
interceptor.classes | インタセプタとして使われるクラスのリスト。org.apache.kafka.clients.producer.ProducerInterceptor インタフェースの実装により、Kafkaクラスタに発行される前にプロデューサによって受け取られるレコードを捉え(そしておそらく変化す)ることができます。デフォルトでは、インタセプタはありません。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@6d4b1c02 | low |
max.in.flight.requests.per.connection | クライアントがブロックされる前に1つの接続上で送信するだろう、返事の無いリクエストの最大数。この設定が1より大きく設定され、失敗した送信がある場合は、再試行(つまり、再試行が有効な場合)により、メッセージの再注文の可能性があります。 | int | 5 | [1,...] | low |
metadata.max.age.ms | パーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。 | long | 300000 | [0,...] | low |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@6093dd95 | low |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | [INFO, DEBUG] | low |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [0,...] | low |
reconnect.backoff.max.ms | 接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。 | long | 1000 | [0,...] | low |
reconnect.backoff.ms | 指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。 | long | 50 | [0,...] | low |
retry.backoff.ms | 指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。 | long | 100 | [0,...] | low |
sasl.kerberos.kinit.cmd | Kerberos kinit コマンドライン パス。 | 文字列 | /usr/bin/kinit | low | |
sasl.kerberos.min.time.before.relogin | リフレッシュ試行間のログインスレッドのスリープ時間。 | long | 60000 | low | |
sasl.kerberos.ticket.renew.jitter | 更新時間に追加されるランダムなジッターのパーセンテージ。 | double | 0.05 | low | |
sasl.kerberos.ticket.renew.window.factor | 最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。 | double | 0.8 | low | |
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 にのみ適用されます。 | short | 300 | [0,...,3600] | low |
sasl.login.refresh.min.period.seconds | 証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。 | short | 60 | [0,...,900] | low |
sasl.login.refresh.window.factor | ログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.8 | [0.5,...,1.0] | low |
sasl.login.refresh.window.jitter | ログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.05 | [0.0,...,0.25] | low |
ssl.cipher.suites | cipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。 | list | null | low | |
ssl.endpoint.identification.algorithm | サーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 | 文字列 | https | low | |
ssl.keymanager.algorithm | SSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。 | 文字列 | SunX509 | low | |
ssl.secure.random.implementation | SSL暗号化操作のために使われる SecureRandom PRNG 実装。 | 文字列 | null | low | |
ssl.trustmanager.algorithm | SSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。 | 文字列 | PKIX | low | |
transaction.timeout.ms | トランザクションのコーディネーターが実行中のトランザクションの破棄の前にプロデューサからのトランザクションの状態更新を待つ最大総時間。もしこの値がブローカー内の transaction.max.timeout.ms 設定よりも大きい場合は、リクエストは`InvalidTransactionTimeout` エラーで失敗するでしょう。 | int | 60000 | low | |
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.deserializer | org.apache.kafka.common.serialization.Deserializer インタフェースを実装するキーのためのDeserializerクラス。 | クラス | high | ||
value.deserializer | org.apache.kafka.common.serialization.Deserializer インタフェースを実装する値のためのDeserializerクラス。 | クラス | high | ||
bootstrap.servers | Kafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,... の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@6093dd95 | high |
fetch.min.bytes | サーバが各フェッチリクエストについて返さなければならないデータの最小量。十分なデータが利用可能では無い場合、リクエストはリクエストに返答する前に多くのデータを集めるのを待つでしょう。デフォルトの設定の1バイトは、データの1バイトが利用可能、あるいはデータの到着を待っているフェッチリクエストがタイムアウトするとすぐにフェッチリクエストに応答することを意味します。これを1より大きいものに設定すると、データの大部分をサーバが待つようになり、ある程度の追加のレイテンシを犠牲にして少しだけサーバのスループットを改善するでしょう。 | int | 1 | [0,...] | high |
group.id | このコンシューマが所属するコンシューマグループを識別するユニークな文字列。このプロパティは、もしコンシューマがsubscribe(topic) を使ってグループの管理機能、あるいはKafkaベースのオフセットの管理戦略を使う場合に必須です。 | 文字列 | "" | high | |
heartbeat.interval.ms | Kafkaのグループ管理機能を使う時に、コンシューマのコーディネータへのハートビート間に期待する時間。ハートビートはコンシューマのセッションが活動中であることを保証し、新しいコンシューマがグループに参加あるいは離れる時のリバランスを円滑にするために使われます。値はsession.timeout.ms より小さくなければなりませんが、一般的にはその値の1/3より大きく設定されなければなりません。通常の再バランスについては、期待する時間を制御するために少し小さく調整されるかも知れません。 | int | 3000 | high | |
max.partition.fetch.bytes | サーバが返すパーティションあたりのデータの最大総量。レコードはコンシューマによってバッチ内で取得されます。取得の最初の空では無いパーティション内の最初のレコードバッチはこの制限よりも大きく、コンシューマが進めることができるようにバッチはまだ返されるでしょう。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。コンシューマのリクエストサイズの制限については、fetch.max.bytes を見てください。 | int | 1048576 | [0,...] | high |
session.timeout.ms | Kafkaのグループ管理機能を使う時に、コンシューマの障害を検知するために使われるタイムアウト。コンシューマはその生存をブローカーに示すために定期的なハートビートを送信します。このセッションのタイムアウトが期限切れになる前にハートビートがブローカーによって受け取られない場合は、ブローカーはグループからこのコンシューマを削除しリバランスを初期化するでしょう。値は group.min.session.timeout.ms とgroup.max.session.timeout.ms によって設定されるブローカーの設定内で設定される可能な範囲内でなければならないことに注意してください。 | int | 10000 | high | |
ssl.key.password | キーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。 | password | null | high | |
ssl.keystore.location | キーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。 | 文字列 | null | high | |
ssl.keystore.password | キーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 | password | null | high | |
ssl.truststore.location | トラストストアーファイルの場所。 | 文字列 | null | high | |
ssl.truststore.password | トラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。 | password | null | high | |
auto.offset.reset | Kafkaの初期オフセットが無い場合、あるいは現在のオフセットがサーバ上にもうない場合(例えば、データが削除された)に、何をするか?:
| 文字列 | latest | [latest, earliest, none] | medium |
connections.max.idle.ms | この設定によって指定されるミリ秒後にアイドルの接続を閉じます。 | long | 540000 | medium | |
default.api.timeout.ms | ブロックするかもしれないコンシューマAPIについてのタイムアウト(ミリ秒)を指定します。この設定は明示的に timeout パラメータを受け取らない全てのコンシューマ操作についてのデフォルトのタイムアウトとして使われます。 | int | 60000 | [0,...] | medium |
enable.auto.commit | trueの場合、コンシューマのオフセットはバックグラウンドで定期的にコミットされるでしょう。 | boolean | true | medium | |
exclude.internal.topics | (オフセットのような)内部トピックからのレコードをコンシューマに公開すべきかどうか。true に設定すると、内部トピックからレコードを受け取る唯一の方法はそれを購読することです。 | boolean | true | medium | |
fetch.max.bytes | サーバが各フェッチリクエストについて返さなければならないデータの最大量。レコードはコンシューマによってバッチ内で取得されます。もし最初の空では無いパーティション内の最初のメッセージがこの値より大きい場合、コンシューマが進めることができるようにレコードのバッチはまだ返されるでしょう。このように、これは絶対的な最大ではありません。ブローカーに受け付けられる最大レコードバッチサイズは message.max.bytes (ブローカー設定) あるいは max.message.bytes (トピック設定) によって定義されます。コンシューマは並行して複数の取得を行うことに注意してください。 | int | 52428800 | [0,...] | medium |
isolation.level | トランザクション的に書き込まれるメッセージをどうやって読むかを制御します。 メッセージは常にオフセットの順番で返されるでしょう。従って、 更に、 | 文字列 | read_uncommitted | [read_committed, read_uncommitted] | medium |
max.poll.interval.ms | コンシューマグループ管理を使う時の poll() の起動間の最大の遅延。これはコンシューマがより多くのレコードを取得する前に仕事をしないでいられる総時間に上限を置きます。poll() がこのタイムアウトの期限切れの前に呼ばれなかった場合、コンシューマは失敗したと見なされ、グループはパーティションを他のメンバーに割り当てるためにリバランスするでしょう。 | int | 300000 | [1,...] | medium |
max.poll.records | poll()への1つの呼び出しで返されるレコードの最大数。 | int | 500 | [1,...] | medium |
partition.assignment.strategy | グループ管理が使われた場合に、コンシューマの間でパーティションの所有を分散するためにクライアントが使用するパーティション分割ストラテジのクラス名 | list | class org.apache.kafka.clients.consumer.RangeAssignor | org.apache.kafka.common.config.ConfigDef$NonNullValidator@5622fdf | medium |
receive.buffer.bytes | データを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 65536 | [-1,...] | medium |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。 | int | 30000 | [0,...] | medium |
sasl.client.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。 | クラス | null | medium | |
sasl.jaas.config | JAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*; '。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です; | password | null | medium | |
sasl.kerberos.service.name | Kafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。 | 文字列 | null | medium | |
sasl.login.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandler | クラス | null | medium | |
sasl.login.class | Loginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLogin | クラス | null | medium | |
sasl.mechanism | クライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。 | 文字列 | GSSAPI | medium | |
security.protocol | ブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。 | 文字列 | PLAINTEXT | medium | |
send.buffer.bytes | データを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 131072 | [-1,...] | medium |
ssl.enabled.protocols | SSL接続のために有効にされるプロトコルのリスト。 | list | TLSv1.2,TLSv1.1,TLSv1 | medium | |
ssl.keystore.type | キーストアファイルのファイル形式。これはクライアントについては任意です。 | 文字列 | JKS | medium | |
ssl.protocol | SSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。 | 文字列 | TLS | medium | |
ssl.provider | SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。 | 文字列 | null | medium | |
ssl.truststore.type | トラストストアファイルのファイル形式。 | 文字列 | JKS | medium | |
auto.commit.interval.ms | もしenable.auto.commit が true に設定されている場合に、コンシューマのオフセットがKafkaに自動コミットされる頻度のミリ秒。 | int | 5000 | [0,...] | low |
check.crcs | 消費されるレコードのCRC32を自動的にチェックする。これにより、通信上あるいはディスク上でメッセージの改竄が無いことを保証します。この調査はいくらかの負荷があるため、極度にパフォーマンスを求めている場合は無効にされているかも知れません。 | boolean | true | low | |
client.id | リクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。 | 文字列 | "" | low | |
fetch.max.wait.ms | すぐに指定されたfetch.min.bytes の要求を満たす十分なデータが無い場合に、サーバがフェッチリクエストに応答する前にブロックする最大の時間。 | int | 500 | [0,...] | low |
interceptor.classes | インタセプタとして使われるクラスのリスト。org.apache.kafka.clients.consumer.ConsumerInterceptor インタフェースを実装することにより、コンシューマによって受け取られるレコードを捕らえ(そしておそらく変化)することができます。デフォルトでは、インタセプタはありません。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@4883b407 | low |
metadata.max.age.ms | パーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。 | long | 300000 | [0,...] | low |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | org.apache.kafka.common.config.ConfigDef$NonNullValidator@7d9d1a19 | low |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | [INFO, DEBUG] | low |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [0,...] | low |
reconnect.backoff.max.ms | 接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。 | long | 1000 | [0,...] | low |
reconnect.backoff.ms | 指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。 | long | 50 | [0,...] | low |
retry.backoff.ms | 指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。 | long | 100 | [0,...] | low |
sasl.kerberos.kinit.cmd | Kerberos kinit コマンドライン パス。 | 文字列 | /usr/bin/kinit | low | |
sasl.kerberos.min.time.before.relogin | リフレッシュ試行間のログインスレッドのスリープ時間。 | long | 60000 | low | |
sasl.kerberos.ticket.renew.jitter | 更新時間に追加されるランダムなジッターのパーセンテージ。 | double | 0.05 | low | |
sasl.kerberos.ticket.renew.window.factor | 最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。 | double | 0.8 | low | |
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 にのみ適用されます。 | short | 300 | [0,...,3600] | low |
sasl.login.refresh.min.period.seconds | 証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。 | short | 60 | [0,...,900] | low |
sasl.login.refresh.window.factor | ログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.8 | [0.5,...,1.0] | low |
sasl.login.refresh.window.jitter | ログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.05 | [0.0,...,0.25] | low |
ssl.cipher.suites | cipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。 | list | null | low | |
ssl.endpoint.identification.algorithm | サーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 | 文字列 | https | low | |
ssl.keymanager.algorithm | SSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。 | 文字列 | SunX509 | low | |
ssl.secure.random.implementation | SSL暗号化操作のために使われる SecureRandom PRNG 実装。 | 文字列 | null | low | |
ssl.trustmanager.algorithm | SSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。 | 文字列 | PKIX | low |
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パスを使う必要があります。例えば、 |
|
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に初期オフセットが無いか、オフセットが範囲外の場合に、何をするか: |
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.converter | Kafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるキーの形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。 | クラス | high | ||
offset.storage.topic | コネクタのオフセットが格納されているKafkaトピック名 | 文字列 | high | ||
status.storage.topic | コネクタとタスクの状態が格納されているKafkaトピック名 | 文字列 | high | ||
value.converter | Kafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれる値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。 | クラス | high | ||
bootstrap.servers | Kafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,... の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。 | list | localhost:9092 | high | |
heartbeat.interval.ms | Kafkaのグループ管理機能を使う時に、コンシューマのグループコーディネータへのハートビート間に期待する時間。ハートビートはワーカーのセッションが活動中であることを保証し、新しいメンバーがグループに参加あるいは離れる時のリバランスを円滑にするために使われます。値はsession.timeout.ms より小さくなければなりませんが、一般的にはその値の1/3より大きく設定されなければなりません。通常の再バランスについては、期待する時間を制御するために少し小さく調整されるかも知れません。 | int | 3000 | high | |
rebalance.timeout.ms | 一旦リバランスが開始された後で各ワーカーがグループに入ることができる最大時間。これは基本的に全てのタスクが全ての延期されているデータをフラッシュしオフセットをコミットするのに必要な総時間を制限します。タイムアウトを超えると、ワーカーはグループから削除されるでしょう。これはオフセットのコミットの失敗を起こすでしょう。 | int | 60000 | high | |
session.timeout.ms | ワーカーの障害を検知するために使われるタイムアウト。ワーカーはその生存をブローカーに示すために定期的なハートビートを送信します。このセッションのタイムアウトが期限切れになる前にハートビートがブローカーによって受け取られない場合は、ブローカーはグループからこのワーカーを削除しリバランスを初期化するでしょう。値は group.min.session.timeout.ms とgroup.max.session.timeout.ms によって設定されるブローカーの設定内で設定される可能な範囲内でなければならないことに注意してください。 | int | 10000 | high | |
ssl.key.password | キーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。 | password | null | high | |
ssl.keystore.location | キーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。 | 文字列 | null | high | |
ssl.keystore.password | キーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 | password | null | high | |
ssl.truststore.location | トラストストアーファイルの場所。 | 文字列 | null | high | |
ssl.truststore.password | トラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。 | password | null | high | |
connections.max.idle.ms | この設定によって指定されるミリ秒後にアイドルの接続を閉じます。 | long | 540000 | medium | |
receive.buffer.bytes | データを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 32768 | [0,...] | medium |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。 | int | 40000 | [0,...] | medium |
sasl.client.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。 | クラス | null | medium | |
sasl.jaas.config | JAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*; '。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です; | password | null | medium | |
sasl.kerberos.service.name | Kafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。 | 文字列 | null | medium | |
sasl.login.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandler | クラス | null | medium | |
sasl.login.class | Loginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLogin | クラス | null | medium | |
sasl.mechanism | クライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。 | 文字列 | GSSAPI | medium | |
security.protocol | ブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。 | 文字列 | PLAINTEXT | medium | |
send.buffer.bytes | データを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 131072 | [0,...] | medium |
ssl.enabled.protocols | SSL接続のために有効にされるプロトコルのリスト。 | list | TLSv1.2,TLSv1.1,TLSv1 | medium | |
ssl.keystore.type | キーストアファイルのファイル形式。これはクライアントについては任意です。 | 文字列 | JKS | medium | |
ssl.protocol | SSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。 | 文字列 | TLS | medium | |
ssl.provider | SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。 | 文字列 | null | medium | |
ssl.truststore.type | トラストストアファイルのファイル形式。 | 文字列 | JKS | medium | |
worker.sync.timeout.ms | ワーカーが他のワーカーとの同期が外れ設定を再同期する必要がある場合、諦め、グループから外れ、再入会する前にバックオフの期間を待つ前に、この時間だけ待ちます。 | int | 3000 | medium | |
worker.unsync.backoff.ms | ワーカーが他のワーカーとの同期から外れ、worker.sync.timeout.ms の間に追いつくことに失敗した場合、再び加わる前にこの期間だけコネクトクラスタを離れます。 | int | 300000 | medium | |
access.control.allow.methods | Access-Control-Allow-Methods ヘッダで設定されるクロス オリジン リクエストをサポートするためのメソッドを設定します。Access-Control-Allow-Methods ヘッダのデフォルト値は GET, POST および HEAD のためのクロス オリジン リクエストを許可します。 | 文字列 | "" | low | |
access.control.allow.origin | REST 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 | 設定ストレージトピックを生成する時に使われるレプリケーション ファクター | short | 3 | [1,...] | low |
header.converter | Kafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われるHeaderConverterクラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるヘッダ値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。デフォルトでは SimpleHeaderConverter がヘッダ値を文字列にシリアライズ化するために使われ、スキーマを推測することでそれらをデシリアライズ化します。 | クラス | org.apache.kafka.connect.storage.SimpleHeaderConverter | low | |
internal.key.converter | Kafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれるキーの形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。この設定は設定やオフセットのようなフレームワークによって使われる内部的な簿記データによって使われる形式を制御します。つまりユーザは一般的にどのような機能のCコンバーターの実装もつかうことができいます。非推奨; もうすぐやってくるバージョンで削除されるでしょう。 | クラス | org.apache.kafka.connect.json.JsonConverter | low | |
internal.value.converter | Kafkaコネクタ形式とKafkaに書き込まれたシリアライズ化された形式との間で変換するために使われる変換クラス。これはKafkaに書き込まれる、あるいはKafkaから読み込まれる値の形式を制御します。これはコネクタから独立しているため、どのようなコネクタもどのようなシリアライズ化形式とも連携することができます。JSONとAvroを含む一般的な形式の例。この設定は設定やオフセットのようなフレームワークによって使われる内部的な簿記データによって使われる形式を制御します。つまりユーザは一般的にどのような機能のCコンバーターの実装もつかうことができいます。非推奨; もうすぐやってくるバージョンで削除されるでしょう。 | クラス | org.apache.kafka.connect.json.JsonConverter | low | |
リスナー | REST APIがlistenするURIのカンマ区切りのリスト。サポートされるプロトコルは HTTP と HTTPS です。全てのインタフェースにバインドするためには 0.0.0.0 としてホスト名を指定してください。デフォルトのインタフェースにバインドするには、ホスト名を空にします。合法なlistenerのリストの例: HTTP://myhost:8083,HTTPS://myhost:8084 | list | null | low | |
metadata.max.age.ms | パーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。 | long | 300000 | [0,...] | low |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | low | |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | [INFO, DEBUG] | low |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [0,...] | low |
offset.flush.interval.ms | タスクのためのオフセットのコミットを試す間隔。 | long | 60000 | low | |
offset.flush.timeout.ms | 将来の試行でオフセットデータが処理され回復される前に、レコードがフラッシュされパーティションのオフセットデータがオフセットストレージにコミットされる最大のミリ秒数。 | long | 5000 | low | |
offset.storage.partitions | オフセット ストレージ トピックを生成する時に使われるパーティションの数 | int | 25 | [1,...] | low |
offset.storage.replication.factor | オフセットストレージトピックを生成する時に使われるリプリケーション ファクター | short | 3 | [1,...] | low |
plugin.path | プラグイン (コネクタ、コンバータ、トランスフォーメーション)を含む、カンマ(,) で区切られたパスのリスト。リストは以下の組み合わせを含むトップレベルのディレクトリから成らなければなりません: a) プラグインとそれらの依存を持つjarを直接含むディレクトリ b) プラグインと依存を持つuber-jar c) プラグインとそれらの依存のクラスのパッケージディレクトリ構造を直接含むディレクトリ 注意: 依存あるいはプラグインを見つけるためにsymlinkが続くでしょう。例: plugin.path=/usr/local/share/java,/usr/local/share/kafka/plugins,/opt/connectors | list | null | low | |
reconnect.backoff.max.ms | 接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。 | long | 1000 | [0,...] | low |
reconnect.backoff.ms | 指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。 | long | 50 | [0,...] | low |
rest.advertised.host.name | これが設定されている場合は、これは他のワーカーが接続するように渡されるだろうホスト名です。 | 文字列 | null | low | |
rest.advertised.listener | 他のワーカーに使うように渡される通知されたlistener(HTTPあるいはHTTPS)を設定する。 | 文字列 | null | low | |
rest.advertised.port | これが設定されている場合は、これは他のワーカーが接続するように渡されるだろうポートです。 | int | null | low | |
rest.extension.classes | 指定された順番でロードおよび呼び出されるConnectRestExtension クラスのカンマ区切りの名前。インタフェースConnectRestExtension を実装することで、フィルタのようなユーザ定義のリソースをコネクタのREST APIに差し込むことができます。一般的にログ、セキュリティなどのような独自の機能を追加するために使われます。 | list | "" | low | |
rest.host.name | REST APIのためのホスト名。設定されている場合は、このインタフェースにのみバインドするでしょう。 | 文字列 | null | low | |
rest.port | REST APIがlistenするポート。 | int | 8083 | low | |
retry.backoff.ms | 指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。 | long | 100 | [0,...] | low |
sasl.kerberos.kinit.cmd | Kerberos kinit コマンドライン パス。 | 文字列 | /usr/bin/kinit | low | |
sasl.kerberos.min.time.before.relogin | リフレッシュ試行間のログインスレッドのスリープ時間。 | long | 60000 | low | |
sasl.kerberos.ticket.renew.jitter | 更新時間に追加されるランダムなジッターのパーセンテージ。 | double | 0.05 | low | |
sasl.kerberos.ticket.renew.window.factor | 最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。 | double | 0.8 | low | |
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 にのみ適用されます。 | short | 300 | [0,...,3600] | low |
sasl.login.refresh.min.period.seconds | 証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。 | short | 60 | [0,...,900] | low |
sasl.login.refresh.window.factor | ログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.8 | [0.5,...,1.0] | low |
sasl.login.refresh.window.jitter | ログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.05 | [0.0,...,0.25] | low |
ssl.cipher.suites | cipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。 | list | null | low | |
ssl.client.auth | クライアント認証をリクエストするためのKafkaブローカーを設定します。以下の設定が一般的です:
| 文字列 | none | low | |
ssl.endpoint.identification.algorithm | サーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 | 文字列 | https | low | |
ssl.keymanager.algorithm | SSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。 | 文字列 | SunX509 | low | |
ssl.secure.random.implementation | SSL暗号化操作のために使われる SecureRandom PRNG 実装。 | 文字列 | null | low | |
ssl.trustmanager.algorithm | SSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。 | 文字列 | PKIX | low | |
status.storage.partitions | ステータス ストレージ トピックを生成する時に使われるパーティションの数 | int | 5 | [1,...] | low |
status.storage.replication.factor | ステータスストレージトピックを生成する時に使われるリプリケーション ファクター | short | 3 | [1,...] | low |
task.shutdown.graceful.timeout.ms | タスクがgrecefullyにシャットダウンするために待つ時間。これはタスクごとではない総時間です。全てのタスクはシャットダウンを引き起こされ、それからそれらは順番に待ちます。 | long | 5000 | low |
3.6Kafka ストリーム設定
以下はKafkaストリームのクライアントライブラリの設定です。名前 | 説明 | 種類 | デフォルト | 有効な値 | 重要性 |
---|---|---|---|---|---|
application.id | ストリーム処理アプリケーションのための識別子。Kafkaクラスタ内でユニークでなければなりません。1) デフォルトのクライアントidのプリフィックス、2) メンバーシップ管理のためのグループid、3) changelogのトピックのプリフィックス。 | 文字列 | high | ||
bootstrap.servers | Kafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,... の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。 | list | high | ||
replication.factor | ストリーム処理アプリケーションによって生成されるログトピックとリパーティショントピックの変更のためのリプリケーション要素。 | int | 1 | high | |
state.dir | 状態の格納のためのディレクトリの場所。 | 文字列 | /tmp/kafka-streams | high | |
cache.max.bytes.buffering | 全てのスレッドを横断してバッファするために使われるメモリの最大バイト数 | long | 10485760 | [0,...] | medium |
client.id | 内部コンシューマ、プロデューサおよびレストア-コンシューマのクライアントidのために使われる、' | 文字列 | "" | medium | |
default.deserialization.exception.handler | org.apache.kafka.streams.errors.DeserializationExceptionHandler インタフェースを実装する例外処理クラス。 | クラス | org.apache.kafka.streams.errors.LogAndFailExceptionHandler | medium | |
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$ByteArraySerde | medium | |
default.production.exception.handler | org.apache.kafka.streams.errors.ProductionExceptionHandler インタフェースを実装する例外処理クラス。 | クラス | org.apache.kafka.streams.errors.DefaultProductionExceptionHandler | medium | |
default.timestamp.extractor | org.apache.kafka.streams.processor.TimestampExtractor インタフェースを実装するデフォルトのタイムスタンプ抽出クラス。 | クラス | org.apache.kafka.streams.processor.FailOnInvalidTimestamp | medium | |
default.value.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$ByteArraySerde | medium | |
num.standby.replicas | 各タスクのためのスタンドバイ レプリカの数。 | int | 0 | medium | |
num.stream.threads | ストリーム処理を実行するためのスレッドの数。 | int | 1 | medium | |
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。 | 文字列 | PLAINTEXT | medium | |
topology.optimization | トポロジを最適化する必要があるかどうかをKafkaストリームに伝える設定。デフォルトでは無効 | 文字列 | none | [none, all] | medium |
application.server | 1つのKafkaStreams アプリケーションの中のステートストアの場所を見つけるために使うことができる組み込みのユーザ定義のエンドポイントを指すホスト:ポートのペア | 文字列 | "" | low | |
buffered.records.per.partition | パーティションごとのバッファのためのレコードの最大数。 | int | 1000 | low | |
commit.interval.ms | プロセッサーの場所を保存する頻度。(注意、もし 'processing.guarantee' が 'exactly_once' に設定された場合、デフォルトは100、そうでなければデフォルト値は 30000 です。 | long | 30000 | low | |
connections.max.idle.ms | この設定によって指定されるミリ秒後にアイドルの接続を閉じます。 | long | 540000 | low | |
metadata.max.age.ms | パーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。 | long | 300000 | [0,...] | low |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | low | |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | [INFO, DEBUG] | low |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [0,...] | low |
partition.grouper | org.apache.kafka.streams.processor.PartitionGrouper インタフェースを実装するパーティショングループクラス。 | クラス | org.apache.kafka.streams.processor.DefaultPartitionGrouper | low | |
poll.ms | 入力を待つブロックの総時間のミリ秒数。 | long | 100 | low | |
receive.buffer.bytes | データを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 32768 | [0,...] | low |
reconnect.backoff.max.ms | 接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。 | long | 1000 | [0,...] | low |
reconnect.backoff.ms | 指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。 | long | 50 | [0,...] | low |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。 | int | 40000 | [0,...] | low |
retries | 0より大きい値を設定すると、クライアントは一時的なエラーによって失敗した全てのリクエストを再送信するでしょう。 | int | 0 | [0,...,2147483647] | low |
retry.backoff.ms | 指定されたトピックパーティションへの失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。 | long | 100 | [0,...] | low |
rocksdb.config.setter | Rocks DB 設定セッタークラス、あるいは org.apache.kafka.streams.state.RocksDBConfigSetter インタフェースを実装するクラス名 | クラス | null | low | |
send.buffer.bytes | データを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 131072 | [0,...] | low |
state.cleanup.delay.ms | パーティションが移行された時の状態を削除する前に待つ総時間のミリ秒数。少なくとも state.cleanup.delay.ms の間修正されていないステート ディレクトリだけが削除されるでしょう。 | long | 600000 | low | |
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日です | long | 86400000 | low |
3.7AdminClient 設定
以下はKafka Admin クライアント ライブラリの設定です。名前 | 説明 | 種類 | デフォルト | 有効な値 | 重要性 |
---|---|---|---|---|---|
bootstrap.servers | Kafkaクラスタへの初期の接続を確立するために使うホスト/ポートのペアのリスト。クライアントはブートストラッピングのためにここでどのサーバが指定されたかに関わらず全てのサーバを利用するでしょう — このリストはサーバの完全なセットを見つけるために使われる初期のホストにのみ影響を与えます。このリストはhost1:port1,host2:port2,... の形式でなければなりません。これらのサーバは完全なクラスタの会員(動的に変わるかも知れません)を見つけるための初期接続に使われるため、このリストはサーバの完全なセットを含む必要はありません (しかし、サーバがダウンした場合のために1つ以上が望まれるかも知れません)。 | list | high | ||
ssl.key.password | キーストアファイル内の秘密キーのパスワード。これはクライアントについては任意です。 | password | null | high | |
ssl.keystore.location | キーストアーファイルの場所。これはクライアントについては任意で、クライアントのための相互認証のために使うことができます。 | 文字列 | null | high | |
ssl.keystore.password | キーストアーファイルのためのストアパスワード。これはクライアントについては任意で、ssl.keystore.locationが設定された場合のみ必要です。 | password | null | high | |
ssl.truststore.location | トラストストアーファイルの場所。 | 文字列 | null | high | |
ssl.truststore.password | トラストストアーファイルのパスワード。もしパスワードが設定されない場合、truststoreへのアクセスはまだ可能ですが、完全性のチェックは無効にされます。 | password | null | high | |
client.id | リクエストする時にサーバに渡されるid文字列。これの目的は、サーバ側のリクエストのログに論理アプリケーション名を追加することで、ip/portを超えたリクエストのソースの追跡をすることです。 | 文字列 | "" | medium | |
connections.max.idle.ms | この設定によって指定されるミリ秒後にアイドルの接続を閉じます。 | long | 300000 | medium | |
receive.buffer.bytes | データを読み込む時に使われるTCPレシーバーバッファ (SO_RCVBUF) のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 65536 | [-1,...] | medium |
request.timeout.ms | この設定はクライアントがリクエストの応答を待つ総時間の最大を制御します。タイムアウトの時間が経過する前に応答が受信されない場合は、必要であればクライアントはリクエストを再送信するでしょう。あるいは再試行が使い尽くされた場合は失敗するでしょう。 | int | 120000 | [0,...] | medium |
sasl.client.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASLクライアント コールバック ハンドラ クラスの完全修飾名。 | クラス | null | medium | |
sasl.jaas.config | JAAS設定ファイル内で使われる形式のSASL接続のためのJAAS login コンテキスト パラメータ。JAAS 設定ファイルのフォーマットはここで説明されます。値の形式は: 'loginModuleClass controlFlag (optionName=optionValue)*; '。ブローカーについては、設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=com.example.ScramLoginModule が必要です; | password | null | medium | |
sasl.kerberos.service.name | Kafkaが実行するKerbrosプリンシパル名。これはKafkaのJAAS設定あるいはKafkaの設定のどちらかで定義することができます。 | 文字列 | null | medium | |
sasl.login.callback.handler.class | AuthenticateCallbackHandler インタフェースを実装するSASL ログイン コールバック ハンドラ クラスの完全修飾名。ブローカーについては、ログインのコールバックハンドラ設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.callback.handler.class=com.example.CustomScramLoginCallbackHandler | クラス | null | medium | |
sasl.login.class | Loginインタフェースを実装するクラスの完全修飾名。ブローカーについては、ログイン設定はlistenerのプリフィックスを前に付ける必要があり、SASL機構名は小文字でなければなりません。例えば、listener.name.sasl_ssl.scram-sha-256.sasl.login.class=com.example.CustomScramLogin | クラス | null | medium | |
sasl.mechanism | クライアント接続で使われるSASL機構。これはセキュリティプロバイダが利用可能な全ての機構です。GSSAPI がデフォルトの機構です。 | 文字列 | GSSAPI | medium | |
security.protocol | ブローカーと通信するために使われるプロトコル。有効な値は: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL。 | 文字列 | PLAINTEXT | medium | |
send.buffer.bytes | データを送信する時に使われるTCP送信バッファ (SO_SNDBUF)のサイズ。値が -1 であれば、OSのデフォルトが使われるでしょう。 | int | 131072 | [-1,...] | medium |
ssl.enabled.protocols | SSL接続のために有効にされるプロトコルのリスト。 | list | TLSv1.2,TLSv1.1,TLSv1 | medium | |
ssl.keystore.type | キーストアファイルのファイル形式。これはクライアントについては任意です。 | 文字列 | JKS | medium | |
ssl.protocol | SSLContextを生成するために使われるSSLプロトコル。デフォルトの設定はTLSで、これはほとんどの場合において問題ありません。最近のJVMで許可される値は、 TLS, TLSv1.1 および TLSv1.2 です。SSL, SSLv2 と SSLv3 は古いJVMではサポートされるかも知れませんが、これらの使用は既知のセキュリティ脆弱性のため推奨されません。 | 文字列 | TLS | medium | |
ssl.provider | SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。 | 文字列 | null | medium | |
ssl.truststore.type | トラストストアファイルのファイル形式。 | 文字列 | JKS | medium | |
metadata.max.age.ms | パーティションのリーダーシップが新しいブローカーあるいはパーティションを前もって見つけるために変更されたのを見ていないとしても、メタデータのリフレッシュを強制するミリ秒単位の時間。 | long | 300000 | [0,...] | low |
metric.reporters | メトリクス レポーターとして使われるクラスのリスト。org.apache.kafka.common.metrics.MetricsReporter インタフェースの実装により、新しいメトリックの生成を知らせるクラスをプラグインすることができます。JMX統計を登録するために常に JmxReporter が含まれます。 | list | "" | low | |
metrics.num.samples | メトリクスを計算するために保持される標本の数。 | int | 2 | [1,...] | low |
metrics.recording.level | メトリクスのための最も高い記録レベル。 | 文字列 | INFO | [INFO, DEBUG] | low |
metrics.sample.window.ms | メトリクスの標本が計算されるための時間の窓。 | long | 30000 | [0,...] | low |
reconnect.backoff.max.ms | 接続が繰り返し失敗するブローカーへの再接続時に待つミリ秒単位の総最大時間。指定された場合、ホスト毎のバックオフはそれぞれの連続する失敗ごとにこの最大まで指数関数的に増加するでしょう。バックオフの計算を増加した後で、接続の嵐を避けるために20%のランダムなジッターが追加されます。 | long | 1000 | [0,...] | low |
reconnect.backoff.ms | 指定されたホストに再接続しようとするまで待機する基本的な総時間。これにより短いループ内でホストに繰り返し接続することを防ぎます。このbackoffはクライアントによってブローカーに送信される全ての接続に適用されます。 | long | 50 | [0,...] | low |
retries | 0より大きい値を設定すると、クライアントは一時的なエラーによって失敗した全てのリクエストを再送信するでしょう。 | int | 5 | [0,...] | low |
retry.backoff.ms | 失敗したリクエストを再試行しようとするまで待機する総時間。これにより短いループ内で幾つかの失敗のシナリオがある場合に繰り返しリクエストすることを防ぎます。 | long | 100 | [0,...] | low |
sasl.kerberos.kinit.cmd | Kerberos kinit コマンドライン パス。 | 文字列 | /usr/bin/kinit | low | |
sasl.kerberos.min.time.before.relogin | リフレッシュ試行間のログインスレッドのスリープ時間。 | long | 60000 | low | |
sasl.kerberos.ticket.renew.jitter | 更新時間に追加されるランダムなジッターのパーセンテージ。 | double | 0.05 | low | |
sasl.kerberos.ticket.renew.window.factor | 最後にリフレッシュされてからチケットの期限切れまでの時間が指定されたウィンドウ要素になるまで、ログインスレッドはスリープします。そしてその時間にチケットを更新しようとするでしょう。 | double | 0.8 | low | |
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 にのみ適用されます。 | short | 300 | [0,...,3600] | low |
sasl.login.refresh.min.period.seconds | 証明書をリフレッシュする前にログイン フレッシュ スレッドが待つ望ましい最小の時間の秒数。有効な値は0から900 (15分); 値が指定されない場合はデフォルトの値60(1分)が使われます。この値と sasl.login.refresh.buffer.seconds は、もしそれらの合計が証明書の残りの生存期間を超える場合に両方とも無視されます。現在のところは OAUTHBEARER にのみ適用されます。 | short | 60 | [0,...,900] | low |
sasl.login.refresh.window.factor | ログイン フレッシュ スレッドは、証明書の生存期間に関連した指定されたウィンドウ ファクタに達するまでスリープしようとします。その時点で証明書をリフレッシュしようとするでしょう。有効な値は0.5 (50%)以上と1.0 (100%)以下の間です; 値が指定されない場合はデフォルトの値 0.8 (80%)が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.8 | [0.5,...,1.0] | low |
sasl.login.refresh.window.jitter | ログイン スレッドのスリープ時間に追加された証明書の生存期間に対するランダム ジッタの最大量。有効な値は 0以上と0.25 (25%)以下の間です; 値が指定されない場合はデフォルトの値 0.05 (5%) が使われます。現在のところは OAUTHBEARER にのみ適用されます。 | double | 0.05 | [0.0,...,0.25] | low |
ssl.cipher.suites | cipher スイーツのリストこれはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる、認証、暗号化、MACおよびキー交換アルゴリズムの名前の組み合わせです。デフォルトでは全ての利用可能なcipherスイーツがサポートされます。 | list | null | low | |
ssl.endpoint.identification.algorithm | サーバの証明書を使ってサーバのホスト名を検証するためのエンドポイント識別アルゴリズム。 | 文字列 | https | low | |
ssl.keymanager.algorithm | SSL接続のためにキーマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されたキーマネージャーファクトリーアルゴリズムです。 | 文字列 | SunX509 | low | |
ssl.secure.random.implementation | SSL暗号化操作のために使われる SecureRandom PRNG 実装。 | 文字列 | null | low | |
ssl.trustmanager.algorithm | SSL接続のためにトラストマネージャーファクトリーによって使われるアルゴリズム。デフォルト値はJava仮想マシーンのために設定されトラストーマネージャーファクトリーアルゴリズムです。 | 文字列 | PKIX | low |
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つの事を知っています:
- オブジェクトのメモリオーバーヘッドは非常に高く、しばしば格納されたデータを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の効果を知るためには、ファイルからソケットへのデータの転送のための共通のデータパスを理解することが重要です:
- オペレーティングシステムはデータをディスクからカーネル空間のページキャッシュに読み込む
- アプリケーションはデータをカーネル空間からユーザ空間のバッファに読み込む
- アプリケーションはデータをソケットバッファのカーネル空間へ書き込む
- オペレーティングシステムはデータをソケットバッファからネットワーク上に送信される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回だけ配送されます。
多くのシステムは "確実に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ミリ秒程度掛かるかもしれません。しかし、プロデューサは、完全に同期して送信をしたい、あるいはリーダー(必ずしもフォロワーではない)がメッセージを受け取るまでのみ待ちたいということも指定することができます。
ではコンシューマの視点からのセマンティクスを説明しましょう。全てのレプリカは同じオフセットを使って確実に同じログを持ちます。コンシューマはログ内のその位置を制御します。もしコンシューマが停止しなければ、メモリ内にこの位置を格納するだけです。しかしもしコンシューマが故障し、このトピックパーティションを他のプロセスに交代したい場合は、新しい処理は処理を開始する適切な位置を選択する必要があります。例えば、コンシューマが何らかのメッセージを読むとした場合 -- メッセージを処理しその位置を更新するには幾つかのオプションがあります。
- メッセージを読み、ログ内に位置を保存し、最後にメッセージを処理することができます。この場合、位置を保存した後だがそのメッセージの処理の出力を保存する前にコンシューマの処理が停止する可能性があります。この場合、処理を引き継いだプロセスは、その位置より前の2,3のメッセージが処理されなかったとしても、保存された位置から開始するでしょう。この場合コンシューマの不足したメッセージは処理されないかも知れないので、これは"最大1回"のセマンティクスに対応します。
- メッセージを読み込み、メッセージを処理し、最後にその位置を保存することができます。この場合、メッセージの処理の後だがその位置を保存する前にコンシューマのプロセスが停止する可能性があります。この場合、新しいプロセスが引き継いだ時に、受信する最初の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つの条件があります
- ノードはZooKeeperを使ってセッションを維持できなければなりません (ZooKeeperのハートビート機構)
- スレーブであれば、リーダーに起きた書き込みをレプリケートしなければならず、"あまりに遅れて"はなりません
分散システムの用語では、ノードが突然動作を停止しその後回復(おそらくそれらが死んだことを知ること無しに)する障害の "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つの挙動があります:
- ISR内のレプリカを復活するのを待ち、このレプリカをリーダーとして選択する(できれば、それはまだ全てのデータを持っています)。
- 復活する最初のレプリカ(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つのトピックレベルの設定を提供します。- 汚れたリーダーの選出を無効化 - もし全てのレプリカが利用不可になった場合、ほとんどの最新のリーダー再び利用可能になるまでパーティションは利用不可のままになるでしょう。これはメッセージの喪失のリスクより利用不可を事実上好みます。説明は前の章の汚れたリーダー選出を見てください。
- 最小の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つはなんらかのデータベースです (RDBMSあるいはおそらく新しい価値のあるキー-値ストア)。例えば、データベース、キャッシュ、検索クラスタおよびHadoopクラスタを持つかもしれません。データベースへの各変更はキャッシュ、検索クラスタ、最終的にHadoopに反映される必要があるでしょう。リアルタイムの更新のみを処理する場合は、最新のログだけが必要です。しかし、キャッシュを再読み込み、あるいは障害を起こした検索ノードを回復したい場合は、完全なデータセットが必要かもしれません。
- イベント ソース。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.
- 高可用性のためのジャーナリング。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スループットの量を超えずに使うように絞ることができます。ログ セグメントの圧縮の実際のプロセスは以下のようなものに見えます:
ログの圧縮は何を提供しますか?
ログの圧縮は以下のものをていきょうします:- ログの先頭に追いついているコンシューマは書き込まれた全てのメッセージを見るでしょう; これらのメッセージは連続するオフセットを持つでしょう。トピックの
min.compaction.lag.ms
は圧縮される前に書き込まれるメッセージの後で経過しなければならない最小の長さを保証するために使われます。つまり、各メッセージが(非圧縮の)head内に存在するだろう長さの低い方の境界を提供します。 - メッセージの順番は常に維持されます。圧縮はメッセージの順番を並び変えることはせず、単に幾つかを削除するでしょう。
- メッセージについてのオフセットは変わりません。それはログ内の位置についての恒久的な識別子です。
- ログの最初から進んでいるコンシューマは書き込まれた順番で全てのレコードの少なくとも最終的な状態を見るでしょう。さらに、コンシューマがトピックの
delete.retention.ms
設定(デフォルトは24時間)より少ない時間でログの先頭に到達した場合、削除されたレコードについての全てのdeleteマーカーが表示されます。別の言い方をすると: deleteマーカーの削除は読み込みと同時に起こるため、もし遅れがdelete.retention.ms
より大きい場合はコンシューマはdeleteマーカーを紛失するかもしれません。
ログの圧縮の詳細
ログの圧縮は、ログクリーナー、ログのセグメントファイルを再コピーするバックグラウンドのスレッドのプール、ログの最初に現れるキーのレコードの削除によって処理されます。各コンパクタースレッドは以下のように動作します:- ログのtailのログの頭の一番高いレートを持つログを選択します
- ログの先頭の各キーについての最後のオフセットの簡潔な要約を作成します
- ログ内で最近現れたキーを削除しながら、最初から最後までログを再コピーします。新しい、きれいなセグメントはすぐにログに入れ替えられます。つまり必要とされる追加のディスク空間はちょうど1つの追加のログセグメントです (ログの完全なコピーではありません)。
- ログの頭の概要は本質的に単なる空間がぎっしりつまったハッシュテーブルです。それはエントリごとに正確に24バイトです。8GBのクリーナーバッファーの結果として、1つのクリナーの繰り返しでログのheadの約366GBをきりえします (1kのメッセージを仮定します)。
ログクリーナーの設定
ログクリーナーはデフォルトで有効です。これはクリーナースレッドのプールを開始するでしょう。あるトピック上でログクリーナーを有効にするために、ログ固有のプロパティを追加することができますlog.cleanup.policy=compactこれはトピックの作成時あるいは代替のトピックコマンドを使って行うことができます。
ログクリーナーはログの非圧縮の"head"の最小量を維持するように設定することができます。これは圧縮時間のラグを設定することで有効になります。
log.cleaner.min.compaction.lag.msこれは最小のメッセージ経過時間より新しいメッセージが圧縮されなければならないことを避けるために使うことができます。設定されない場合は、最後の、つまり現在書き込まれているセグメントを除いて、全てのログのセグメントが圧縮の資格があります。有効なセグメントは、たとえメッセージの全てが最小の圧縮タイムのラグより古くても圧縮されないでしょう。
クリーナーの更なる設定はここで説明されます。
4.9クォータ
Kafka クラスタはクライアントにいって使われるブローカーのリソースを制御するために、リクエストに割り当てを強制することができます。クォータを共有するクライアントグループごとにKafkaのブローカーによって2種類のクライアント クォータを適用することができます:
- ネットワークの帯域の割り当てはバイトレートの閾値を定義します (0.9から)
- リクエストのレートの定員はネットワークと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の下に書き込まれます。これらの上書きは全てのブローカーから読み込まれ、すぐに有効になります。これにより、クラスタ全体のローリング再起動をする必要無しに割り当ての変更ができます。詳細はここを見てください。各グループについてのデフォルトの割り当ては同じ仕組みを使って動的に更新することもできます。
割り当て設定の優先順位は以下の通りです:
- /config/users/<user>/clients/<client-id>
- /config/users/<user>/clients/<default>
- /config/users/<user>
- /config/users/<default>/clients/<client-id>
- /config/users/<default>/clients/<default>
- /config/users/<default>
- /config/clients/<client-id>
- /config/clients/<default>
ネットワークの帯域の割り当て
ネットワークの帯域の割り当ては、割り当てを共有するクライアントの各グループについてのバイトレートの閾値として定義されます。デフォルトでは、各ユニークなクライアントグループはクラスタによって定義されたものとして、バイト/秒の一定の割り当てを受け取ります。この割り当てはブローカー単位を基準に定義されます。クライアントの各グループはクライアントが絞られる前にブローカーあたり最大 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_0
と my_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に移設することができます:
- コンシューマの設定の中で
offsets.storage=kafka
とdual.commit.enabled=true
を設定します。 - コンシューマのローリング バランスを行い、コンシューマがhealthyであることを確認します。
- コンシューマの設定の中で
dual.commit.enabled=false
を設定します。 - コンシューマのローリング バランスを行い、コンシューマが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を生成します。
ブローカーのノードの登録
ブローカーのノードは基本的に依存しません。つまり、それらは何を持っているかについて情報を公開するだけです。ブローカーが参加した時に、それは自身をブローカーノードのレジストリディレクトリに登録し、ホスト名とポートについての情報を書き込みます。ブローカーも既存のトピックのリストとそれらの論理パーティションをブローカーのトピックのレジストリに書き込みます。新しいトピックはそれらがブローカー上に生成された時に動的に登録されます。
コンシューマーの登録アルゴリズム
コンシューマが開始すると、それは以下のことを行います:
- 自身をグループの下のコンシューマid内に登録します。
- コンシューマidレジストリの下に変更時(新しいコンシューマが参加あるいは既存のコンシューマの中止)の監視を登録する。(各変更は変更されたコンシューマが所属するグループ内の全てのコンシューマ間でリバランスを引き起こします。)
- ブローカーidレジストリの下に変更時(新しいブローカーが参加あるいは既存のブローカーの中止)の監視を登録する。(各変更は全てのコンシューマグループ内の全てのコンシューマ間でリバランスを引き起こします。)
- コンシューマがトピックフィルターを使ってメッセージストリームを生成した場合、コンシューマはブローカートピックレジストリの下に変更時(新しいトピックが追加)の監視も登録します。(各変更はどのトピックがトピックフィルターによって許されるかを決定するために、利用可能なトピックの再評価を引き起こすでしょう。新しく許されたトピックはコンシューマグループ内の全てのコンシューマ間でリバランスを引き起こすでしょう。)
- コンシューマ グループ内で強制的にリバランスしてください。
コンシューマーのリバランスのアルゴリズム
コンシューマのリバランスアルゴリズムにより、グループ内の全てのコンシューマはどのコンシューマがどのパーティションを消費しているかの同意を取ることができます。コンシューマのリバランスはブローカーノードおよび同じグループ内の他のコンシューマの両方の追加あるいは削除時に引き起こされます。指定されたトピックおよび指定されたコンシューマグループについて、ブローカーのパーティションは最終的にグループ内のコンシューマ間で分配されます。パーティションは常に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つの最適化があります:- 再起動をした時にログの回復をする必要を避けるためにディスクに全てのログを同期するでしょう (つまり、ログのtailの中で全てのメッセージについてチェックサムの検証をする)。ログの回復には時間がかかるため、これは内部的な再起動を高速化します。
- シャットダウンする前に、そのサーバがリーダーになっている全てのパーティションを他のレプリカに移行するでしょう。リーダーシップの転送を高速化し、各パーティションが利用できない時間を数ミリ秒に最小化するでしょう。
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'
を使ってA と Bという名前の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
> 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 successfullykafka-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.bytes
と socket.receive.buffer.bytes
の設定を使って、プロデューサ、コンシューマおよびブローカーのTCPソケットバッファサイズを増やす必要があるかもしれません。これを設定する適切な方法はここで提供されます。
高レンテンシのリンク上で複数のデータセンタに掛かる単独のKafkaクラスタを実行することは、一般的に望ましいものではありません。これはKafkaの書き込みおよびZookeeperの書き込みの両方に高レプリケーション レイテンシを招き、もし場所間のネットワークが利用できない場合にKafkaあるいはZooKeeperのどちらも全ての場所で利用できないままになるでしょう。
6.3Kafka 設定
重量なクライアント設定
最も重要な古いScalaプロデューサの設定の制御- acks
- 圧縮
- sync vs async production
- バッチ サイズ (非同期プロデューサのため)
- acks
- 圧縮
- バッチ サイズ
全ての設定は設定の章の中で提供されます。
プロダクションのサーバ設定
以下はプロダクションのサーバ設定の例です:# 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
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-rate
はrecords-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-count | Kafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの数。 | |
sink-record-active-count-avg | Kafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの平均数。 | |
sink-record-active-count-max | Kafkaから読み込まれたが、まだシンクタスクによって完全には コミット/フラッシュ/通知 されていないレコードの最大数。 | |
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監視インフラストラクチャーと良く連携することは確かです)
- クラスタを建て過ぎないでください: 大きなクラスタ、特に書き込みが激しい使用パターンは多くのクラスタ内の通信(書き込みの定員とその後のクラスタメンバーの更新)を意味しますが、中途半端に建てないでください(リスクがクラスタを圧倒します)。サーバを増やすと、読み取りの容量が増えます。
7. セキュリティ
リリース 0.9.0.0で、Kafkaコミュニティは、個々にあるいは一緒に使われる、Kafkaクラスタのセキュリティを強める多くの機能を追加しました。以下のセキュリティ手段が現在のところサポートされます:- 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から
- ブローカーからZooKeeperへの接続の認証
- SSLを使って、ブローカーとクライアント間、ブローカー間、あるいはブローカーとツール間で転送されるデータを暗号化 (SSLが有効な場合にパフォーマンスの低下があり、大きさはCPUの型とJVM実装に依存することに注意してください)。
- クライアントによる 読み込み/書き込み操作の認証
- 認証は差し込み可能で外部の認証サービスとの統合がサポートされます
7.2SSLを使った暗号化と認証
Apache Kafka を使ってクライアントはSSL上で接続することができます。デフォルトでは、SSLは無効ですが、必要に応じて作動することができます。各KafkaブローカーのためのSSLキーと証明書を生成する
SSLをサポートする1つ以上のブローカーを配備する最初のステップは、クラスタ内の各マシーンのためにキーと証明書を生成することです。この作業を実行するためにJavaのキーツール ユーティリティを使うことができます。キーをエクスポートし後でCAを使って署名するために、最初にキーを一時的なキーストアに生成しましょう。keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey -keyalg RSA
上のコマンドの中で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つに対して検証するでしょう:- 一般名 (CN)
- サブジェクトの別名 (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
独自の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を信頼する同じトラストストアを共有することができます。そのようにして全てのマシーンは全ての他のマシーンを認証することができます。証明書の署名
次のステップはステップ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
パラメータの定義は以下の通りです:- keystore: キーストアの場所
- ca-cert: CAの証明書
- ca-key: CAの秘密鍵
- ca-password: CAのパスフレーズ
- cert-file: エクスポートされた、サーバの未署名の証明書
- cert-signed: サーバの署名された証明書
#!/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
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へのアクセスはまだ可能ですが、完全性のチェックは無効にされます。考慮に値する任意の設定:- ssl.client.auth=none ("required" => クライアントの認証が必要です、"requested" => クライアント認証が必要で、証明書なしのクライアントはまだ接続することができます。"requested"の使用は大丈夫だという誤った間隔を与え、間違ったクライアントはまだ接続に成功するだろうためお勧めできません。)
- ssl.cipher.suites (任意)。cipherスイートはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる認証、暗号、MACおよびキー交換アルゴリズムの組み合わせで名前を付けられます。(デフォルトは空のリストです)
- ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1 (クライアントから受け付けるつもりのSSLプロトコルをリスト化する。SSLはTLSに賛成して非推奨で、プロダクションでのSSLの使用はお勧めされないことに注意してください)
- ssl.keystore.type=JKS
- ssl.truststore.type=JKS
- ssl.secure.random.implementation=SHA1PRNG
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接続のパフォーマンスが問題になる場合は、明示的に使用する実装の設定を考慮してください。TheSHA1PRNG
実装は非ブロッキングで高負荷でとても良いパフォーマンスの特徴を示しています (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
もし証明書が現れないか、他のエラーメッセージがある場合は、キーストアが適切にセットアップされていません。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
必要とされるかもしれない他の構成の設定は、要求とブローカーの設定によります:- ssl.provider (任意)。SSL接続のために使われるセキュリティプロバイダの名前。デフォルト値はJVMのデフォルトのセキュリティプロバイダです。
- ssl.cipher.suites (任意)。cipherスイートはTLSあるいはSSLネットワークプロトコルを使うネットワーク接続のためのセキュリティ設定を取り決めるために使われる認証、暗号、MACおよびキー交換アルゴリズムの組み合わせで名前を付けられます。
- ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1. ブローカー側で設定される少なくとも1つのプロトコルがリスト化されるべきです
- ssl.truststore.type=JKS
- 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を使った認証
JAAS 設定
KafkaはSASL設定のためのJavaの認証と権限サービス(JAAS) を使います。
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)に設定してください。
- ブローカーの設定プロパティ
listener.name.{listenerName}.{saslMechanism}.sasl.jaas.config
- 静的なJAAS設定の
{listenerName}.KafkaServer
セクション - 静的なJAAS設定の
KafkaServer
セクション
ブローカーはブローカー設定プロパティ
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設定が異なるレベルで定義される場合、以下の優先度の順番が使われます:ブローカーの設定の例についてはGSSAPI (Kerberos), PLAIN, SCRAM あるいは OAUTHBEARER を見てください。
KafkaクライアントのためのJAAS設定
クライアントは、クライアントの設定プロパティ sasl.jaas.config あるいはブローカーのように 静的な JAAS 設定ファイルを使って設定することができます。
クライアントの設定プロパティを使ったJAAS 設定
クライアントは物理的な設定ファイル無しにプロデューサあるいはコンシューマプロパティとしてJAAS設定を指定することができます。このモードはクライアントごとに異なるプロパティを指定することで同じJVM内の異なるプロデューサとコンシューマに異なる証明書を使うことができるようにもします。もし静的なJAAS設定システムプロパティ
java.security.auth.login.config
とクライアントプロパティsasl.jaas.config
の両方が指定された場合、クライアントプロパティが使われるでしょう。設定の例についてはGSSAPI (Kerberos), PLAIN, SCRAM あるいは OAUTHBEARER を見てください。
静的な設定ファイルを使ったJAAS設定
静的なJAAS設定ファイルを使ってクライアント上でSASL認証を設定するには:- 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"; };
- JVMパラメータとしてJAAS設定ファイルの場所を各クライアントのJVMに渡す。例えば:
-Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf
- KafkaClientという名前のクライアント ログイン セクションを持つJAAS設定ファイルを追加します。GSSAPI (Kerberos), PLAIN SCRAM あるいは OAUTHBEARERを設定するために、例の中で説明されたように選択された仕組みのための KafkaClient 内のログインモジュールを設定する。例えば、GSSAPI証明書は以下のように設定することができます:
SASL設定
SASLはそれぞれセキュリティプロトコル SASL_PLAINTEXT あるいは SASL_SSL を使ってトランスポート層としてPLAINTEXTあるいはSSLと一緒に使われるかもしれません。もし SASL_SSL が使われた場合、SSLも設定されなければなりません。
SASL 機構
Kafkaは以下のSASL機構をサポートします:- GSSAPI (Kerberos)
- PLAIN
- SCRAM-SHA-256
- SCRAM-SHA-512
- OAUTHBEARER
Kafkaブローカーのための SASL 設定
- 少なくとも 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)
- ブローカー内で有効にするために1つ以上のsupported mechanismsを選択し、仕組みのためのSASLを設定するためにステップに従います。ブローカー内で複数の仕組みを有効にするには、ここのステップに従ってください。
- 少なくとも SASL_PLAINTEXT あるいは SASL_SSL のうちの1つを listeners パラメータに追加することで、server.properties内のSASLポートを設定します。これは1つ以上のカンマ区切りの値を含みます:
KafkaクライアントのためのSASL設定
SASL認証は新しいJava Kafkaプロデューサとコンシューマについてのみサポートされ、古いAPIはサポートされません。
クライアント上でSASL認証を設定するには、クライアント認証のためにブローカー内で有効にされるSASL仕組みを選択し、選択された仕組みのためのSASLを設定するためにステップに従います。
SASL/Kerberos を使った認証
必要条件
- Kerberos
組織がすでにKerberosサーバを使っている場合(例えば、Activeディレクトリを使って)、Kafkaのためだけに新しいサーバをインストールする必要はありません。そうでなければ、インストールする必要があります。LinuxのベンダーがおそらくKerberosのためのパッケージとそれをどうやってインストールおよび設定する方法についての概要を持っているでしょう (Ubuntu, Redhat)。Oracle Javaを使っている場合は、JavaバージョンのためのJCEポリシーファイルをダウンロードし、それらを $JAVA_HOME/jre/lib/security にコピーする必要があるでしょう。 - 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}"
- 全てのホストがホスト名を使って到達可能であるようにしてください - それらのFQDNを使って全てのホストが解決可能であることがKerberosの要求です。
- Kerberos
Kafkaブローカーの設定
- 以下のものに似た適切に修正された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"; };
JAASファイル内のKafkaServerセクションはブローカーにどのprincipalを使用するか、このprincipalが格納されているkeytabの場所を伝えます。それによりブローカーはこのセクションで指定されたkeytabを使ってログインすることができます。Zookeeper SASL設定の詳細についてはnotes を見てください。
- 各KafkaサーバにJAASと任意にkerb5ファイルの場所をJVMパラメータとして渡します (詳細は ここ を見てください):
-Djava.security.krb5.conf=/etc/kafka/krb5.conf -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
- JAASファイル内で設定されたkeytabがkafkaブローカーを開始するオペレーティングシステムのユーザに読み込み可能であるようにしてください:
- ここで説明されるように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
server.properties 内でサービス名を設定する必要もあります。これはkafkaブローカーのprincipal名と一致しなければなりません。上の例では、principalは "kafka/kafka1.hostname.com@EXAMPLE.com"です。つまり:
sasl.kerberos.service.name=kafka
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう (各ブローカーは独自のkeytabを持つ必要があることに注意してください):
Kafkaクライアントの設定
クライアント上でSASL認証を設定するには:-
クライアント (プロデューサ、コンシューマ、コネクト ワーカーなど)は独自の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からの全てのクライアント接続のためにただ一人だけのユーザを許可します。 - JAAS設定内で設定されたkeytabがkafkaクライアントを開始するオペレーティングシステムのユーザに読み込み可能であるようにしてください:
- 任意でkrb5ファイルの場所をJVMパラメータとして各クライアントJVMに渡します (詳細はここを見てください):
-Djava.security.krb5.conf=/etc/kafka/krb5.conf
- 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
security.protocol=SASL_PLAINTEXT (or SASL_SSL) sasl.mechanism=GSSAPI sasl.kerberos.service.name=kafka
-
クライアント (プロデューサ、コンシューマ、コネクト ワーカーなど)は独自のprincipal (通常はクライアントを実行するユーザと同じ名前と一緒に)を使ってクラスタを認証するでしょう。ですので必要に応じてこれらのprincipalを取得あるいは生成してください。そして、各クライアントについてJAAS設定プロパティを設定します。JVM内の子となるクライアントは異なるprincipalを指定することで異なるゆーあとして実行するかもしれません。producer.propertiesあるいはconsumer.properties内のプロパティ
SASL/PLAIN を使った認証
SASL/PLAIN は安全な認証を実装するためのTLSで一般的に使われる暗号化のための単純な ユーザ名/パスワード 認証です。Kafkaはここで説明されるようにプロダクションでの使用のために拡張可能なSASL/PLAINのためのデフォルトの実装です。
ユーザ名はACLなどの設定のための認証されたPrincipal
として使われます。
Kafkaブローカーの設定
- 以下のものに似た適切に修正された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つのユーザを定義します (adminとalice)。KafkaServer セクション内のプロパティ username と passwordはブローカーによって他のブローカーへの接続を開始するために使われます。この例では、adminは内部ブローカー接続のためのユーザです。プロパティ user_userName のセットはブローカーへ接続する全てのユーザのためのパスワードを定義し、ブローカーはこれらのプロパティを使って他のブルーカーからの全てのクライアント接続を検証します。 - JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
- ここで説明されるように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
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
Kafkaクライアントの設定
クライアント上でSASL認証を設定するには:- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はPLAIN機構についてのクライアントのための設定例です:
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ username="alice" \ password="alice-secret";
オプションusername と password はクライアント接続のためのユーザを設定するためにクライアントによって使われます。この例では、クライアントはブローカーにユーザ alice として接続します。JVM内の子となるクライアントは
sasl.jaas.config
内で異なるユーザ名とパスワードを指定することで、異なるユーザとして接続するかもしれません。別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。
- 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
security.protocol=SASL_SSL sasl.mechanism=PLAIN
- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はPLAIN機構についてのクライアントのための設定例です:
プロダクションでの SASL/PLAIN の使用
- SASL/PLAIN は明白なパスワードが暗号化無しに回線上を転送されないようにするために、トランスポート層としてSSLのみが使われるべきです。
- KafkaでのSASL/PLAINのデフォルトの実装はここで示されるようにJAAS設定ファイル内でユーザ名とパスワードを指定します。Kafkaバージョン 2.0以降、設定オプション
sasl.server.callback.handler.class
とsasl.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インストレーション内で使うのに適しています。詳細は セキュリティの考慮を参照してください。
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
Kafkaブローカーの設定
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
KafkaServer { org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin-secret"; };
KafkaServerセクション内のプロパティ username と passwordはブローカーによって他のブローカーへの接続を始めるために使われます。この例では admin が内部ブローカー通信のためのユーザです。 - JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
- ここで説明されるように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)
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
Kafkaクライアントの設定
クライアント上でSASL認証を設定するには:- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はSCRAM機構のためのクライアントのための設定の例です:
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \ username="alice" \ password="alice-secret";
オプションusername と password はクライアント接続のためのユーザを設定するためにクライアントによって使われます。この例では、クライアントはブローカーにユーザ alice として接続します。JVM内の子となるクライアントは
sasl.jaas.config
内で異なるユーザ名とパスワードを指定することで、異なるユーザとして接続するかもしれません。別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。
- 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
security.protocol=SASL_SSL sasl.mechanism=SCRAM-SHA-256 (あるいは SCRAM-SHA-512)
- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はSCRAM機構のためのクライアントのための設定の例です:
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インストレーションでの使用にのみ適しています。詳細は セキュリティの考慮を参照してください。
Kafkaブローカーの設定
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
KafkaServer { org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required unsecuredLoginStringClaim_sub="admin"; };
KafkaServerのセクションのプロパティunsecuredLoginStringClaim_subは、ブローカが他のブローカーに接続を始める時にブローカーによって使われます。この例では、adminは件名 (sub) 要求に現れ、ブローカー間の通信のためのユーザになるでしょう。 - JAAS設定ファイルの場所をJVMパラメータとして各Kafkaブローカーに渡します:
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
- ここで説明されるように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
- 以下のものに似た適切に修正されたJAASファイルを各Kafkaブローカーの設定ディレクトリに追加し、この例のために kafka_server_jaas.conf を呼んでみましょう:
Kafkaクライアントの設定
クライアント上でSASL認証を設定するには:- 各クライアントについての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からの全てのクライアント接続のためにただ一人だけのユーザを許可します。
- 以下のプロパティを producer.properties あるいは consumer.properties の中で設定します:
security.protocol=SASL_SSL (or SASL_PLAINTEXT if non-production) sasl.mechanism=OAUTHBEARER
- SASL/OAUTHBEARER のデフォルトの実装は jackson-databind ライブラリに依存します。それは任意の依存のため、ユーザはそれらのビルドツールを使って依存としてそれを設定する必要があります。
- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はOAUTHBEARER機構のためのクライアントのための設定の例です:
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 要求の名前を望む場合、独自の要求名を設定してください。
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を参照してください。
- これらはUnsecured JSON Web Token検証のためのブローカー側での様々なサポートされるJAASモジュールオプションです:
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 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 ブローカー設定オプションを使って宣言する必要もあるでしょう。
SASL/OAUTHBEARER のセキュリティの考慮
- Kafkaでの SASL/OAUTHBEARER のデフォルトの実装は、Unsecured JSON Web Tokensを作成し検証します。これは非プロダクションの使用のためのみに適しています。
- OAUTHBEARER はプロダクション環境ではトークンの傍受を避けるためにTLS-encryptionと一緒にのみ使われるべきです。
- デフォルトの安全では無いSASL/OAUTHBEARER 実装は上で説明したように独自のloginおよびSASLサーバ コールバック ハンドラを使って上書きすることができます (そしてプロダクション環境では上書きされるべきです)。
- 一般的なOAuth 2 セキュリティの考慮についての詳細は RFC 6749, Section 10を参照してください。
ブローカー内での複数のSASL機構を有効化
- 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"; };
- server.properties内のSASL機構を有効にする:
sasl.enabled.mechanisms=GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512,OAUTHBEARER
- 必要であればserver.properties内の内部ブローカー通信のためのSASLセキュリティプロトコルと仕組みを指定します:
security.inter.broker.protocol=SASL_PLAINTEXT (あるいは SASL_SSL) sasl.mechanism.inter.broker.protocol=GSSAPI (あるいは他の有効にされた仕組みのうちの1つ)
- 有効にされた機構のためのSASLを設定するためにGSSAPI (Kerberos), PLAIN, SCRAM および OAUTHBEARER内の仕組みに固有のステップに従います。
実行中のクラスタ内のSASL機構を修正する
以下の手順を使って実行中のクラスタ内のSASL機構を修正することができます:
- 各ブローカーについて仕組みをserver.properties内のsasl.enabled.mechanismsに追加することで新しいSASL機構を有効にします。ここで説明される両方の仕組みを含めるためにJASS設定ファイルを更新します。クラスタのノードを逐次的にバウンスします。
- 新しい仕組みを使ってクライアントを再起動します。
- (必要であれば)内部ブローカー通信の仕組みを変更するために、server.properties内のsasl.mechanism.inter.broker.protocolを新しい仕組みに設定し、再びクラスタを逐次的にバウンスします。
- (必要であれば)古い仕組みを削除するために、古い仕組みをserver.properties内のsasl.enabled.mechanismsから削除し、JAAS設定ファイルから古い仕組みのためのエントリーを削除します。再び逐次的にクラスタをバウンスします。
移譲トークンを使った認証
移譲トークン ベースの認証は既存のSASL/SSLメソッドを補完するための軽量な認証機構です。移譲トークンはkafkaブローカーとクライアント間の共有秘密鍵です。移譲トークンは2方向SSLが使われる時にKerberos TGT/keytabあるいはキーストアの分散の追加の負荷無しに安全な環境内の利用可能なワーカーへ作業を分散するためのフレームワークの処理を助けるでしょう。詳細はKIP-48 を見てください。
移譲トークンの使用法の一般的なステップは:
- ユーザはSASLあるいはSSLを経由してKafkaクラスタを認証し、移譲トークンを取得します。これはAdminClient APIあるいはkafka-delegation-token.sh スクリプトを使って行うことができます。
- Kafkaクラスタとの認証のために、ユーザは安全に移譲トークンをKafkaクライアントに渡します。
- Token owner/renewer は移譲トークンを renew/expire することができます。
トークンの管理
マスター キー/秘密鍵は移譲トークンを生成および検証するために使われます。これは設定オプションdelegation.token.master.keyを使って提供されます。同じ秘密鍵のキーが全てのブローカーに渡って設定される必要があります。秘密鍵が設定されないか空の文字列に設定された場合、ブローカーは移譲トークン認証を無効にするでしょう。
現在の実装では、トークンの詳細はZookeeperに格納され、Zookeeperがプライベートネットワーク上にあるKafkaインストレーションでの使用に適しています。また、現在のところ、マスター key/secretは server.properties 設定ファイル内に平文として格納されます。これらの設定を将来のKafkaリリースで設定可能にするつもりです。
トークンは現在の寿命と最大の更新可能な寿命を持ちます。デフォルトでは、トークンは各24時間ごとに7日まで更新されなければなりません。これらはdelegation.token.expiry.time.msとdelegation.token.max.lifetime.ms設定オプションを使って設定可能です。
トークンも明示的に取り消すことができます。トークンが期限切れにより更新あるいはトークンが最大生存時間を超えた場合、全てのブローカーのキャッシュとzookeeperから削除されるでしょう。
移譲トークンの作成
トークンは 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
トークンの認証
移譲トークンの認証は現在のSASL/SCRAM認証機構と抱き合わせです。ここで説明されるようにKafkaクラスタ上でSASL/SCRAM機構を有効にしなければなりません。
Kafkaクライアントの設定:
- 各クライアントについての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";
オプション username と password はクライアントによってトークンidとトークンHMACを設定するために使われます。そして、オプション tokenauth はサーバにトークン認証を示すために使われます。この例では、クライアントはトークンid: tokenID123 を使ってブローカーに接続します。JVM内の異なるクライアントは
sasl.jaas.config
内で詳述される異なるトークンを指定することで異なるトークンを使って接続することができます。別のやり方として、クライアントのためのJAAS設定はここで説明されたブローカーに似てJVMパラメータとして指定することができます。クライアントはKafkaClientという名前のログイン セクションを使います。このオプションはJVMからの全てのクライアント接続のためにただ一人だけのユーザを許可します。
- 各クライアントについてのJAAS設定プロパティを producer.properties あるいは consumer.properties の中で設定します。ログイン モジュールはプロデューサとコンシューマのようなクライアントがどのようにKafkaブローカーに接続することができるかを説明します。以下はトークン認証についてのクライアントのための設定例です:
手動で秘密鍵をローテートする手順:
秘密鍵がローテートされる必要がある場合、再デプロイが必要です。このプロセスの間、既に接続したクライアントは動作し続けるでしょう。しかし古いトークンを持つどのような新しい接続リクエストおよび更新/期限切れのリクエストは失敗するでしょう。手順は以下で与えられます。
- 全ての既存のトークンを期限切れにする。
- ローリング更新によって秘密鍵をローテートする。そして
- 新しいトークンを生成する
将来のKafkaのリリースでこれを自動化するつもりです。
移譲トークンの注意
- 現在のところ、ユーザはそのユーザだけの移譲トークンを作成することだけができます。所有者/更新者はトークンを更新あるいは期限切れにすることができます。所有者/更新者は常にそれらの独自のトークンを表示することができます。他のトークンを表示するには、トークンのリソースに DESCRIBE パーミッションを追加する必要があります。
7.4認証とACL
Kafkaは差し込み可能なオーソライザと、全てのaclを格納するためにzookeeperを使う取り出したままで使えるオーソライザの実装を同梱します。オーソライザはserver.properties内でauthorizer.class.name
を設定することで構成できます。取り出したままで使える実装を有効にするには、以下を使います:
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizerKafkaの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 ポートを閉じるために最後の逐次的なバウンス。
listeners=PLAINTEXT://broker1:9091,SSL://broker1:9092そして、クライアントの設定が新しく開かれた安全なポートを示すように変更して、クライアントを再起動します:
bootstrap.servers = [broker1:9092,...] security.protocol = SSL ...etc2つ目の増加サーバのバウンスで、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 ...etc2つ目のサーバのバウンスはクラスタが前にポート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=SSLZooKeeperはKakfaクラスタとは関係なく安全にすることができます。これを行うステップはセクション7.6.2でカバーされます。
7.6ZooKeeper 認証
7.6.1新しいクラスタ
ブローカー上でZooKeeperを有効にするには、2つの必要なステップがあります:- JAASログインファイルを作成し、上で説明されたように適切なシステムプロパティがそれを指すように設定します
- 各ブローカー内で構成プロパティzookeeper.set.aclをtrueに設定する
7.6.2クラスタの移設
セキュリティをサポートしないバージョンのKafkaを実行しているか、単純にセキュリティを無効にしていて、クラスタを安全にしたい場合、オペレーションへの最小の混乱をもってZooKeeperの認証を有効にするために以下のステップを実行する必要があります:- JAASログインファイルを設定してローリング リスタートを実施します。これはブローカーに認証を可能にします。ローリング リスタートの最後に、ブローカーは厳密なACLを持つznodeを操作することができますが、それらはこれらのACLを持つznodeを作成しないでしょう。
- 今度は設定zookeeper.set.aclをtrueに設定して、パラメータブローカーの2つ目のローリング リスタートを実施します。これはznodeを生成する時に安全なACLを使うことを可能にします
- ZkSecurityMigrator ツールを実行します。ツールを実行するために、このスクリプトがあります: zookeeper.aclをsecureに設定した./bin/zookeeper-security-migration.sh。このツールはznodeのACLを変更する対応する副木を横断します
安全なクラスタ内で認証を止めることもできます。そうするには、以下のステップに従います:
- JAASログインファイルを設定しているブローカーのローリング リスタートを実施します。これはブローカーの認証を有効にしますが、zookeeper.set.aclをfalseに設定します。ローリング リスタートの最後に、ブローカーは安全なACLを持つznodeの生成を停止しますが、まだ認証し全てのznodeを操作することができます。
- ZkSecurityMigrator ツールを実行します。ツールを実行するには、zookeeper.aclをunsecureに設定したこのスクリプト./bin/zookeeper-security-migration.shを実行します。このツールはznodeのACLを変更する対応する副木を横断します
- 今度は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のドキュメントを参照してください: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.field | Kafkaオフセットのためのフィールド名 - シンク コネクタへのみ適用可能。 これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。 | 文字列 | null | medium | |
partition.field | Kafkaパーティションのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。 | 文字列 | null | medium | |
static.field | 静的なデータフィールドのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。 | 文字列 | null | medium | |
static.value | フィールド名が設定された場合、静的なフィールド値。 | 文字列 | null | medium | |
timestamp.field | レコードのタイムスタンプのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。 | 文字列 | null | medium | |
topic.field | Kafkaトピックのためのフィールド名。これを必須フィールドにするには ! を、任意(デフォルト)にするには ? を後ろに付けます。 | 文字列 | null | medium |
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:xyz | medium |
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 | 設定するスキーマ名。 | 文字列 | null | high | |
schema.version | 設定するスキーマのバージョン。 | int | null | high |
org.apache.kafka.connect.transforms.TimestampRouter
レコードのトピック フィールドを元のトピックの値とレコードのタイムスタンプの関数として更新します。トピックフィールドはしばしば宛先のシステム(例えばデータベーステーブルあるいは検索インデックス名)の中の等価なエンティティ名を決定するために使われるため、これは主にシンク コネクタに便利です。名前 | 説明 | 種類 | デフォルト | 有効な値 | 重要性 |
---|---|---|---|---|---|
timestamp.format | java.text.SimpleDateFormat と互換性のあるタイムスタンプのためのフォーマット文字列。 | 文字列 | yyyyMMdd | high | |
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
) のために設計された具体的な変換型を使います。
名前 | 説明 | 種類 | デフォルト | 有効な値 | 重要性 |
---|---|---|---|---|---|
spec | List 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:xyz | high |
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
. 現在のところサポートされるプロトコルは http
と https
です。例えば:
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つの対応する持ち味で提供されます: SourceTask
と SinkTask
。
手持ちの割り当てを使って、各タスク
データのサブセットをKafkaへ、あるいはKafkaからコピーしなければなりません。Kafka コネクトでは、これらの割り当てを一貫性のあるスキーマを持つレコードから成る入力と出力ストリームのセットとして常に構成できる必要があります。このマッピングは時には明白です: ログファイルのセット中の各ファイルは、ファイル内のバイトのオフセットとして格納された同じスキーマとオフセットを使ってレコードを形成する各パースされた行を持つストリームと見なすことができます。他の場合では、このモデルにマップするためにより努力が求められるかもしれません: JDBC コネクタは各テーブルをストリームにマップすることができますが、オフセットはより不明確です。1つの可能なマッピングは、逐次的に新しいデータを返すクエリを生成するためにタイムスタンプのカラムを使い、最後にクエリされたタイムスタンプはオフセットとして使うことができます。
ストリームとレコード
各ストリームはキー-値 レコードの系列でなければなりません。キーと値の両方は複雑な構造を持つかもしれません -- 多くのprimitiveな型が提供されますが、配列、オフジェクト および入れ子の構造も同様に表現されるかもしれません。実行時のデータ形式は特定のシリアライズ化形式を仮定しません; この変換はフレームワークによって内部的に処理されます。
キーと値に加えて、レコード(ソースによって生成され、シンクに配送されるものの両方)は関連するストリームIDとオフセットを持ちます。障害時に不必要な再処理とイベントの複製を避けながら、処理が最後のコミットされたオフセットから再開できるように、処理されたデータのオフセットを定期的にコミットするためにフレームワークによってそれらが使われます。
動的なコネクタ
全てのジョブが静的ではないため、コネクタ
の実装は再設定が必要になるかもしれない全ての変更のために外部システムを監視する責任もあります。例えば、JDBCSourceConnector
の例では、Connector
は各Task
にテーブルのセットを割り当てるかもしれません。新しいテーブルが生成される時、設定を更新することで新しいテーブルをTasks
の1つに割り当てることができるように、これを発見する必要があります。再設定を必要とする変更(あるいはTasks
の数の変更)に気づいた時、それはフレームワークに通知し、フレームワークは全ての対応するTasks
を更新します。
簡単なコネクタの開発
コネクタの開発は2つのインタフェースの実装のみを必要とします。Connector
と Task
。file
パッケージ内に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を提供します: commit
と commitRecord
。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
を実装する方法を説明しました。SourceConnector
と SinkConnector
とは異なり、SourceTask
はpullインタフェースを使用しSinkTask
はpushインタフェースを使用するため、SourceTask
と SinkTask
はとても異なるインタフェースを持ちます。両方とも共通のライフサイクル メソッドを共有しますが、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
のセットを受け付け、必要な全ての変換を行い、宛先のシステム内にそれらを格納する実装のほとんどを含む必要があります。このメソッドは返す前にデータが完全に宛先のシステムに書き込まれることを確実にする必要はありません。実際、多くの場合で内部的なバッファリングは便利なため、レコードの全体のバッチは一度に送ることができ、イベントをダウンストリームのデータストアに挿入するオーバーヘッドを減らします。SinkRecords
はSourceRecords
として本質的に同じ情報を含みます: 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つが入力ストリーム内で破棄、例えばもしテーブルがデータベースから削除される場合された時に、変更はタスクにも影響するかもしれません。Task
がConnector
の前に問題に遭遇した場合、これは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つのクラスとやり取りをする必要があるでしょう: Schema
と Struct
。
APIドキュメントは完全な参照を提供しますが、ここでは Schema
と Struct
を生成する簡単な例です:
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ストリームについての詳細はこの 章を読んでください。