ESができたのに、なぜClickHouseを使い続けるのか——ClickHouseが速い理由を原理からまとめた

CH のいくつかの主要な特徴を理解することで、数千億の企業の ClickHouse リアルタイム処理エンジン アーキテクチャ設計、コア技術設計、および動作メカニズムの全プロセスを理解できます。

1 初期 ClickHouse

1.1 ClickHouseとは

ClickHouseの正式名称は Click Stream、Data WareHouse で、オンライン分析 (OLAP) 用のカラム型データベース管理システム (DBMS) ですこれは、ロシアのローカル検索エンジン会社である Yandex が、独自の Web トラフィック分析製品 Yandex.Metrica のために開発し、その後、現在の ClickHouse に発展しました。

1.2 ClickHouseの長所と短所

  • クリックハウスの利点

ClickHouse は、ROLAP、オンライン リアルタイム クエリ、完全な DBMS 機能のサポート、列型ストレージを備え、データの前処理を必要とせず、バッチ更新をサポートし、非常に完全な SQL サポートと機能を備え、高可用性をサポートし、Hadoop の複雑なエコロジーに依存しません。箱から出してすぐに使用でき、他の多くの機能があります。

1億個のデータセットの場合、ClickHouseの平均応答速度は、Verticaの2.63倍、InfiniDBの17倍、MonetDBの27倍、Hiveの126倍、MySQLの429倍、その10倍です。グリーンプラムの。テスト結果: https://clickhouse.tech/benchmark/dbms/.

ClickHouseには非常に多くの機能と利点がありますが、明らかにいくつかの欠点があります:

  1. 完全なトランザクション サポートはありません。
  2. まばらなインデックスにより、ClickHouse は、きめの細かい、またはキーと値の型のデータ クエリ要件に適していません。
  3. 既存のデータを変更または削除するための高頻度で低遅延の機能の欠如。バッチでデータを削除または変更するためにのみ使用できます。
  4. 結合操作が苦手で、構文が特殊です。
  5. 並列処理メカニズムにより、1 つのクエリでも CPU リソースの半分を使用するため、高い同時実行性はサポートされていません。

1.3 誰が ClickHouse を使用しているか

ClickHouse は、ビジネス インテリジェンスの分野 (つまり、BI 分野と呼ばれるもの) に非常に適しています。さらに、広告トラフィック、Web、アプリ トラフィック、電気通信、金融、電子商取引、情報セキュリティでも広く使用できます。 、オンラインゲーム、モノのインターネット、その他多くの分野。

ClickHouse は、主にデータ分析 (OLAP) の分野で使用され、近年大きな注目を集めているオープンソースのカラムナ データベースです。現在、国内コミュニティは熱く、さまざまな主要メーカーが大規模な使用をフォローアップしています。

  1. Toutiao は内部で ClickHouse を使用してユーザーの行動を分析します. 内部には何千もの ClickHouse ノードがあり、単一のクラスターには最大 1200 ノードがあります. 総データ量は数十 PB であり、生データの毎日の増加は約 300 TB です.
  2. Tencent は社内で ClickHouse を使用してゲーム データを分析し、そのための監視運用および保守システムの完全なセットを確立しています。
  3. Ctrip の内部アクセス トライアルは 2018 年 7 月に開始され、現在、ビジネスの 80% が ClickHouse で実行されています。毎日、10 億を超えるデータが増加し、100 万近くのクエリ リクエストが行われています。
  4. Kuaishou も社内で ClickHouse を使用しています. 合計ストレージは約 10PB で、毎日 200TB が追加されています. クエリの 90% は 3S 未満です.

3 データ エンジン

ClickHouse は、ライブラリとテーブルの概念も持つ OLAP 分析データベースであり、ライブラリとテーブルの両方が異なるタイプのエンジンを提供するため、ClickHouse の基になるエンジンは、データベース エンジンテーブル エンジンの 2 つのタイプに分けることができます

