Skip to content

EKS 上の ClickHouse 測定済みベンチマーククイズ ​

  1. ベンチマークでは、1 時間分の namespace + timestamp 範囲を数えるクエリ(Q1)が、1 億行のテーブルに対して 4ms で完了しました。主な理由は何ですか?
    • A) 結果がすでにクエリーキャッシュに保存されていた
    • B) PARTITION BY (day) と ORDER BY (namespace, timestamp) による枝刈りで、1 億行のうち 16,385 行だけが読み込まれた
    • C) gp3 ボリュームの 3,000 IOPS で十分だった
    • D) LowCardinality 型によって比較がベクトル化された
解答を表示

解答: B) PARTITION BY (day) と ORDER BY (namespace, timestamp) による枝刈りで、1 億行のうち 16,385 行だけが読み込まれた

解説: クエリ条件がパーティションキー(日単位)とソートキー(namespace、timestamp)に一致すると、ClickHouse はプライマリーインデックスを使って granule 単位で枝刈りします。このベンチマークでは 59,916 行を数えましたが、読み込んだのは 16,385 行(0.016%)だけです。プライマリーキーの範囲に完全に含まれる granule はインデックスから数えられ(ClickHouse 24.6 以降の最適化)、範囲の端にある部分的な granule だけが展開されます。ClickHouse の速度の大部分は、この「読み込まない」設計によるものです。

  1. 列ごとの圧縮結果では、trace_id は 1.0×(圧縮できない)でしたが、namespace は約 201×に圧縮されました。この差の理由は何ですか?
    • A) trace_id 列だけに圧縮コーデックが設定されていなかった
    • B) namespace の文字列が短い
    • C) この実行では trace_id に繰り返しパターンがほとんどなく、LZ4 でほぼ圧縮されなかった。一方、namespace はカーディナリティが低く、最初の ORDER BY キーなので、同じ値が長く連続する
    • D) namespace だけに個別の辞書ファイルがある
解答を表示

解答: C) この実行では trace_id に繰り返しパターンがほとんどなく、LZ4 でほぼ圧縮されなかった。一方、namespace はカーディナリティが低く、最初の ORDER BY キーなので、同じ値が長く連続する

解説: この LZ4 の結果では、生データ約 3.07 GiB が圧縮後に 3.08 GiB でした。16 進数は 1 バイトあたり 4 ビットの情報しか持たないため、別のコーデックやバイナリ表現ならさらに削減できる可能性があります。namespace の異なる値は 10 個だけで、最初のソートキーでもあるため、同じ値が連続して保存されます。95.72 MiB が 488.63 KiB に縮小されました(201×)。ログスキーマでは「ID をどのように保存するか」がストレージコストを左右する最大の要因である理由です。

  1. 測定された LZ4(既定)と ZSTD(3) の比較に合致する説明はどれですか?
    • A) ZSTD(3) はストレージとスキャン速度の両方で優れていた
    • B) ZSTD(3) はストレージ使用量が 47% 少なかったが、CPU バウンドの全件スキャンは LZ4 より約 1.9 倍遅かった
    • C) コーデック間のストレージ使用量の差は 5% 以内だった
    • D) LZ4 はディスク上では小さかったが、スキャンは遅かった
解答を表示

解答: B) ZSTD(3) はストレージ使用量が 47% 少なかったが、CPU バウンドの全件スキャンは LZ4 より約 1.9 倍遅かった

解説: 測定値は LZ4 が 7.82 GiB(1.97×)、ZSTD(3) が 4.16 GiB(3.7×)で、ストレージ使用量は 47% 減りました。一方、ウォーム状態の LIKE '%timeout%' 全件スキャンは 2.63 秒から 4.9 秒に遅くなりました。最近のパーティションには LZ4 を使い、TTL によって ZSTD に再圧縮する方法もありますが、実データと CPU/I/O のバランスに照らして検証してください。

  1. LIKE '%timeout%' の全件スキャン(Q3)は、ページキャッシュを回避すると 31.5 秒かかりました。この数値はどのボトルネックを示唆しますか?
    • A) ClickHouse の文字列検索アルゴリズムが非効率である
    • B) 圧縮後の約 4 GiB の message 列を 31.5 秒で読み込むと約 130 MiB/s になる。ボリューム/インスタンスの EBS スループット制約と整合するが、唯一のボトルネックだと特定するには不十分である
    • C) m5.xlarge の 4 vCPU が飽和した
    • D) EBS CSI ドライバーのオーバーヘッドが支配的だった
解答を表示

解答: B) 圧縮後の約 4 GiB の message 列を 31.5 秒で読み込むと約 130 MiB/s になる。ボリューム/インスタンスの EBS スループット制約と整合するが、唯一のボトルネックだと特定するには不十分である

