はじめに
全8回、第6弾です。
Technical Description — Galera Cluster Documentation
FLOW CONTROL
Galera ClusterはFlow Conrtolと呼ばれるフィードバックするするメカニズムを用いてレプリケーションプロセスを管理している。Flow Controlは必要に応じてレプリケーションを止めたり、再開させたりする。また、トランザクションを適用する際に、他のノードより遅れてしまうことを防ぎます。
HOW FLOW CONTROL WORKS
Galera Clusterはクラスタ上のすべてのノードでトランザクションの順番を保証することによって同期レプリケーションを達成しています。つまり、クラスタ間でのトランザクションの複製は非同期で行われると言えます。
ノードはWrite-setを受信し、グローバルな順番に並べ替えます。ノードがクラスタから受信したが、まだコミットされていないトランザクションは受信したqueueの中で保たれます。
受信したqueueがあるサイズに到達した場合、ノードはFlow Controlを発動します。ノードはレプリケーションを止め、受信したキューに対して処理をはじめます。管理可能なサイズより受信したキューが減ってくれば、またレプリケーションを再開します。
UNDERSTANDING NODE STATES
Galera Clusterは、ノードの状態に依存する、いくつかのFlow Controlの実装方式があります。これによって、仮想的な同期ではなく、一時的な同期と一貫性が保証されます。(訳注:as opposed to logicalが不明。。。)
主に4種類のFlow Controlがあります。
No Flow Control
これはノードがOPENかPRIMARY状態のときに作用します。
ノードはこの状態のとき、クラスタの一部分であることを考慮しません。これらのノードはあらゆるwrite-setをcache、実行、複製することが許されません。
Write-set caching
これはノードがJOINERかDONOR状態のときに作用します。
ノードはこの状態ではwrite-setを適用することはできず、あとで行う必要があります。同期を停止する意外に、ノードがクラスタと同期するための合理的な方法はありません。
同期の割合を制限することは、write-set cacheが設定されたサイズを超えないようにすることで可能になります。write-set cacheは以下のパラメタで制御できます。
- gcs.recv_q_hard_limit: write-set cache sizeの最大
- gcs.max_throttle: クラスタ内でノードが許容できる通常のレプリケーションの割合の最小単位
- gcs.recv_q_soft_limit: ノードのレプリケーション割合の平均
(訳注:replication rateが何をいっているのかいまいちつかみとれず。write-setはgcacheにたまった未適用のトランザクションでしょう。JOINERまたはDONERのときは差分適用をしているので、新しい変更は受け入れず、あとで行うのでしょう。)
Catching Up
これはノードがJOINED状態のときに作用します。
この状態のノードはwrite-setを適用します。Flow Controlはクラスタに追いつこうとします。特に、write-set chacheは大きくならないことを保証します。これより、クラスタ間のレプリケーション率はこの状態のノードがwrite-setを適用する率に制限されます。write-setの適用はトランザクションを処理するより数倍速いので、この状態のノードはクラスタのパフォーマンスにほとんど影響を与えません。
(訳注:write-setがどんな状態かはわからないけど、トランザクションを処理するより数倍速いのはなぜだろう?結局write-setの中身からトランザクション(UPDATEやINSERT)を実行すると思ってた)
ノードがJOINED状態のときにクラスタ性能に影響を及ぼす状況は、ノードのバッファプールが空のときです。
注意:並行して適用することで高速化できます
(訳注:バッファプールはgcacheのことなのか、innodbのbuffer poolではないよね?自分自身のバッファプール=gcacheが空で、DONORのgcacheを全部適用するときの話?だとするとSSTを使いそうだし、やっぱりよくわからないな)
Cluster Sync
これはSYNCED状態のときに作用します。
ノードがこの状態に入った時、Flow Controlはslaveのqueueを最小限にしようとします。以下のパラメタを使ってノードの扱いを制御できます。
- gcs.fc_limit: フロー制御が動作するポイントを決定します
- gcs.fc_factor フロー制御が解除されるポイントを決定します
(訳注:パラメタを見るとlimitは16、factorは0.5がデフォルト値になっていて、write-setの数のようですね。)
CHANGES IN THE NODE STATE
ノードのState-MachineはGalera Clusteの異なるレイヤー上で異なる状態変更を扱います。以下は最上位レイヤーで起こるノードの状態変更です。
Primary Componentに接続します
ノードがstate transferリクエストに成功すると、write-setのcacheがはじまります
ノードはState Snapshot Transferを受信します。すべてのクラスタのデータを持ち、cacheされたwrite-setを適用します。
ノードはFlow Controlにslave queueを結果的に減少させます。
- nodeはクラスタに追いつきます。slave queueは空になり、Flow Controlは空の状態を保ちます。
ノードがwsrep_readyを1にセットします。nodeはトランザクションを受け入れられる状態です。
ノードはstate transferリクエストを受信します。Flow ControlはDONORします。ノードはwrite-setを適用できません。
ノードはstate transferをJOINERノードに送信します。
(訳注:ここでいうslave queueがgcache内の差分のようですね。)
読みやすさのために、特定の遷移は上の図からは省かれている。次の点に注意してください。
- 接続性:クラスタの設定変更イベントはPRIMARYかOPENで送信されます。例えば、ネットワーク分断によって、Primary Componentとの接続が失われた時、SYNCEDのノードはOPENにもm取ります。
- 遷移の消失:joiningノードがstate transferが必要ない場合、ノードの状態はPRIMARYから直接JOINEDに変化します
注意:一緒に読むこと:Flow Controlに関するより詳細な情報はGalera Flow Control in Percona XtraDB Clusterを参照
おわりに
Flow Control、ノードのクラスタ加入に際の状態に応じて、write-setの適用(=FLOW)を制御するもののようですね。
状態ごとにFlow Controlの様子を整理しましょう。
- OPEN/PRIMARY: No Flow Control, write-setのレプリケーションも複製もキャッシュもしない
- JOINER/DONER: Write-set Caching, write-setの適用は行わない。具体的にはノード間でメッセージ交換をし、DONORを選択、ISTかSSTかどちらを適用するか決定するまでがこのフェーズでないかと思います。
- JOINED: Caching Up, クラスタへ無事加入し、他のノードに追いつくためにwrite-setを適用している状態です。
- SYNCED: Cluster Sync, クラスタの一員になり、slave queueと呼ばれる、他ノードとのwirte-set差分はなく、galeraによって配られるwrite-setを順次適用されている状態です。