ClickHouse をキー・バリュー型ストレージとして使用できますか?
短い答えは 「いいえ」 です。キー・バリュー型ワークロードは、ClickHouse を使用すべきではないケースの代表例のひとつです。結局のところ ClickHouse は OLAP システムであり、キー・バリュー型ストレージには他にも優れたシステムが多数存在します。
とはいえ、キー・バリュー型に近いクエリに ClickHouse を使うことに一定の意味がある状況もあります。典型的には、主なワークロードは分析的な性質を持ち ClickHouse によく適合している一方で、高いリクエストスループットや厳密なレイテンシ要件を必要としないキー・バリュー型パターンを用いる副次的な処理が存在する、低予算のプロダクトなどです。もし無制限の予算があれば、この副次的なワークロード向けに別途キー・バリュー型データベースを導入するところですが、現実にはストレージシステムをもう 1 つ運用するための追加コスト(監視、バックアップなど)が発生し、これを避けたい場合があります。
推奨に反して ClickHouse に対してキー・バリュー型に近いクエリを実行することにした場合、次のようなヒントがあります。
- ClickHouse でポイントクエリが高コストになる主な理由は、MergeTree テーブルエンジンファミリーのスパースなプライマリインデックスにあります。このインデックスは各行を直接指すことはできず、N 行ごとにしかポインタを持てないため、目的の行を得るには近傍の N 行ごとの位置からスキャンしていく必要があり、その過程で余分なデータを読み取ることになります。キー・バリュー型のシナリオでは、
index_granularity設定で N の値を小さくすることが有用な場合があります。 - ClickHouse では各カラムが別々のファイル群として保存されるため、1 行を組み立てるにはそれぞれのファイルを読み出す必要があります。ファイル数はカラム数に比例して増加するため、キー・バリュー型シナリオでは多くのカラムの使用を避け、すべてのペイロードを JSON や Protobuf など、何らかのシリアライゼーション形式でエンコードした単一の
Stringカラムに格納することを検討する価値があります。 - 通常の
MergeTreeテーブルの代わりに Join テーブルエンジンと、データ取得に joinGet 関数を使用する代替アプローチもあります。これによりクエリ性能が向上する可能性がありますが、使い勝手や信頼性の面でいくつかの問題が生じる場合があります。利用例はこちらを参照してください。