6.ClickHouseのコピーとシャーディング

10.レプリカとフラグメント

10.1レプリカとシャード

1.データレベルの区別:

CKクラスターにhost1とhost2の2つのノードがあると想定します。両方のノードには、同じ構造のテーブルがあります。

現時点で、host1のテーブルのデータがhost2のテーブルのデータと異なる場合、それは断片化です。

このとき、host1のテーブルのデータとhost2のテーブルのデータが同じであれば、それはコピーです。

したがって、テーブルエンジンの違いは別として、純粋なデータの観点からは、レプリカとシャードの間に細い線しかない場合があります。

2.機能レベルの差別化:

コピー:データの損失を防ぎ、データストレージの冗長性を高めます。

断片化:データの水平方向のセグメンテーションを実現し、データの書き込みと読み取りのパフォーマンスを向上させます。

[外部リンク画像の転送に失敗しました。ソースサイトにヒル防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-npRtuHnD-1610932819138)(C:\ Users \ 12942 \ AppData \ Roaming \ Typora \ typora-user-images \ image-20210112074852130.png)]

10.2データコピー

プレフィックスReplicateはMergeTreeの前面に追加され、新しいバリアントエンジン、つまり、Replicate-MergeTreeレプリケートテーブルに組み合わせることができます。

[外部リンクの画像転送に失敗しました。ソースサイトにアンチホットリンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-kKDM0L1X-1610932819138)(C:\ Users \ 12942 \ AppData \ Roaming \ Typora \ typora-user-images \ image-20210112075924142.png)]

ReplicatedMergeTreeレプリケーションテーブルシリーズエンジンを使用することによってのみ、レプリケーション機能を適用できます。つまり、ReplicateMergeTreeを使用するデータテーブルはコピーです。

ReplicatedMergeTreeはMergeTreeの派生エンジンであり、MergeTreeに基づいて分散コラボレーションの機能を追加します。

プレビュー

MergeTreeでは、データパーティションは作成から完了まで2種類のストレージ領域を通過します。
(1)メモリ:データは最初にメモリバッファに書き込まれます。
(2)ローカルディスク:データはtmp一時ディレクトリパーティションに書き込まれ、すべてが完了すると一時ディレクトリの名前が公式パーティションに変更されます。ReplicatedMergeTreeは、上記に基づいてZooKeeperの一部を追加し、ZooKeeperに一連の監視ノードをさらに作成し、複数のインスタンス間の通信を実現します。通信プロセス全体で、ZooKeeperはテーブルデータの送信を含みません。

コピーの特徴

データコピーの主要な実装キャリアとして、ReplicateMergeTreeは設計においていくつかの注目すべき機能を備えています。
❑ZooKeeperに依存する:INSERTクエリとALTERクエリを実行する場合、ReplicateMergeTreeはZooKeeperの分散コラボレーション機能を使用して、複数のレプリカ間の同期を実現する必要があります。ただし、コピーをクエリする場合、ZooKeeperは必要ありません。これについての詳細は、後で詳しく説明します。
❑テーブルレベルのレプリカ:レプリカはテーブルレベルで定義されるため、各テーブルのレプリカ構成は、レプリカの数やクラスター内のレプリカの配布場所など、実際のニーズに応じてカスタマイズできます。
❑マルチマスター:INSERTクエリとALTERクエリは任意のコピーで実行でき、その効果は同じです。これらの操作は各コピーに分散され、ZooKeeperのコラボレーション機能を使用してローカルで実行されます。
❑ブロックデータブロック:INSERTコマンドを実行してデータを書き込む場合、データはmax_insert_block_sizeのサイズ(デフォルトは1048576行)に応じていくつかのブロックデータブロックに分割されます。したがって、ブロックデータブロックはデータ書き込みの基本単位であり、書き込みの原子性と独自性を備えています。
❑アトミシティ:データが書き込まれると、ブロックブロック内のすべてのデータが正常に書き込まれるか、すべてのデータが失敗します。
❑一意性:ブロックデータブロックを書き込む場合、ハッシュ情報の要約は、現在のブロックデータブロックのデータシーケンス、データ行、およびデータサイズに従って計算および記録されます。その後、書き込まれるブロックデータブロックが以前に書き込まれたブロックデータブロックと同じハッシュダイジェストを持っている場合(ブロックデータブロックのデータシーケンス、データサイズ、およびデータ行が同じである場合)、ブロックデータ無視されます。この設計により、異常な理由によるブロックデータブロックの繰り返し書き込みを防ぐことができます。これらの特性の説明を単純に見ると、直感的ではない場合があります。それは問題ではありません、それは一連の特定の例で、次に徐々に拡大されます。

