MySQL NDB Cluster のパーティションバランシングについての検証

この記事は最終更新から6年以上経過しています。内容が古くなっている可能性があります。

パーティションバランスとは

MySQL NDB Cluster 7.5より導入された、今までよりも柔軟なパーティショニングを
提供する機能です。

マニュアルでは下記のページで説明されています。

Setting NDB_TABLE Options

目次

MySQL NDB Clusterのパーティションについて

MySQL NDB Clusterでは、追加されたデータは自動的に各データノードの
パーティショニングされた表に格納されます。

デフォルトは主キーによるKEYパーティショニングです。
データは以下の条件で各パーティションへ分配されます。

パーティションはLDMスレッドと密接な関係にあり、パーティション数はLDMスレッド数
によって決定されます。
LDMスレッドとは、データノードのローカルデータを管理するためのスレッドです。

ver7.4 以前では、以下のパーティション方式のみ提供されていました。

  • 各ノードの各LDMスレッドごとに1つのパーティションが作成される。
  • NoOfReplicas(デフォルト2)によってLDMスレッドが担当するパーティションはプライマリレプリカ、バックアップレプリカの2つ。
  • 読み取りはプライマリレプリカを使用。

LDMスレッド数は、ndbmtdをご利用の場合MaxNoOfExecutionThreads、もしくはThreadConfig
パラメータによって決定されます。

詳しくは以下のマニュアルをご確認ください。

MaxNoOfExecutionThreads
ThreadConfig

パーティションバランスを指定したテーブル作成

パーティションバランスはCREATE TABLE時に指定します。

指定するパラメータの命名規則は以下の通りです。

選択可能なパーティションバランスの方式

データノード数 4、レプリカ数 2(つまり2ノードのノードグループが2つ)存在している
ケースを前提として説明します。

FOR_RP_BY_LDM
7.4以前、及びデフォルトで選択される方式です。
各ノードの各LDMスレッドごとに1つのパーティションをプライマリ、バックアップに作成します。
読み取りはプライマリレプリカから実行されます。

FOR_RA_BY_LDM
各ノードの各LDMスレッドごとに1つのパーティションをプライマリ、バックアップに作成します。
いずれかのレプリカから読み取りを行うことができます。
LDMスレッドは読み取りを行うパーティションにつき1スレッドとなるため、パーティション数は
RPに比較して半分となります。

FOR_RP_BY_NODE
ノードごとに1つのパーティションをプライマリ、バックアップに作成します。
読み取りはプライマリレプリカから実行されます。

FOR_RA_BY_NODE
各ノードに単一のパーティションを持ちます。
つまり、各ノードには1つのプライマリレプリカかバックアップレプリカがあり、
自身のプライマリレプリカを持たないノードが発生します。
読み取りは任意のレプリカから行うことができます。

実際に作成してパーティションを確認

config.iniは以下の通りです。

今回、データノード数は4、NoOfReplicasはデフォルトの2であるため、
2ノードずつのノードグループが2つ作成されています。
また、検証のためにLDMスレッドを8スレッドとしています。

パーティショニングの状況は、ndb_descコマンドを使用して確認できます。
FOR_RP_BY_LDMのテーブルから確認してみます。

  • ndb_desc結果

パーティション数と、バランシングのタイプが確認できました。
FOR_RP_BY_LDMは、MySQL NDB Clusterのデフォルトであり、基本的にこの方式を使用すれば問題ありません。
各LDMスレッドに1:1でパーティションが存在するため、今回の設定では8*4=32パーティション存在しています。
各パーティションのデータに均等にアクセスするようなワークロードでは最も各LDMスレッドの負荷が均一です。

ノード1,2が所属するノードグループ1を例に取ると、各ノードのプライマリレプリカは以下のように所属しています。

クエリが実行された際には、実行ノードがプライマリレプリカを持たないパーティションのデータは対向ノードに要求します。

それでは、FOR_RA_BY_LDMにした時はどうでしょうか。

パーティション数が半分になっていますが、バックアップレプリカからも読み取り可能な方式です。

RPの際にはノードグループ1に所属するパーティションが更に2分割されてノード1、2が所有していましたが、ノードグループに所属するノードは自身のノードグループ全体のパーティションを読み取れるようになっています。
ただし、バックアップレプリカに対しても完全な同期が必要となるため、WRITE系の処理のパフォーマンスは落ちます。

LDMスレッドの半数がフリーとなるため、あるパーティションに対する負荷が高まった場合も、他のLDMスレッドが動作することができます。

FOR_RP_BY_NODEとした場合は以下です。

パーティションがノード数と等価になり、1つのパーティションに対して、複数のLDMスレッドが動作できるようになりました。
ただし、パーティション数が減るとレンジスキャンする範囲が広くなってしまい、パフォーマンスの劣化につながる場合もあります。
この方式は、マスタ表のような基本的に少ない行から構成される表で有効です。

FOR_RA_BY_NODEとすると、以下です。

FOR_RA_BY_LDMの場合と同様に、ノードグループ単位でパーティションが作成されました。
用途としては、FOR_RP_BY_NODEの場合と同一ですが、加えてノード間通信を少なくすることができます。

なお、ver7.5.4からは、FOR_RA_BY_LDM_X_2、FOR_RA_BY_LDM_X_3、FOR_RA_BY_LDM_X_4という方式が追加されており、
LDMごとに、方式名の末尾の数値のパーティションを作成する事ができるようになりました。
表のワークロードに合わせて設定を検討するとよいかと思います。

以上となります。

MySQL NDB Clusterのパーティションの理解にお役立て頂ければ幸いです。


 

 

スマートスタイルTECHブログについて

スマートスタイルTECHブログでは、日頃MySQLのサポート業務に従事している有資格者で構成された技術サポートチームがMySQLに関する技術情報を発信しています。データベースのお困りごとはお気軽にご相談下さい。

よかったらシェアしてね!
  • URLをコピーしました!
目次