3.1 ライブラリ エンジン

ClickHouse は、ライブラリ作成時のライブラリ エンジンの指定をサポートしており、現在、Ordinary、Dictionary、Memory、Lazy、MySQL の 5 つのタイプをサポートしています。このうち、Ordinary はデフォルトのライブラリ エンジンであり、このタイプ ライブラリ エンジンの下では、任意のタイプのテーブル エンジンを使用できます。

  • 通常のエンジン: 通常のデータベースを作成するためにデータベース エンジンを指定しない場合の既定のエンジン。

  • ディクショナリ エンジン: このデータベースは、すべてのデータ ディクショナリのテーブルを自動的に作成します。

  • メモリ エンジン: すべてのデータはメモリにのみ保存され、サービスの再起動後にデータが消えます. このデータベース エンジンは、メモリ エンジン テーブルのみを作成できます。

  • MySQL エンジン: エンジンを変更すると、リモート MySQL のデータが自動的に取得され、ライブラリの下に MySQL テーブル エンジンのデータ テーブルが作成されます。

  • Lazy delay engine : 最新のアクセスからの時間expiration_time_in_seconds間隔ます。ログ エンジン テーブルにのみ適用されます。

3.2 テーブルエンジン

テーブル エンジンは、ライブラリ エンジンと比較して、ClickHouse でより中心的な役割を果たします. データがどのように格納され、CH で読み取られるか、同時読み取りと書き込み、Idex をサポートするかどうかなどを直接決定します。

詳細については、公式 Web サイトを参照してください: https://clickhouse.tech/docs/zh/engines/table-engines/

ClickHouse のテーブル エンジンは、それぞれ独自の目的を持つ 4 つのシリーズ (Log、MergeTree、Integration、Special) で約 28 のテーブル エンジンを提供します。たとえば、Log シリーズは小さなテーブル データの分析に使用され、MergeTree シリーズは大量のデータ ボリュームの分析に使用され、Integration シリーズは主に外部データの統合に使用されます。Log、Special、および Integration シリーズのテーブル エンジンは、比較的限定されたアプリケーション シナリオ、単純な機能、および専用アプリケーションを備えています.MergeTree シリーズのテーブル エンジンは、2 つの特別なテーブル エンジン (Replicated、Distributed) と直交して、さまざまな MergeTree を形成します。さまざまな機能のテーブル エンジン。

3.3 マージツリー エンジン

The MergeTree series is the official main storage engine of ClickHouse, which supports most all core functions. このシリーズで一般的に使用されるテーブル エンジンは、MergeTree、ReplacingMergeTree、CollapsingMergeTree、VersionedCollapsingMergeTree、SummingMergeTree、AggregatingMergeTree などです。

MergeTree の機能について

ネイティブの MergeTree テーブル エンジンは、主に大規模なデータ分析に使用され、データのパーティショニング、格納順序、主キー インデックス、スパース インデックス、データ TTL などをサポートします。MergeTree はすべての ClickHouse SQL 構文をサポートしますが、一部の関数は MySQL と一貫性がありません。たとえば、MergeTree の主キーは重複排除に使用されません。

MergeTree の同じ主キーが重複排除できないという問題を解決するために、ClickHouse は重複排除のための ReplacingMergeTree エンジンを提供します。ReplaceingMergeTree は、データが最終的に重複排除されることを保証しますが、クエリ プロセス中に主キーが繰り返されないことを保証することはできません。同じ主キーを持つデータが異なるノードにシャードされる可能性があるため、圧縮は 1 つのノードでしか実行できず、最適化のタイミングも不確実です。

削除のシナリオを解決するために、CollapsingMergeTree エンジンは、テーブル作成ステートメントでマーカー列の記号 (挿入時に 1、削除時に -1) を指定する必要があります。つまり、削除します。ReplacingMergeTree の制限を削除します。