解説: 同じクエリをページキャッシュから処理した場合は 2.63 秒で完了しました(CPU バウンドで約 3,800 万行/秒)。直接ディスクを読む際に 12 倍遅くなったことは、全件スキャンの性能がデータベースの特性だけでなく、ボリュームのスループット設定にも左右され得るという測定上の証拠です。gp3 のスループットは追加料金で最大 2,000 MiB/s まで設定できます(到達には少なくとも 8,000 IOPS も必要です)。ただし、この m5.xlarge では、インスタンスの約 137 MiB/s のベースラインとバースト状態も確認してください。継続的な需要に備えて、ノードとボリュームの容量を併せて見直してください。

  1. bloom filter の skip index を追加すると、測定上、trace_id のポイント検索(Q5)はどう変化しましたか?
    • A) 検索時間は 1.13 s → 0.036 s(31 倍)、読み込み行数は 1 億 → 108 万(98.9% をスキップ)、インデックスサイズはテーブルの約 1.5%
    • B) 検索時間は変わらず、メモリ使用量だけが減った
    • C) 検索時間は半分になり、インデックスがテーブルサイズの 30% を占めた
    • D) ORDER BY キーの変更と同じ効果があり、ストレージも縮小した
解答を表示

解答: A) 検索時間は 1.13 s → 0.036 s(31 倍)、読み込み行数は 1 億 → 108 万(98.9% をスキップ)、インデックスサイズはテーブルの約 1.5%

解説:bloom_filter(0.01) GRANULARITY 4 の skip index では、メンバーシップ判定に偽陰性はありません。陰性ならグループをスキップでき、陽性は偽陽性の可能性があり、その場合は追加読み込みが必要です。読み込んだデータは 3.82 GiB から 42.6 MiB に減りました。インデックス自体は 119.7 MiB(テーブルの 1.5%)で、MATERIALIZE には約 20 秒かかりました。

  1. ベンチマークの取り込み値(約 94 万行/秒)には、どのような注意点を付けるべきですか?
    • A) 3 つのレプリカを使って測定した
    • B) サーバー内の INSERT…SELECT で測定したため、外部からのネットワーク転送/解析を含む取り込みスループットを直接測定したものではない
    • C) メモリにだけ書き込み、ディスクには一切書き込まなかった
    • D) 測定中は圧縮を無効にしていた
解答を表示

解答: B) サーバー内の INSERT…SELECT で測定したため、外部からのネットワーク転送/解析を含む取り込みスループットを直接測定したものではない

解説: 行はサーバー内で生成され、直接挿入されています。外部クライアントが TSV/Native データを送信する場合より有利な条件です。ソート、圧縮、ディスク書き込みはすべて計測に含まれますが、データ生成の CPU 負荷も含まれるため、この数値が外部取り込みの理論上の上限というわけではありません。想定するクライアント、バッチサイズ、並行数、形式を別途測定してください。

  1. Q4(namespace ごとの duration p50/p99)は、1 億行すべてをスキャンするのにウォーム状態では約 1 秒で完了しました。これを可能にした特性はどれですか?
    • A) マテリアライズドビューで結果が事前計算されていた
    • B) 列指向ストレージにより、テーブル全体の 7.8 GiB ではなく、duration_ms(289 MiB)と namespace(0.5 MiB)だけを読み込んだ
    • C) quantile 関数はディスク上の 8,192 行だけ読み、残りの行は処理しない
    • D) パーティション枝刈りによって 1 日分のデータだけが対象になった
解答を表示

解答: B) 列指向ストレージにより、テーブル全体の 7.8 GiB ではなく、duration_ms(289 MiB)と namespace(0.5 MiB)だけを読み込んだ

解説: 行指向データベースでは、このクエリのために行全体を読み取る必要がありますが、列指向エンジンでは集計に必要な列だけを読み取ります。時間範囲全体をスキャンしているため、パーティション枝刈りはありません(D は誤りです)。quantile はすべての入力行を処理しながら、近似のために最大 8,192 サンプルのリザーバーを使います。サンプリングしても、入力列のスキャンは省略されません。正確な値が必要な場合は、quantileExact を別途評価してください。

  1. このガイドブックの判断基準では、マネージドサービスではなく EKS 上で ClickHouse をセルフホストするのが特に妥当なのはどのような場合ですか?
    • A) プラットフォームチームもデータベース運用の経験もない
    • B) 標準的なマネージドサービスで十分であり、テナントが 1 つだけである
    • C) マネージドサービスの選択肢が限られているか、費用が大幅に高く、プラットフォームチームがバックアップ/復元のリハーサルを含む Operator ベースの運用を担える
    • D) データが小さい(100 GiB 未満)
解答を表示

解答: C) マネージドサービスの選択肢が限られているか、費用が大幅に高く、プラットフォームチームがバックアップ/復元のリハーサルを含む Operator ベースの運用を担える

解説: これはベンチマーク記事自体ではなく、Database セクションの概要にあるマネージド/セルフホストの判断基準です。ClickHouse は Apache-2.0 ライセンスで、成熟したコミュニティ製 Operator(Altinity)があるため、セルフホストが現実的な選択肢になります。その前提として、Operator とそれを運用するチームが必要です。逆に、運用担当者が不足している場合や適切なマネージドサービスがある場合は、マネージドが有利です。素の StatefulSet を運用するチームは、同じライフサイクル管理と復旧の責任を自ら実装する必要があります。

ドキュメントに質問する

Enter で送信、Shift+Enter で改行します。