ZooKeeperを構成する方法

ClickHouseは、一連のzookeeperタグを使用して、関連する構成を定義します。デフォルトでは、グローバル構成config.xmlで定義できます。ただし、各コピーで使用されるZookeeper構成は通常同じです。複数のノード間で構成ファイルをコピーしやすくするために、構成のこの部分を抽出して別のファイルに保存するのが一般的です。

まず、サーバーの/etc/clickhouse-server/config.dディレクトリにmetrika.xmlという名前の構成ファイルを作成します。

<zookeeper-servers>
  <node index="1">
    <host>10.0.0.31</host>
    <port>2181</port>
  </node>
  <node index="2">
    <host>10.0.0.32</host>
    <port>2181</port>
  </node>
  <node index="3">
    <host>10.0.0.33</host>
    <port>2181</port>
  </node>
</zookeeper-servers>

次に、グローバル構成config.xmlの<include_from>タグを使用して、定義したばかりの構成をインポートします。
そして、ZooKeeper構成の定義を参照します。

<!-- If element has 'incl' attribute, then for it's value will be used corresponding substitution from another file.
     By default, path to file with substitutions is /etc/metrika.xml. It could be changed in config in 'include_from' element.
     Values for substitutions are specified in /yandex/name_of_substitution elements in that file.
  -->
  
  <include_from>/etc/clikhouse-server/config.d/metrika.xml</include_from>

その中で、inclおよびmetrika.xml構成ファイルのノード名は互いに対応している必要があります。この時点で、構成プロセス全体が完了しています。

ClickHouseは、システムテーブルにzookeeperという名前のプロキシテーブルを提供します。このテーブルを通じて、SQLクエリを使用してリモートZooKeeperのデータを読み取ることができます。注意すべき点の1つは、クエリに使用されるSQLステートメントで、クエリのルートパスなどのパス条件を指定する必要があることです。

SELECT * FROM system.zookeeper where path = '/';
SELECT name,value,czxid,mzxid FROM system.zookeeper where path = '/clickhouse';
コピーの定義形式

コピーを使用すると、データの冗長ストレージが増えるため、データ損失のリスクが軽減されます。次に、コピーはマルチマスターアーキテクチャを採用しているため、各コピーインスタンスをデータの読み取りと書き込みの入り口として使用できます。これは間違いなくノードの負荷を償却します。

レプリカを使用する場合、クラスター構成に依存する必要はありません。ReplicatedMergeTreeをZooKeeperと組み合わせると、すべての作業を完了できます。

ReplicatedMergeTreeの定義は次のとおりです。

ENGINE =ReplicatedMergeTree('zk_path','replica_name')

zk_pathは、ZooKeeperで作成されたデータテーブルのパスを指定するために使用されます。パス名はカスタマイズされており、固定ルールはありません。ユーザーは任意のパスを設定できます。それでも、ClickHouseは、参照用にいくつかのカスタム構成テンプレートを提供します。次に例を示します。

/clickhouse/tables/{shard}/table_name

そのうち:
❑/ clickhouse / Tables /は、慣例により確立されたパスの固定プレフィックスであり、データテーブルのルートパスを示します。
❑{shard}はシャード番号を表し、通常は01、02、03などの番号に置き換えられます。データテーブルには複数のシャードを含めることができ、各シャードには独自のコピーがあります。
❑table_nameはデータテーブルの名前を表します。メンテナンスを容易にするために、通常は物理テーブルの名前と同じです(ただし、ClickHouseではパス内のテーブル名が物理テーブル名と同じである必要はありません) );そしてreplica_nameの役割は、作成されたZooKeeperで定義されます。コピーの名前。これは、さまざまなコピーインスタンスを区別するための一意の識別子です。従来の命名方法は、サーバーが配置されているサーバーのドメイン名を使用することです。

zk_pathの場合、同じデータテーブルの同じシャードの異なるコピーで同じパスを定義する必要があります。replica_nameの場合、同じデータテーブルの同じシャードの異なるコピーで異なる名前を定義する必要があります。

ZooKeeperのノード構造

ReplicatedMergeTreeは、レプリカ間のコラボレーションを実現するために、ZooKeeperのイベント監視メカニズムに依存する必要があります。したがって、各ReplicateMergeTreeテーブルの作成中に、ルートパスとしてzk_pathを使用して、Zoo-Keeperでこのテーブルの監視ノードのセットを作成します。さまざまな機能に応じて、監視ノードは大きく次のカテゴリに分類できます。

(1)メタデータ:
❑/ metadata:主キー、パーティションキー、サンプリング式などのメタデータ情報を保存します。
❑/ columns:列名やデータ型などの列フィールド情報を保存します。
❑/ replicas:設定パラメーターのreplica_nameに対応するコピーの名前を保存します。

(2)判断フラグ:
❑/ Leader_election:マスターコピーの選出に使用され、マスターコピーがMERGEおよびMUTATION操作(ALTERDELETEおよびALTERUPDATE を支配します。これらのタスクがマスターコピーで完了した後、ZooKeeperを使用してメッセージイベントを他のコピーに配布します。
❑/ blocks:ブロックデータブロックと対応するpartition_idのハッシュ情報の概要を記録します。ハッシュの概要から、ブロックデータブロックが重複しているかどうかを判断できます。partition_idから、同期する必要のあるデータパーティションを見つけることができます。
❑/ block_numbers:パーティションの書き込み順序に従って同じ順序でpartition_idを記録します。各コピーがローカルでMERGEの場合、同じblock_numbersシーケンスに従います。
❑/ quorum:クォーラムの数を記録します。少なくともクォーラム番号のコピーが正常に書き込まれると、書き込み操作全体が成功したと見なされます。クォーラムの数はinsert_quorumパラメーターによって制御され、デフォルト値は0です。

(3)操作ログ:
❑/ log:通常の操作ログノード(INSERT、MERGE、およびDROP PARTITION)。これは、動作メカニズム全体の中で最も重要な部分であり、コピーの実行に必要なタスク命令を保存します。LogはZooKeeperの永続的なシーケンシャルノードを使用し、各命令の名前の前にはlog-0000000000、log-0000000001などのlog-が付きます。各コピーインスタンスは/ logノードを監視します。新しい命令が追加されると、コピーのそれぞれのタスクキューに命令が追加され、タスクが実行されます。この点に関する実行ロジックは、後でさらに拡張されます。

❑/ mutations:MUTATION操作ログノード。その機能はログログに似ています。ALERTDELETEおよびALERT UPDATEクエリを実行すると、操作命令がこのノードに追加されます。ミューテーションもZooKeeperの永続的なシーケンシャルノードを使用しますが、その名前にはプレフィックスがなく、各命令は0000000000、0000000001などの増加する番号の形式で直接格納されます。この点での実行ロジックも後で拡張されます。

❑/ replicas / {replica_name} / *:各レプリカの各ノードの下にある監視ノードのグループ。レプリカが特定のタスク命令をローカルで実行するようにガイドするために使用されます。より重要なノードは次のとおりです
。❍/ queue:特定の操作タスクを実行するために使用されるタスクキューノード。コピーが/ ​​logまたは/ mutationsノードからの操作命令をリッスンすると、実行タスクがノードに追加され、キューに基づいて実行されます。
❍/ log_pointer:logログポインタノード。最後の実行のログ添え字情報を記録します。たとえば、log_pointer:4は/ log / log-0000000003(0から数えて)に対応します。
❍/ mutation_pointer:前回実行されたミューテーションログの名前を記録するミューテーションログポインタノード。たとえば、mutation_pointer:0000000000は/ mutations / 000000000に対応します。

INSERTのコア実行プロセス

データを書き込むためにReplicateMergeTreeでINSERTクエリを実行する必要がある場合、INSERTコアプロセスに入ります

プレビュー

プレビュー

最初のレプリカインスタンスを作成する最初に
CH5ノードから開始し、CH5ノードで次のステートメントを実行した後、最初のレプリカインスタンスが作成されるとします。

CREATE TABLE replicated_sales_1 (
    id String,
    price Float64,
    create_time DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/replicated_sales_1','ch5.nauu.com')
partition by toYYYYMM(create_time)
ORDER BY id ;

作成プロセス中に、ReplicateMergeTreeは次のようないくつかの初期化操作を実行します。

❑zk_pathに従ってすべてのZooKeeperノードを初期化します。
❑/ replicas /ノードの下に独自のレプリカインスタンスch5.nauu.comを登録します。
❑監視タスクを開始し、/ logログノードを監視します。
❑レプリカの選出に参加し、マスターレプリカを選出します。選出方法は、子ノードを/ Leader_election /に挿入することです。正常に挿入された最初のレプリカはマスターレプリカです。

次に、CH6ノードで次のステートメントを実行して、2番目のコピーインスタンスを作成します。テーブル構造とzk_pathは最初のレプリカと同じである必要があり、replica_nameはCH6のドメイン名に設定する必要があります。

CREATE TABLE replicated_sales_1 (
    id String,
    price Float64,
    create_time DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/01/replicated_sales_1','ch6.nauu.com')
partition by toYYYYMM(create_time)
ORDER BY id ;

作成プロセス中に、2番目のReplicatedMergeTreeは、次のようないくつかの初期化操作も実行し
ます。❑/ replicas /ノードの下に独自のレプリカインスタンスch6.nauu.comを登録します。
❑監視タスクを開始し、/ logログノードを監視します。
❑重複の選出に参加し、マスターの重複を選出します。この例では、CH5コピーがマスターコピーになります。

次に、最初のコピーCH5にデータを書き込んでみます。次のコマンドを実行します。

INSERT INTO TABLE replicated_sales_1 VALUES ('A001',100,'2019-05-10 00:00:00');

上記のコマンドが実行された後、パーティションディレクトリの書き込みはローカルで完了します。

プレビュー

次に、データパーティションのblock_idを/ blocksノードに書き込みます。

プレビュー

block_idは、後続の重複排除操作の基礎として使用されます。この時点で再度INSERTステートメントを実行し、重複データを書き込もうとすると、次のプロンプトが表示されます。

プレビュー

つまり、コピーは、block_idを繰り返して書き込まれるデータを自動的に無視します。
さらに、insert_quorumパラメーターが設定され(デフォルトは0)、insert_quorum> = 2の場合、CH5は、書き込み操作を完了したコピーの数をさらに監視します。書き込まれたコピーの数が以上の場合のみ。 insert_quorum、書き込み全体エントリ操作は成功したと見なされます。

最初のレプリカインスタンスからのプッシュログログ

3つのステップの完了後、実行されたINSERTのコピーは、操作ログを/ logノードにプッシュし続けます。この例では、最初のコピーであるCH5がこの重要なタスクを引き受けます。ログ番号は/ log / log-0000000000であり、LogEntryのコア属性は次のとおりです。

プレビュー

ログの内容から、操作の種類はget downloadであり、ダウンロードが必要なパーティションは201905_0_0_0であることがわかります。他のすべてのコピーは、ログに基づいて同じ順序でコマンドを実行します。

2番目のレプリカインスタンスが
ログログをプルしますCH6レプリカは常に/ logノードの変更を監視します。CH5が/ log / log-0000000000をプッシュすると、CH6はログプルタスクをトリガーし、log_pointerを更新して最新のログを指すようにします。添字:

プレビュー

LogEntryがプルされた後、直接実行されることはありませんが、タスクオブジェクトに変換され、キューに配置されます。

プレビュー

これは、複雑な状況では、多くのLogEntryが同じ期間に継続的に受信されることを考慮すると、キューの形式でタスクをダイジェストする方が合理的な設計であるためです。プルされたLogEntryは間隔であることに注意してください。これは、複数のLogEntryを連続して受信する可能性があるためでもあります。

2番目のコピーインスタンスは、他のコピーへのダウンロード要求を開始します

CH6は/ queueキューに基づいてタスクの実行を開始します。タイプがgetであることがわかると、ReplicateMerge-Treeは、この時点でデータパーティションが他のリモートレプリカに正常に書き込まれたことを認識し、これらのデータを同期する必要があります。

CH6の2番目のコピーインスタンスは、データダウンロードソースとしてリモートコピーの選択を開始します。リモートコピーの選択アルゴリズムは、おおまかに次のとおりです。

(1)/ replicasノードからすべてのレプリカノードを取得します。

(2)これらのコピーをトラバースして、そのうちの1つを選択します。選択したコピーには最大のlog_pointer添え字が必要であり、/ queue子ノードの数は最小です。最大のlog_pointer添え字は、コピーが最も多くのログを実行し、データがより完全である必要があることを意味します。最小の/ queueは、コピーの現在のタスク実行の負担が小さいことを意味します。

この例では、アルゴリズムによって選択されたリモートコピーはCH5です。したがって、CH6のコピーは、パーティション201905_0_0_0をダウンロードすることを期待して、CH5へのHTTP要求を開始します。

プレビュー

最初のダウンロードリクエストが失敗した場合、デフォルトでは、CH6はリクエストを4回試行し、合計5回試行します(max_fetch_partition_retries_countパラメーターで制御されます。デフォルトは5回です)。

CH5のDataPartsExchangeポートサービスは呼び出し要求を受信します。相手の意図を知った後、パラメータに従って応答し、DataPartsExchangサービスの応答に基づいてローカルパーティション201905_0_0_0をCH6に送り返します。

送信パーツ201905_0_0_0

CH6コピーはCH5のパーティションデータを受信した後、最初にそれを一時ディレクトリに書き込みます。

tmp_fetch_201905_0_0_0

すべてのデータを受信したら、ディレクトリの名前を変更します。

プレビュー

この時点で、書き込みプロセス全体が終了します。

ZooKeeperは、INSERT書き込みプロセス中に実質的なデータ送信を実行しないことがわかります。この場合、実装の責任者の原則に基づいて、CH5は最初にパーティションデータをローカルに書き込みます。その後、このコピーは、ログログを送信し、データをダウンロードするように他のコピーに通知する役割も果たします。insert_quorumが設定され、insert_quorum> = 2の場合、書き込まれたコピーの数もコピーによって監視されます。他のコピーがログを受信した後、最適なリモートコピーを選択し、パーティションデータをポイントツーポイントでダウンロードします。

ALTERのコア実行プロセス

ReplicatedMergeTreeでALTER操作を実行してメタデータを変更すると、テーブルフィールドの追加や削除など、ALTER部分のロジックが入力されます。ALTERのコアプロセスを図に示します。

プレビュー

以前のプロセスと比較して、ALTETのプロセスははるかに単純になり、/ logログの配布は実行プロセスに関与しません。プロセス全体は、上から下に時系列で進行し、大きく3つのステップに分けられます。次に、図に示されている番号に従ってプロセス全体を説明します。

共有メタデータの変更
CH6ノードで、列フィールドを追加して、次のステートメントを実行してみてください。

プレビュー

実行後、CH6はZooKeeperの共有メタデータノードを変更します。

プレビュー

データが変更された後、ノードのバージョン番号も同時にアップグレードされます:

プレビュー

同時に、CH6は、すべてのコピーの変更の完了を監視する責任もあります。

プレビュー

共有メタデータの変更を監視し、ローカルの変更を個別に実行します

CH5とCH6の2つのコピーは、共有メタデータの変更を監視します。その後、ローカルメタデータのバージョン番号と共有バージョン番号を比較します。この場合、ローカルバージョン番号が共有バージョン番号よりも小さいことがわかるため、それぞれのローカルで更新操作の実行を開始します。

プレビュー


すべてのコピーが変更れたことを確認しますCH6はすべてのコピーが変更れたことを確認します:

プレビュー

この時点で、ALTERプロセス全体が終了します。
ZooKeeperは、ALTERの実行全体を通じて実質的なデータ送信を実行しないことがわかります。すべてのALTER操作は、最終的に各コピーによってローカルで完了します。実装の責任者の原則に基づいて、この場合、CH6は、共有メタデータの変更と、各コピーの変更の進行状況の監視を担当します。

よりエキサイティングなコンテンツについては、WeChatパブリックアカウントをフォローして入手してください

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_45320660/article/details/112761872