CollapsingMergeTree が順不同で記述されると正常に折り畳めない問題を解決するために、VersionedCollapsingMergeTree テーブル エンジンは、テーブル作成ステートメントに Version の列を追加します。これは、ステータス行とキャンセルの対応関係を記録するために使用されます。乱れた場合の行。同じ主キー、同じバージョン、反対の符号を持つ行は、圧縮中に削除されます。

集計シナリオを解決するために、ClickHouse は SummingMergeTree による主キー列の事前集計をサポートしています。バックグラウンドでの圧縮中に、同じ主キーを持つ複数の行が合計され、1 行のデータに置き換えられます。これにより、ストレージ スペースの使用量が大幅に削減され、集計コンピューティングのパフォーマンスが向上します。同様に、AggregatingMergeTree を使用して平均値を事前に集計します。

MergeTree テーブル作成構文

CREATE TABLE [IF NOT EXISTS] [db_name.]table_name ( name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr], name2 [type] [DEFAUErEMAMLERLALLIZED|ALIAS expr], 省略...
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, 省略...]

いくつかの重要なオプション:

名前 必要 例証する
パーティション パーティションキー 番号 テーブル データを分割する基準を指定します。分割キーは、単一列フィールドまたは複数列フィールドにすることができ、列式もサポートされます。パーティション フィールドが実装されていない場合、すべてのデータが 1 つのパーティションに格納されます
オーダーバイ ソートキー はい これは、データ セグメント内でデータを並べ替える基準を指定するために使用されます。通常は主キーと同じ
主キー 主キー はい 宣言後、主キー フィールドに従って第 1 レベルのインデックスが生成されます。通常は主キーと同じ
設定 インデックスの粒度 番号 デフォルト値は 8192 です。つまり、MergeTree インデックスはデフォルトで 8192 行のデータごとにインデックスを生成するだけです。
サンプルバイ サンプル式 番号 データがサンプリングされる基準を宣言するために使用されます

settingsの重要なパラメータに注意してください。

  • index_granularityデフォルトは 8192 = 1024 * 8 です。変更しないことをお勧めします
  • index_granularity_bytesデフォルトは 10M で、enable_mixed_granularity_parts で有効にする必要があります
  • enable_mixed_granularity_partsデフォルトでアダプティブ インデックスの粒度を有効にする
  • merge_with_ttl_timeoutデータ TTL 機能を提供します。

MergeTree の主キー インデックスは疎インデックス (データの一部がインデックスを作成する) であることに注意してください各データに対して生成されるインデックスは、密なインデックスです。

4 動作原理

ClickHouse は OLAP シナリオの要件から出発して、新しい高効率の列型ストレージ エンジンのセットをカスタマイズおよび開発し、データ順序付けストレージ、主キー インデックス、スパース インデックス、データ シャーディング、データ パーティショニング、TTL、マスターなどの豊富な機能を実現しました。 -バックアップ レプリケーションなど 一緒に、これらの機能は、ClickHouse の非常に高速な分析パフォーマンスの基盤を提供します。

4.1 データの分割

物理構造の観点から、いわゆるデータ パーティションは、テーブル内のすべてのデータを特定の次元に従って複数のサブフォルダーに分割することです。追加モードで書き込みを行う他のデータベースとは異なり、MergeTree は、データの書き込み (挿入) のバッチごとに新しいパーティション ディレクトリのバッチを生成します後で (書き込み後 10 ~ 15 分、optimize クエリ ステートメントを手動で実行することもできます)、ClickHouse はバックグラウンド タスクを通じて、同じパーティションに属する複数のディレクトリを新しいディレクトリにマージします。既に存在する古いパーティション ディレクトリはすぐには削除されませんが、後でバックグラウンド タスクによって削除されます (既定では 8 分)。

パーティション フォルダの命名規則

パーティションの命名規則: PartitionID_MinBlockNum_MaxBlockNum_Level:

