アロケーションプロファイリング
ClickHouseはグローバルアロケータとして jemalloc を使用しています。 Jemallocにはアロケーションサンプリングとプロファイリングのためのツールがいくつか備わっています。
アロケーションプロファイリングをより便利にするために、ClickHouseとKeeperは設定、クエリ設定、SYSTEMコマンド、およびKeeperの4文字コマンド(4LW)を使用してサンプリングを制御することを可能にしています。
また、サンプルはsystem.trace_logテーブルのJemallocSampleタイプに収集することができます。
このガイドはバージョン25.9以降に適用されます。 それ以前のバージョンについては、バージョン25.9以前のアロケーションプロファイリングを確認してください。
サンプリングアロケーション
jemallocでアロケーションをサンプリングしプロファイリングするには、設定jemalloc_enable_global_profilerを有効にした状態でClickHouse/Keeperを起動する必要があります。
jemallocはアロケーションをサンプリングし、情報を内部的に保存します。
また、jemalloc_enable_profiler設定を使用することで、クエリごとにアロケーションを有効にすることもできます。
ClickHouseはアロケーション負荷の大きいアプリケーションであるため、jemallocのサンプリングはパフォーマンスのオーバーヘッドを引き起こす可能性があります。
system.trace_logにおけるjemallocサンプルの保存
すべてのjemallocサンプルを、JemallocSampleタイプとしてsystem.trace_logに保存することができます。
グローバルにこれを有効にするには、設定jemalloc_collect_global_profile_samples_in_trace_logを使用します。
ClickHouseはアロケーション負荷の大きいアプリケーションであるため、system.trace_logへのすべてのサンプルの収集は高負荷を引き起こす可能性があります。
また、jemalloc_collect_profile_samples_in_trace_log設定を使用することで、クエリごとに有効にすることもできます。
system.trace_logを使用したクエリのメモリ使用量分析の例
まず、jemallocプロファイラを有効にしてクエリを実行し、そのサンプルをsystem.trace_logに収集する必要があります:
ClickHouseがjemalloc_enable_global_profilerで起動された場合、jemalloc_enable_profilerを有効にする必要はありません。
jemalloc_collect_global_profile_samples_in_trace_logとjemalloc_collect_profile_samples_in_trace_logについても同様です。
system.trace_logをフラッシュします:
そして、実行したクエリの各時点でのメモリ使用量を取得するためにクエリします:
メモリ使用量が最も高かった時点を見つけることもできます:
その結果を使用して、その時点でのアクティブなアロケーションがどこから発生したかを確認できます:
ヒーププロファイルのフラッシュ
デフォルトでは、ヒーププロファイルファイルは/tmp/jemalloc_clickhouse._pid_._seqnum_.heapに生成されます。ここで、_pid_はClickHouseのPIDで、_seqnum_は現在のヒーププロファイルのグローバルシーケンス番号です。
Keeperの場合、デフォルトファイルは/tmp/jemalloc_keeper._pid_._seqnum_.heapで、同じルールに従います。
現在のプロファイルをフラッシュするには、jemallocに次のコマンドを実行します:
- ClickHouse
- Keeper
フラッシュされたプロファイルの場所が返されます。
prof_prefixオプションを付加したMALLOC_CONF環境変数を追加することで、異なる場所を定義できます。
例えば、ファイル名のプレフィックスをmy_current_profileにして/dataフォルダにプロファイルを生成したい場合、次の環境変数でClickHouse/Keeperを実行します:
生成されたファイルは、プレフィックスPIDとシーケンス番号に追加されます。
ヒーププロファイルの分析
ヒーププロファイルが生成されたら、それを分析する必要があります。
そのために、jemallocのツールである jeprof を使用することができます。これは複数の方法でインストールできます:
- システムのパッケージマネージャを使用
- jemallocリポジトリをクローンし、ルートフォルダから
autogen.shを実行します。これにより、binフォルダ内にjeprofスクリプトが提供されます。
jeprofはスタックトレースを生成するためにaddr2lineを使用し、非常に遅くなる場合があります。
その場合は、ツールの代替実装をインストールすることが推奨されます。
また、llvm-addr2lineも同様に機能します。
jeprofを使用してヒーププロファイルから生成するフォーマットは多くあります。
ツールの使用法やさまざまなオプションについての情報は、jeprof --helpを実行することをお勧めします。
一般的に、jeprofコマンドは次のように使用されます:
2つのプロファイル間でどのアロケーションが発生したかを比較したい場合は、base引数を設定できます:
例
- 各手続きが1行ずつ書かれたテキストファイルを生成したい場合:
- コールグラフを持つPDFファイルを生成したい場合:
ファイアフレームグラフの生成
jeprofはファイアフレームグラフを構築するために圧縮スタックを生成することができます。
--collapsed引数を使用する必要があります:
その後、圧縮スタックを視覚化するために多くの異なるツールを使用できます。
最も人気のあるツールは、FlameGraphで、flamegraph.plというスクリプトを備えています:
もう一つの興味深いツールは、speedscopeで、収集されたスタックをよりインタラクティブに分析できます。
プロファイラに関する追加オプション
jemallocには、プロファイラに関連する多数の異なるオプションがあります。これらはMALLOC_CONF環境変数を変更することで制御できます。
例えば、アロケーションサンプルの間隔はlg_prof_sampleで制御できます。
Nバイトごとにヒーププロファイルをダンプしたい場合はlg_prof_intervalを使用して有効にできます。
オプションの完全なリストについては、jemallocのリファレンスページを確認することをお勧めします。
その他のリソース
ClickHouse/Keeperは、jemalloc関連のメトリクスをさまざまな方法で公開しています。
これらのメトリクスはすべて同期されていないため、値がずれる可能性があることを認識しておくことが重要です。
システムテーブル asynchronous_metrics
システムテーブル jemalloc_bins
異なるサイズクラス(ビン)においてjemallocアロケータを介して行われたメモリアロケーションに関する情報を、すべてのアリーナから集約して含みます。
Prometheus
asynchronous_metricsからのすべてのjemalloc関連メトリクスは、ClickHouseとKeeperの両方でPrometheusエンドポイントを使用して公開されています。
Keeperのjmst 4LWコマンド
Keeperは、基本アロケータ統計を返すjmst 4LWコマンドをサポートしています: