はじめに
configuration編第5弾。Galera Clusterではそれぞれのノードでtransactionが発生し、それを全ノードへ書き込み可能か確認してから書き込みます。この書き込み制御のことをFlow Controlと言うのでした。
今回はこのFlow Controlの管理についてです。
Managing Flow Control — Galera Cluster Documentation
MANAGING FLOW CONTROL
クラスタは変更をグローバルな順番で同期しますが、各ノードでの変更は非同期に行われます。クラスタから離れているノードの適用失敗を防ぐために、Galera ClusterはFlow Controlと呼ばれるフィードバックメカニズムを実装しています。
ノードはグローバルな順に並べられたwrite-setをキューにいれて、データベースにコミットします。大きいキューを受け取った場合、ノードはFlow Controlを初期化します。ノードはキューを受け取っている間レプリケーションを停止します。管理できる量までキューが減ったら、レプリケーションを再開します。
MONITORING FLOW CONTROL
Galera ClusterはFlow Controlの監視にグローバル変数を使います。Flow Controlを数えるステータスは、pauseイベントとpauseの効果を計測するものにわけられます。
SHOW STATUS LIKE 'wsrep_flow_control_%';
これらのステータス変数はノードの現在の状況だけを返却します。結果をグラフ化して活用したいのであれば一定間隔でみていくといいでしょう。例えば、myq_gadgetsを使います。
$ mysql -u monitor -p -e 'FLUSH TABLES WITH READ LOCK;' \ example_database $ myq_status wsrep Wsrep Cluster Node Queue Ops Bytes Flow Conflct time name P cnf # name cmt sta Up Dn Up Dn Up Dn pau snt dst lcf bfa 09:22:17 cluster1 P 3 3 node3 Sync T/T 0 0 0 9 0 13K 0.0 0 101 0 0 09:22:18 cluster1 P 3 3 node3 Sync T/T 0 0 0 18 0 28K 0.0 0 108 0 0 09:22:19 cluster1 P 3 3 node3 Sync T/T 0 4 0 3 0 4.3K 0.0 0 109 0 0 09:22:20 cluster1 P 3 3 node3 Sync T/T 0 18 0 0 0 0 0.0 0 109 0 0 09:22:21 cluster1 P 3 3 node3 Sync T/T 0 27 0 0 0 0 0.0 0 109 0 0 09:22:22 cluster1 P 3 3 node3 Sync T/T 0 29 0 0 0 0 0.9 1 109 0 0 09:22:23 cluster1 P 3 3 node3 Sync T/T 0 29 0 0 0 0 1.0
Queue Dn列の下にslave queueを、FC pauはFlow Control pausesを意味することがわかるだろう。slave queueがある点まで上昇すると、Flow Controlはpauseの値を1に変更する。ノードはslave queueが管理できる値に下がるまでこの値を維持する。
Monitoring for Flow Control Pauses
Flow Conrtrolが動いているとき、FC_Pauseイベントを使ってレプリケーションを停止していることをクラスタに知らせる。Galera Clusterは2つのstatus変数でこれらのイベントを監視する。
- wsrep_flow_control_sent: ローカルノードが最後にstatusを変更してから送信したFlow Control イベントの数
- wsrep_flow_control_recv: ローカルノードによって最後にstatusを変更してから他のノードでpause eventが発生した数(?)
Measuring the Flow Control Pauses
Flow Controlのpauseを追跡することに加えて、Galera Clusterは最後のFLUSH STATUSからreplicationが停止するまでの総量も計測できる。
CONFIGURING FLOW CONTROL
Galera ClusterはFlowControlとレプリケーションレートを扱うための2つのパラメタを提供する。1つめはwrite-set cache、2つめはFlow Controlを停止または開始するポイントである。
Managing the Replication Rate
レプリケーションレートを変更するための3つのパラメタがある。これらは各ノードでwrite-set cacheを管理する。
- gcs.recv_q_hard_limit: これはwrite-set cache sizeの最大値である。パフォーマンスが発揮できる範囲のRAM、swapサイズのの合計に依存する。
デフォルトは、32bitシステムではSSIZE_MAXから2 GBを引いた値である。64bitシステムでは制限はない。
nodeがこの制限を超えて、gcs.max_throttleが0でない場合、nodeはout-of-memoryエラーでダウンする。gcs.mx_throttleが0にセットしてあれば、クラスタのレプリケーションは停止する。
デフォルト値は0.25である。
- gcs.recv_q_soft_limit: これはノードがレプリケーションレートの平均を見積もるものである。gcs.recv_q_hard_limitの一部分となる。レプリケーションレートがsoft limitを超えると、ノードは一定区間の平均レプリケーション例とを計算する。その後、ノードはレプリケーションレートを、cache sizeに比例して落としていく。これは平均のレプリケーションレートがgcs.max_throttleの値に到達しないようにするためである。
デフォルト値は0.25である。
write-set cacheはstate transferが完了するために、gcs.recv_q_soft_limitと時間経過とともに大きくなる。
Managing Flow Control
ノードがFlow Controlをトリガーとして決定されるパラメタである。Flow Controlとレプリケーションの再開が動くべきでないときに決定される。
- gcs.fc_limit: このパラメタはFlow Controlが作動する点を決定する。slave queueがこの制限を超えた場合、ノードはレプリケーションを停止する。
マルチマスタ設定ではこの制限を低くすることが重要である。証明が衝突する確率はslave queueの長さに比例する。マスタースレーブ設定では、Flow Controlが間に入ることを減らせるようにできるだけ高い値を使うことができる。
デフォルトは1.6。
- gcs.fc_factor: このパラメタはノードがFlow Controlを停止するときに決められる値。slave queueがgcs.fc_limitより低いと、fcs.fc_factorのレプリケーションが再開する。(?)
デフォルトは0.5。
マルチマスタの場合、できるだけslave queueは小さく保つことが重要である一方で、マスタ-スレーブの場合はそこまで気にする必要はない。アプリケーションやハードウェアに依存しするが、ノードは瞬間的に1kものwrite-setを適用することができる。slave queueの長さはmaster-slaveのフェールオーバーには影響しない。
注意:警告:クラスタはそれぞれが日同期にトランザクションを行います。ノードはどのぐらいの量のレプリケーションデータがあるか予期することができません。このため、Flow Controlは常に反応するのです。これは、ノードが各種制限を超えた場合のみ動作します。これらの制限を超えることを妨げることはできませんし、こえた場合に、どれほど超えるかを保証することもできません。ノードに以下の設定をするとしましょう。
gcs.recv_q_hard_limit=100Mb
このノードは1Gbのwrite-setによって制限を超えてしまいます。
おわりに
Flow Controlは書き込み量が多すぎたときに、slave-queueにたまったwrite-setの書き込みに集中させ、同期を中止するなど、書き込み流量をコントロールする仕組みでした。