はじめに
全8回、第5弾です。ようやく半分超えました。
Technical Description — Galera Cluster Documentation
STATE TRANSFERS
クラスタ内の各ノード間でデータを複製するプロセスで、クラスタに同期することでノードを追加することはプロビジョニングとして知られています。Galera Clusterのプロビジョンには2種類の方法があります。
- State Snapshot Transfers(SST): ノード全体のスナップショットが転送される
- Incremental State Transsfers(IST) 失われたデータのみが転送される
STATE SNAPSHOT TRANSFER (SST)
SSTでは、あるノードから別のノードにフルデータを転送することでプロビジョニングされます。新しいノードがクラスタに加入するとき、新しいノードはクラスタにすでに存在しているノードのデータを同期することによってSSTを初期化します。
SSTを行うために、Galera Clusterでは2つの異なる概念的なアプローチを選択できます。
- Logical: この方法はmysqldumpを用います。受信サーバは完全に初期化されていて、転送の前にコネクションを受け入れることが必要です。(訳注:?どういうことだろう?)
これはブロッキングな方法です。Donorノードは転送中はREAD-ONLYになります。State Snapshot Transferは"FLUSH TABLES WITH READ LOCK"をDonorノード上で行われます。
(訳注:テーブルをロックするからREAD ONLYになるんですね。InnoDBだとsingle transactionを使えばいいんでしょうけど)
mysqldumpは遅いSSTの方法です。クラスタ内に負荷を生じてしまいます。
- Physical: この方法はrsync、rsync_wan, xtrabackupなどの実際のデータを直接コピーする方法です。転送の後にサーバの受信が初期化されます。(訳注:ここもLogicalと対比して前と後が違うようだ。クラスタ加入とみなされるのが前か後かってことのような気がしてきた)
この方法はmysqldumpよりは早い一方で、確かな制限があります。サーバのスタートアップでのみそれらが使えます。受信サーバはDonorとほとんど同じコンフィギュレーションが求められます。(例えば、どちらのサーバも同じinnodb_file_per_tableの値を使う必要があります。) (訳注:サーバのスタートアップ、が何をさすかわからないけれど、実データをコピーするので、実データの構造を決定しうるinnodb_file_per_tableを同じ値にしなければならないのは納得)
これらのメソッドの中のいくつか、xtrabackupはdonor上でノン・ブロッキングで実施可能です。それらはスクリプト可能なSSTインターフェースを通じてサポートされます。
注意:一緒に確認すること:各メソッドのSSTでの使われ方はState Snapshot Transfersを参照。(訳注:rsyncはblockingですね!)
confugrationファイルでどのSSTメソッドを使うかセットすることができます。
wsrep_sst_method=rsync_wan
INCREMENTAL STATE TRANSFER (IST)
ISTでは、データ全体を送る代わりに、クラスタはjoinerノードで欠けているトランザクションのみを送ります。
プロビジョニング方法は以下の条件でのみ利用可能です。
- joiner nodeのstate UUIDがグループ内のものと同じであること
- すべての欠けているwrite-setがdonerのwrite-set cacheに存在すること
(訳注:このdonerのwrite-set cacheがgcacheですね)
これらの条件が合致したとき、ノードは欠けたトランザクションのみを転送し、クラスタにjoinerが追いつくまで順番に(トランザクションが)再実行されます。
例えば、クラスタのノードが以下の値を持っていたとします。このノードは状態として以下を読み取ります。
5a76ef62-30ec-11e1-0800-dba504cf2aab:197222
それまで、現在のクラスタはこの状態を持っていたとします。
5a76ef62-30ec-11e1-0800-dba504cf2aab:201913
クラスタのdonorノードはjoinerノードからstate transferリクエストを受信します。そしてwrite-set cacheのシーケンスナンバーである197223を確認します。このシーケンスナンバーでがwrite-set cacheに存在しない場合、State Snapshot Transfer(SST)の準備をはじめます。シーケンスナンバーがwrite-set cacheに存在する場合、donorノードは197223から201913までのコミットをjoinerに送信します。
ISTの利点は劇的にノードのクラスタ加入が速い点です。加えて、donorはノンブロッキングで実行できます。
注意:ISTで最も重要なパラメタはdonorノードのgcache.sizeです。これはwrite-setをキャッシュするシステムメモリ上に割りあてる領域を制御します。このスペースが多ければ、weite-setを保存できる数も多くなります。write-setをより多く格納できれば、ISTにおけるシーケンスナンバーの差分もより大きくなります。 一方で、write-set cacheがデータベースのサイズより大きい場合、ISTはstate snapshotを送るよりは効果は薄くなるでしょう。
Write-set Cache(GCache)
Galera Clusterはwrite-set Cache(あるいはGCache)と呼ばれる特別なキャッシュにwrite-setを保存します。GCacheはwrite-setのためのメモリ割り当てです。主要な目的はRAM上のwrite-setのfootprint(訳注:???)を最小にすることです。Galera Clusterはディスクへのオフロードwrite-setストレージを通じてこれを改善します。(訳注:GCacheはメモリといいつつただのリングバッファ・ファイルだった気がするけれど。。。)
GCacheは3つのタイプのストレージを使います。
永続的なメモリストア:OSのデフォルトのメモリ領域をwrite-setに割り当てます。これは余分なRAMがシステムにある場合に有益です。物理的なメモリサイズが上限になります。デフォルトではdisableです。
リングバッファ・ファイル: cache初期化中に、ディスクへ事前に割りあてます。これはメインのwrite-set格納場所として向けられます。デフォルトでは128MBです。
オンデマンド・ページストア:write-setは必要に応じて、実行時にメモリにマップされたページファイルを割り当てます。デフォルトでは128MBですが、より大きなwrite-setを格納するときはより大きくすることができます。ページサイズの上限は空いてるディスクスペースが上限です。デフォルトではGalera Clusterは使っていないページファイルを削除しますが、ページファイルサイズの合計を上限にすることもできます。すべての格納場所がdisableのとき、少なくともディスク上の1つのページファイルが残ります。
注意:一緒に見ること:write-set cacheの制御をするパラメタについてさらなる情報はGalera Parametersのgcache.*の欄をみてください。
Galera Clusterは上記順番でwrite-setを格納しようとします。まずはじめに、メモリ上の領域を使おうとします。もしwrite-setのために十分な領域がなかった場合、次にring-bufferファイルを使います。でwrite-setの量が利用可能なディスクサイズを超えない限りは、ページへの格納は常に成功します。
デフォルトでは、write-set cacheはプロセスのworking directoryのファイルに割り当てられます。write-sec cacheを別の場所に置きたい場合は、gcache.dirパラメタを使いましょう。
注意:すべてのキャッシュファイルがメモリに割り当てられた場合、write-setキャッシュプロセスは実際よりも多く割り当てられているように見えます
注意:もしgcache.recoverパラメタがyesにセットされている場合、起動時にgcacheを修復しようとします。ノードが他のノードからのISTの受信を続けるためです。noにセットすると、gcacheはノード起動時無効とされ、ノードはSSTでの受信をするでしょう。
(訳注:むしろこのパラメタ、yesじゃないとISTが動かないように見えたけど、本当?)
おわりに
Galera Clusterでもっとも重要だと思われるISTとSSTの2つのメソッドが紹介されました。差分トランザクションのみで他ノードに加入する方式が早く、ドナーノードのブロックもしないため非常に良い選択肢です。
この差分トランザクションを格納するのがgcacheで、実際はメモリ->リングバッファファイル->ページファイルという順番で使われるんですね。リングバッファファイルのみかと思ってました。このサイズが大きければ大きいほどISTでの加入になる確率があがりますが、データベースサイズ以上にする意味はないようです。