1) partition_id: 2021905、特定のパーティション生成規則は次のとおりです。

1)不指定分区键:如果建表时不指定分区键,则数据默认不分区,所有数据写到一个默认分区 all 里面。

2)使用整型:如果分区键取值属于整型且无法转换为日期类型 YYYVYMMDD 格式,则直接按照该整型的字符形式输出作为分区 ID 的取值。

3)使用日期类型:如果分区键取值属于日期类型,或者是能够转换为 YYYYMMDD 日期格式的整型,则按照分区表达式逻辑格式化后作为分区ID的取值。

4)使用其它类型:如果分区键取值既不属于整型,也不屋于日期类型,如 String、Float 等,则通过 128 位 Hash 算法取其 Hash 值作为分区 ID 的取值。

2) min_block_number: 1、最小ブロック数、MergeTree エンジンは 1 からカウントを開始し、毎回 +1;

3) max block_number: 1、最大ブロック番号、新しく挿入されたデータ、最小数と最大数は一致しています。

4) レベル: 0、これはマージの数として理解できます。新しく挿入されたデータはすべて 0 であり、各マージは +1 です。

分割されたフォルダーのマージ ルール

ここに画像の説明を挿入

パーティションフォルダ内のファイルの意味

(これがマージツリー エンジンの新しいバージョンです。bin と mrk3 のファイルは 1 つだけです。古いバージョンでは、テーブルの各列に独自の bin と mrk2 ファイルがあります)

  • checksums.txt チェックサム ファイル。バイナリ形式で格納されます。残りのさまざまなファイル (primary.idx、count.txt など) のサイズとサイズのハッシュ値が保存され、ファイルの整合性と正確性をすばやく検証するために使用されます。

  • columns.txt 列情報ファイル。プレーン テキスト形式で保存されます。このデータ パーティションの下に列フィールド情報を保存するために使用されます。

  • count.txt カウント ファイル。プレーン テキスト形式で保存されます。現在のデータ パーティション ディレクトリの下にあるデータの合計行数を記録するために使用されます。

  • primary.idx プライマリ インデックス ファイル、プライマリ キー インデックス ファイル。

  • xxx.binデータ・ファイルは圧縮形式で格納されます。デフォルトはLZ4圧縮形式です。特定の列のデータを格納するために使用されます。各列はファイルに対応します。たとえば、日付列はdate.binです。 .

  • The xxx.mrk2 column field mark the file. アダプティブ サイズ インデックス間隔が使用されている場合、マーク ファイルは .mrk2 という名前で、それ以外の場合は .mrk という名前です。

  • セカンダリ インデックスとパーティション キー関連の情報ファイル、ホップ インデックス ファイルなどもあります。

ここでは展開せず、後ほど詳しく紹介します。

4.2 列の保管

OLAP は通常、多数の行と少数の列に対して集計分析を実行するため、列ストレージは基本的に必須のソリューションであり、行ストレージよりも次の利点があります。

  • 分析シナリオでは、多くの場合、多数の行と少数の列を読み取る必要があります行ストレージモードでは、データは行ごとに連続して保存され、すべての列のデータがブロックに保存され、計算に参加しない列はすべてIO中に読み取られ、読み取り操作が大幅に増幅されます. 列ストレージ モードでは、計算に関係する列のみを読み取る必要があるため、IO コストが大幅に削減され、クエリが高速化されます。

  • 同じ列のデータは同じ型に属し、圧縮率が高く、データ圧縮効果が顕著です。多くの場合、列ストレージの圧縮率は最大 10 倍またはそれ以上であるため、多くのストレージ スペースが節約され、ストレージ コストが削減されます。

  • 圧縮率が高いということは、データ サイズが小さいことを意味し、対応するデータをディスクから読み取るのにかかる時間が短くなります。同時に、同じサイズのメモリがより多くのデータを保存できることも意味し、システムキャッシュの効果が向上します。

  • 圧縮アルゴリズムは、さまざまな種類に応じて自由に選択でき、さまざまな列の種類に最適な圧縮アルゴリズムを選択できます。

