Protocols & Binary Serialization

Kafkaパーティション計算キーのバイト列から確認

キーとパーティション総数を指定し、Java互換Murmur2の計算を追跡します。

Kafkaパーティション計算

シリアライズ済みキー

空白や改行もそのまま使います。空のバイト列は有効です。キーが存在しない場合はnullを選んでください。

計算結果

パーティション番号(0始まり)
9
バイト数
5
符号付き32ビットハッシュ
2132663229
符号なし32ビットハッシュ
2132663229
符号ビットを除いた値
2132663229

計算の手順

  1. キーを5バイトに変換。
  2. シード0x9747b28cのMurmur2 → 2132663229。
  3. 2132663229 & 0x7fffffff → 2132663229。
  4. 2132663229 % 12 → パーティション9。

キーの16進バイト列

68 65 6c 6c 6f

計算はこのブラウザー内で完結します。キーを送信・保存せず、Kafkaクラスターにも接続しません。

設定

Java互換のキー付きMurmur2ルーティングを対象にします。明示的な送信先、キーの無視、独自のシリアライザーやパーティショナーでは結果が異なる場合があります。

計算が完了しました。

同じ顧客IDのはずなのに、別のパーティションに届いている。そんなときは表示文字列だけでなく、シリアライズ後の内容を比べる必要があります。Kafkaパーティション計算では、送信先に至る前のハッシュ値まで確認できます。

パーティションキーが整数や構造化データなら、見た目をコピーしても同じバイト列にはなりません。シリアライザーの出力を16進数やBase64で入力すれば、文字列表現の違いを切り分けられます。

Kafkaパーティション計算を使う理由

文字列とバイト列の差を見つける

Kafkaパーティション計算は3種類の入力を同じバイト列に揃えてから計算します。末尾の改行や空白、複数バイトの文字が含まれていても、16進プレビューなら具体的な差を追えます。同じバイト列なら入力形式を変えてもハッシュは一致します。

3つの入力経路が同じバイト列に合流し、同じ結果に進む図。

空のキーとキーなしを区別する

空文字列のUTF-8表現は長さ0のバイト配列です。nullは配列自体が存在しない状態です。前者には固定のハッシュ計算ができますが、後者はプロデューサーの実行状態に依存するため、固定番号を表示しません。

バイトキーは実線で1つの送信先へ進み、キーなしは点線で複数の候補に分かれる図。

実際の送信条件を揃える

01

シリアライズ後の形式を選ぶ

UTF-8では空白と改行も入力の一部です。16進数はASCII空白を挟めますが、0xを付けず完全な2桁単位で指定します。Base64は必要なパディングを付けます。形式変更は再解釈であり、入力の変換ではありません。

02

現在の総数を確認する

初期値12は操作例であり、推奨構成ではありません。番号は0始まりなので、12個なら0から11です。総数が変わるとハッシュが同じでも剰余が変わり、今後の書き込み先が変わる可能性があります。

03

参照値で照合する

テストベクトルからabcやfoobarを読み込むと、公式の符号付きハッシュと比較できます。自動計算は350msの待ち時間後に実行されます。無効にすればCtrl/Cmd + Enterで実行でき、古い結果の出力は防がれます。

計算を構成する値を確認

Kafka固有の固定シード

Murmur2はシード0x9747b28cとリトルエンディアンの4バイト単位を使用します。乗算は32ビットです。符号付きと符号なしは同じビット列の表示方法であり、送信先の計算では0x7fffffffで符号ビットを除きます。絶対値への変換とは異なります。

バイト入力の厳密な検査

標準Base64と16進数は00やffを含む任意のバイト列を扱えます。奇数桁、誤ったパディング、Base64の不正な末尾ビットは拒否します。テキストは大文字小文字やUnicode形式を変更しないため、意図しない補正が入りません。

参照ベクトルと完全なレポート

abc、foobar、21にApache Kafkaの固定参照値を表示します。バイト列は最初の100バイトから100ずつ展開できます。JSONには全バイト、形式、キーの種類、パーティション総数と中間値が含まれます。

対応範囲と計算の前提

すべてのクライアントに共通ではない
実装はJava互換Murmur2のみです。librdkafkaの既定方式は異なることがあります。独自パーティショナー、partitioner.ignore.keys、明示的な送信先はこの式を迂回できます。CRC32やMurmur3、任意シードには対応していません。
nullの送信先は予測しない
nullを選ぶとテキストを保持したまま計算対象から外します。stickyやrandomの動作には実行状態が必要です。バイト列モードで文字としてnullを入力した場合は、4バイトの通常のキーとして扱われます。
シリアライザーを実行しない
Avro、Protobuf、整数のシリアライズやschema registryへの照会は行いません。前後の空白削除やUnicode正規化も行いません。未対応のサロゲートは置換せず拒否するため、必要なら実際のバイト列を指定してください。
上限はブラウザーの処理予算
入力は196608個のUTF-16コード単位、デコード後は65536バイトまでです。総数は1から2147483647の十進整数に限ります。ファイルやURL、バッチの入力はありません。Kafkaブローカーのメッセージ上限を示す値ではありません。
容量や過去のデータは扱わない
必要なパーティション数、ブローカー、コンシューマーやオフセットは算出しません。総数変更によって将来の宛先が変わっても、保存済みのレコードは移動しません。単一キーから分布やパーティション間の順序を保証することもできません。

Kafkaパーティション計算のよくある質問

キーから送信先のパーティションを調べるには?

対象のキー付きルーティングでは、シリアライズ済みバイト列のMurmur2を計算し、符号ビットを除いてから総数で剰余を取ります。abcの符号付きハッシュは479470107で、12パーティションなら番号3です。総数は実際のメタデータと照合してください。

異なるキーが同じパーティションに入ることはありますか?

あります。宛先の数は有限なので、多くのキーが同じ番号を共有します。32ビットハッシュ全体が一致する必要はなく、異なる値でも剰余は一致します。同じパーティションに入ったことだけでは、キーが等しいとは判断できません。

同じキーなのに別のパーティションに送られるのはなぜですか?

バイト列、パーティション総数、クライアントのアルゴリズムを順に比べます。同じ表示文字列でもシリアライズ結果が違う場合があります。明示的な番号やキーを無視する設定も確認してください。コンシューマーのリバランス自体はハッシュ式を変更しません。

Kafkaへの送信にキーは必須ですか?

必須ではありません。キーを使うかどうかは、レコードのグループ化や順序の要件によります。キーなしでも送信できますが、その送信先をこのキー付きハッシュ式だけで決めることはできません。空文字列はキーなしとは別の入力です。

キーを指定しない場合、送信先はどう決まりますか?

クライアントのバージョンと設定、バッチなどの実行状態に依存します。現行のJavaプロデューサーにはsticky動作があり、他のクライアントにも固有の方式があります。このページはnullに固定の番号を割り当てません。

Murmur2のシードは実行ごとに変わりますか?

KafkaのこのMurmur2実装では、シード0x9747b28cを固定して使います。同じバイト列ならハッシュは再現できます。ただし、パーティション総数が変われば剰余が変わり、別のパーティショナーなら別の規則で送信先を選ぶことがあります。

計算や入力判定に問題がありましたか?

実際のキーで照合する

Kafkaパーティション計算にシリアライザーの出力を入力し、中間値を確かめてからプロデューサーの設定と比較してください。