ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法

ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法

こんにちは、ハブル。

誰かがシステムを悪用した場合 グラファイトウェブ ストレージのパフォーマンスの問題が発生しました ささやきます (IO、消費されたディスク容量) の場合、ClickHouse が代替としてキャストされる可能性は XNUMX になるはずです。このステートメントは、サードパーティの実装がメトリクスを受信するデーモンとしてすでに使用されていることを意味します。 カーボンライター または ゴーカーボン.

ClickHouse は、上記の問題をうまく解決します。たとえば、ウィスパーから 2TiB のデータを転送すると、300GiB に収まります。この比較については詳しく説明しません。このトピックに関する記事はたくさんあります。さらに、最近まで、ClickHouse ストレージはすべてが完璧だったわけではありません。

消費スペースの問題

一見すると、すべてがうまく機能するはずです。続く ドキュメンテーション、メトリクスストレージスキームの構成を作成します(さらに retention)、次に、Graphite-Web 用に選択したバックエンドの推奨に従ってテーブルを作成します。 カーボンクリックハウス+グラファイトクリックハウス または グラファイト、使用されるスタックに応じて異なります。そして…時限爆弾が爆発する。

どちらかを理解するには、挿入がどのように機能するか、および * ファミリーのエンジンのテーブル内のデータのその後のライフパスを知る必要があります。マージツリー ClickHouse (チャートは以下から引用) プレゼンテーション アレクセイ・ザテレピン):

  • 挿入されました блок データ。私たちの場合、到着したのはメトリクスでした。
    ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法
  • このような各ブロックは、ディスクに書き込まれる前にキーに従ってソートされます。 ORDER BYテーブル作成時に指定します。
  • 並べ替えた後、 кусок (part) データがディスクに書き込まれます。
    ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法
  • サーバーはそのような部分が多くならないようにバックグラウンドで監視し、バックグラウンドで起動します。 слияния (merge、以下マージします)。
    ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法
    ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法
  • データがアクティブに流れなくなると、サーバーは自動的にマージの実行を停止します。 партицию (partition)、ただし、次のコマンドを使用してプロセスを手動で開始できます。 OPTIMIZE.
  • パーティションに XNUMX つの部分しか残っていない場合、通常のコマンドを使用してマージを実行することはできません。 OPTIMIZE ... FINAL

したがって、最初のメトリクスが到着します。そして、それらはある程度のスペースを占有します。その後のイベントは、多くの要因に応じて多少異なる場合があります。

  • パーティション化キーは、非常に小さい (XNUMX 日) ことも、非常に大きい (数か月) こともできます。
  • 保持設定は、アクティブ パーティション (メトリックが記録される場所) 内のいくつかの重要なデータ集約しきい値に適合する場合もあれば、適合しない場合もあります。
  • データが大量にある場合、バックグラウンドでのマージにより (最適でないパーティション化キーを選択した場合) 最も初期のチャンクがすでに巨大になっている可能性があり、新しい小さなチャンクとマージされません。

そしてそれはいつも同じ終わり方をします。 ClickHouse のメトリクスが占めるスペースは、次の場合にのみ増加します。

  • 適用しないでください OPTIMIZE ... FINAL 手動または
  • 遅かれ早かれバックグラウンドでマージが開始されるよう、すべてのパーティションに継続的にデータを挿入しないでください。

XNUMX 番目の方法は実装が最も簡単と思われるため、間違っており、最初に試行されました。
私は過去 4 年間、毎日ダミーのメトリクスを送信し、XNUMX 時間ごとに cron を実行する、かなり単純な Python スクリプトを作成しました。
ClickHouse DBMS の操作全体は、このシステムが遅かれ早かれすべてのバックグラウンド作業を実行するという事実に基づいているため、いつになるかはわかりませんが、古い巨大な部分が結合し始める瞬間を待つことができませんでした。新しい小さいもの。強制的な最適化を自動化する方法を探す必要があることが明らかになりました。

ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法