ここに画像の説明を挿入

4.3 一次索引

PRIMARY KEY を使用して MergeTree の主キーを定義した後、index_granularity間隔 (既定では 8192 行)に従ってデータ テーブルの主インデックスが生成され、primary.idxファイル。第 1 レベルのインデックスは疎なインデックスであり、その利点は、少量のインデックス マークで大量のデータ間隔の位置情報を記録できることです. ClickHouse では、第 1 レベルのインデックスはメモリに常駐しています. 一般に、第 1 レベルのインデックスとタグ ファイルは 1 つずつ配置され、2 つのインデックス タグ間のデータはデータ間隔です. データ ファイルでは、このデータ間隔のすべてのデータが圧縮されたデータ ブロックを生成します.

ここに画像の説明を挿入

もちろん、スパース インデックスには、重複排除されないます。重複排除効果を実現するには、特定のテーブル エンジン ReplacingMergeTree、CollapsingMergeTree、および VersionedCollapsingMergeTree と組み合わせて実装する必要があります。

4.4 二次索引

ClickHouseの二次インデックスはジャンプ インデックスとも呼ばれ、その目的は一次インデックスと同じで、検索の範囲を縮小するためです。ただし、セカンダリ インデックスはデフォルトで閉じられており、粒度はgranularityパラメーター. 開いた後skp_idx_[Column].idxskp_idx_[Column].mrkファイルはパーティション ディレクトリに生成されます。セカンダリ インデックスの生成規則も非常に単純です。データの 1 つおきgranularity * index_granularityにセカンダリ インデックスが生成されます。

テーブルは複数のセカンダリ インデックスの宣言をサポートし、次の複数のタイプをサポートします: minmax (最大および最小)、set (重複排除セット)、ngrambf_v1 (ngram 分詞ブルーム インデックス)、および tokenbf_v1 (句読点分詞ブルーム インデックス)。

  • minmax: index_granularity には、指定された式によって計算された最小値と最大値が格納されます; 要件を満たさないブロックをすばやくスキップし、等価および範囲クエリで IO を削減するのに役立ちます。

  • set(max_rows): インデックスの粒度の単位で、指定された式の個別の値セットを格納します。これは、同等のクエリがブロックにヒットするかどうかを迅速に判断し、IO を削減するために使用されます。

  • ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed): 文字列に対して ngram セグメンテーションを実行した後、ブルーム フィルターを構築します。これにより、equivalent、like、in などのクエリ条件を最適化できます。

  • tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed): ngrambf_v1 と同様に、単語の分割に ngram を使用せず、単語の分割に句読点を使用する点が異なります。

  • Bloom_filter([false_positive]): 指定された列のブルーム フィルターを構築して、equal value、like、in などのクエリ条件の実行を高速化します。

ここに画像の説明を挿入

4.5 データ圧縮

column.bin1列分のデータを保存するClickHouseのデータ保存ファイルです.1列は同じ種類のデータなので圧縮すると便利で効率的です. 圧縮中、圧縮データ ブロックはヘッダー情報圧縮データで構成されます。

  • ヘッダー情報は、1 つの UInt8 (1 バイト) 整数と 2 つの UInt32 (4 バイト) 整数で構成される固定の 9 ビット バイトで表され、それぞれ使用される圧縮アルゴリズムのタイプ、圧縮されたデータのサイズ、および圧縮された以前のデータ サイズ。

  • 圧縮された各データ ブロックのサイズは、圧縮前のデータ バイト サイズに従って 64KB ~ 1MB の範囲内で厳密に制御され、上限と下限は min_compress_block_size (デフォルト 65536=64KB) および max_compress_block_size (デフォルト 1048576=1M) パラメータによって指定されます。

