kafka serde landscape
kafkaのブローカーにおいてはメッセージの中身はバイト列でしかなく、中身の意味の解釈の責務はアプリケーション側にある。なのでkafkaアプリケーション内でプログラムで扱うデータ構造をいかにバイト列にシリアライズするか、という議論が必ず発生する。
結論としてはアプリケーションの要件によるよね、という話になってしまうがこの記事ではいくつかの選択肢と主観による判断の軸をまとめる。認識が間違っている点とかコメントは積極的に投げて欲しい
選択肢
json
text
ユニバーサル
2021年であれば流石にどのプログラミング言語を使っていてもjsonはしゃべれる筈
text + typed
schema registry前提
avro/protocol buffer
binary + typed
schema registry前提
clojure勢
Clojureネイティブな型はサポートされている
edn
clojure native
text
binary
binary
仕事ではこちらを採用している
考慮する軸
アプリケーションで使用している言語との相性
敢えてインピーダンスミスマッチを起こす必要は無い
例えばClojureではマップ (dictionary的な意味) のキーに文字列以外にもkeyword型が広く使われたり (e.g. {:key "value"}) 、あるいはコレクションを使うことができる (e.g. [:foo :bar])が、jsonのオブジェクトのキーは文字列に限定されてしまうのでアプリケーションよりも表現力が落ちる。
もっと深刻な話ではBigIntegerで桁が落ちでお金の計算が合わないとか絶対に防ぐ必要がある
binary vs text
パフォーマンス出すならbinary一択
割とデフォルトのkafkaのメッセージサイズ(1MB)も引っ掛かりがち
typed vs untyped
戦争の火種
typed~=型チェックに通らないとシリアライズ/デシリアライズに失敗する世界
topicにあるデータは綺麗ということがアプリケーションの外側のレイヤーで担保できる
schema registry
typedなserdeはschema registryに依存していがち
運用のオーバーヘッドを無視するべきでは無い
実際に仕事ではschema registryのオーバーヘッドが大きいということでtypedなserdeの採用を見送っている