ClickHouse システム テーブルの情報

テーブル構造を見てみましょう システムパーツ。これは、ClickHouse サーバー上のすべてのテーブルの各部分に関する包括的な情報です。特に次の列が含まれます。

  • データベース名 (database);
  • テーブル名 (table);
  • パーティション名とID (partition & partition_id);
  • 作品が作成されたとき(modification_time);
  • ピース内の最小および最大の日付 (分割は日ごとに行われます) (min_date & max_date);

テーブルもあります system.graphite_retentions、次の興味深いフィールドがあります。

  • データベース名 (Tables.database);
  • テーブル名 (Tables.table);
  • 次の集計を適用する必要があるメトリックの経過時間 (age);

だから:

  1. チャンクのテーブルと集計ルールのテーブルがあります。
  2. それらの交差部分を結合して、すべてのテーブル *GraphiteMergeTree を取得します。
  3. 次のようなすべてのパーティションを探しています。
    • XNUMX枚以上
    • または、次の集計ルールを適用する時期が来た、および modification_time この瞬間よりも古い。

具現化

このリクエスト

SELECT
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Самое "старое" правило, которое может быть применено для
    -- партиции, но не в будущем, см (*)
    max(g.age) AS age,
    -- Количество кусков в партиции
    countDistinct(p.name) AS parts,
    -- За самую старшую метрику в партиции принимается 00:00:00 следующего дня
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Когда партиция должна быть оптимизированна
    max_time + age AS rollup_time,
    -- Когда самый старый кусок в партиции был обновлён
    min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
    -- Все правила для всех таблиц *GraphiteMergeTree
    SELECT
        Tables.database AS database,
        Tables.table AS table,
        age
    FROM system.graphite_retentions
    ARRAY JOIN Tables
    GROUP BY
        database,
        table,
        age
) AS g ON
    (p.table = g.table)
    AND (p.database = g.database)
WHERE
    -- Только активные куски
    p.active
    -- (*) И только строки, где правила аггрегации уже должны быть применены
    AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    table,
    partition
HAVING
    -- Только партиции, которые младше момента оптимизации
    (modified_at < rollup_time)
    -- Или с несколькими кусками
    OR (parts > 1)
ORDER BY
    table ASC,
    partition ASC,
    age ASC

マージによってディスク領域が解放される必要がある各 *GraphiteMergeTree テーブル パーティションを返します。残っている唯一のことは、リクエストを使用してそれらをすべて実行することです OPTIMIZE ... FINAL。最終的な実装では、アクティブな記録でパーティションに触れる必要がないという事実も考慮されています。

これはまさにこのプロジェクトが行うことです グラファイト-ch-オプティマイザー。 Yandex.Market の元同僚が本番環境でそれを試しました。その結果を以下に示します。

ClickHouse + Graphite: ディスク容量の消費を大幅に削減する方法

ClickHouse を使用してサーバー上でプログラムを実行すると、デーモン モードで動作し始めます。 XNUMX 時間に XNUMX 回リクエストが実行され、XNUMX 日以上経過した最適化可能な新しいパーティションが出現したかどうかがチェックされます。

私たちの当面の計画は、少なくとも deb パッケージを提供し、可能であれば rpm も提供することです。

代わりに、結論の

過去 9 か月以上にわたり、私は社内にいた InnoGames ClickHouse とグラファイトウェブの交差点をいじくり回して多くの時間を費やしました。これは良い経験であり、その結果、メトリクス リポジトリとして Whisper から ClickHouse に迅速に移行することができました。この記事が、このスタックのさまざまな部分にどのような改善が加えられたか、そして将来何が行われるかについてのシリーズの始まりのようなものになれば幸いです。

リクエストの作成には数リットルのビールと管理者の日数が費やされました。 v0デビル、彼に感謝の意を表したいと思います。そしてこの記事のレビューにも。

github のプロジェクトページ

出所: habr.com

コメントを追加します