特定の圧縮ルール

  1. 単一バッチ データ サイズ < 64KB: データの単一バッチが 64KB 未満の場合、累積サイズ >= 64KB になるまでデータの次のバッチを取得し続け、次の圧縮データ ブロックを生成します。平均レコードが 8 バイト未満の場合、複数のデータ バッチが 1 つのデータ ブロックに圧縮されます。

  2. データの単一バッチ 64KB <= サイズ <=1MB: データの単一バッチのサイズが 64KB から 1MB の場合、次の圧縮データ ブロックが直接生成されます。

  3. 単一バッチ データ サイズ > 1MB: データの単一バッチが直接 1MB を超える場合、最初に 1MB のサイズに従って切り捨てられ、次の圧縮データ ブロックが生成されます。残りのデータは、上記のルールに従って引き続き実行されます。この時点で、データのバッチが複数の圧縮データ ブロックを生成する場合があります。各レコードの平均サイズが 128 バイトを超える場合、現在のデータのバッチは複数のデータ ブロックに圧縮されます。

ここに画像の説明を挿入

4.6 データのラベル付け

data tag files.binfilesの間には 1 対 1 の対応があり、これはプライマリ インデックスと data の間のマッピングです。つまり、各列フィールド[Column].binファイルには対応する[Column].mrk2データ マーク ファイルがあり、.binファイル。マークされたデータの行は、2 つの整数値のオフセット情報を含むタプルで表されます。これらはそれぞれ、このセグメントのデータ間隔内の対応する .bin 圧縮ファイル内の圧縮データ ブロックの開始オフセットと、圧縮データ ブロックが解凍された後の非圧縮データの開始オフセットを示します。マークされたデータは、メモリに常駐できないという点でプライマリ インデックス データとは異なりますが、LRU 戦略を使用してアクセスを高速化します。

したがって、データ読み取りプロセスは次のとおりです。

  1. まず、第 1 レベルのインデックスに従って、マークされたファイル内の対応するデータ圧縮ブロック情報[Column].binを見つけ、ファイル内の対応する圧縮データ ブロックを見つけ、読み取り、解凍します。
  2. 解凍されたデータ ブロックから、データをindex_granularityの、結果データが見つかるまでクエリを実行します。

5 クエリ処理

データ クエリの本質は、データ範囲を継続的に縮小するプロセスと見なすことができます。最も理想的なケースでは、MergeTree は最初にパーティション インデックス、プライマリ インデックス、およびセカンダリ インデックスを順番に使用して、データ スキャンの範囲を最小限に抑えることができます。次に、データ マーキングの助けを借りて、解凍して計算する必要があるデータの範囲を最小限に抑えます。

ここに画像の説明を挿入

  1. 指定パーティション
  2. 指定フィールド ([Column].bin)
  3. プライマリ インデックス (primary.idx) に従って、マーク ファイル ([Column].mrk2) 内のレコードを検索します。
  4. 対応するフィールドのマーク ファイルをスキャンして、2 つのオフセット情報を取得します。
  5. 最初のオフセット (この.binファイル見つけます。
  6. データをメモリに読み込み、解凍を実行します
  7. 2番目のオフセットに従って、メモリ内の解凍されたデータで対応するデータを見つけます(圧縮データブロックの解凍後のデータのオフセットを見つけます)

もちろん、上記は理想的な状況ですが、クエリがどのインデックス (パーティション、プライマリおよびセカンダリ インデックス) にもヒットしない場合、MergeTree は事前にデータ範囲を縮小することはできません。ただし、ClickHouse は引き続きデータ タグを使用して、マルチスレッドの形式で複数の圧縮データ ブロックを同時に読み取り、クエリ速度を向上させることができます。

参照

なぜClickHouseはとても速いのですか?
クリックハウスの仕組み

おすすめ

転載: blog.csdn.net/adminpd/article/details/128010479