MySQL道普請便り

第256回MySQL Group ReplicationのFlow Control

MySQL Group Replicationでは、データベースの更新を行うノードを制御するために、Flow Controlという仕組みが提供されています。これは、グループ内の各ノードが他のノードと同期を保つために使用され、遅延が発生しているノードがある場合に、そのノードが追いつくまで他のノードの更新を一時的に低速化させます。

なぜ Flow Controlが必要か

Group Replicationでは、トランザクションはグループの過半数による合意でコミットされます。しかし、ネットワークの遅延やノードの負荷などにより、あるノードが他のノードに比べて遅れている場合があります。たとえば、短時間に大量の更新処理が行われた場合、binary logの伝播やrelay logの適用に時間がかかり、遅延が発生することがあります。このような状況では、遅れているノードが最新のデータを持っていないため、データの一貫性が損なわれる可能性があります。

この進んでいるノードと遅れているノードの差を埋めるために、Flow Controlが導入されています。

Group Replication Flow Control発動判断

Group Replicationでは、group_replication_flow_control_modeがQUOTAになっている状態で、ノード間で遅延が発生していると判断された場合、最新のノードの書き込み速度を低速化することでFlow Controlを実現しています。

ノード間で遅延が発生していると判断する基準は、競合チェック中のトランザクションの数と、各ノードで適用待機中のトランザクションの数を見ることで行われます。具体的には以下のような条件です。

  • COUNT_TRANSACTIONS_IN_QUEUE(競合チェック中のトランザクションの数⁠⁠ > group_replication_flow_control_certifier_threshold
  • COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE(適用待機中のトランザクションの数⁠⁠ > group_replication_flow_control_applier_threshold

この2つの変数はデフォルト値が25,000に設定されています。また、これらはGroup Replicationの実行中に動的に変更することが可能です。

Group Replication Flow Control動作

Flow Controlが発動した場合、完全に書き込みを停止するのではなく、書き込み速度を低速化することで、遅れているノードが追いつくまでの時間を稼ぎます。

各ノードの統計をお互いに共有

COUNT_TRANSACTIONS_IN_QUEUEとCOUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUEなどの値をお互いに確認し、閾値を超えた場合にFlow Controlを発動します。共有の頻度はgroup_replication_flow_control_periodで設定されており、デフォルトでは1秒に設定されています。

書き込み速度の低速化度合いを決定

共有された統計をもとに、新しいトランザクションをcommitできる量を制限します。各メンバーの中で最も処理能力の低いメンバーに合わせて、書き込み速度を低速化します。低速化の度合いはそのメンバーが計測前の1期間(group_replication_flow_control_period)に適応できた件数であれば次の1期間でも適応できるとして、実行可能なトランザクション件数を決定します。

example:
  • group_replication_flow_control_period: 1秒
  • ノードA: 1000tx/秒
  • ノードB: 800tx/秒
  • ノードC: 600tx/秒

ノードCが最も処理能力が低いため、Group全体で書き込み速度を600tx/秒に低速化します。

書き込み速度の低速化

低速化する度合いが決定したら、各ノードごとでどれだけ書き込みを遅延させるかを決定します。Group Replicationでは書き込みノードが複数ある可能性があるため、前期間で書き込みを行ったノードで均等にトランザクション数を分配し、その数までしかcommitできないようにします。

example:
  • ノードA: 300tx/秒書き込み
  • ノードB: 300tx/秒書き込み
  • ノードC: 0tx書き込み

この場合、ノードAとノードBはそれぞれ実行可能書き込み量を均等に配分した300txまでしかcommitできなくなり、ノードCが追いつくまでの時間を稼ぎます。

低速化後の微調整

Flow Controlが発動している間、各ノードは1期間ごとに処理能力を再計測し、書き込み速度の低速化度合いを調整します。各書き込みノードに割り当てられた実行可能トランザクション数からも遅延が発生した場合、遅延分+10%下げた値を再度実行可能トランザクション数として設定します。

example:
  • ノードA: 300tx/秒書き込み
  • ノードB: 250tx/秒書き込み(50tx遅延発生)

この場合、ノードBは(300tx-50tx)×0.9=225tx/秒に書き込み速度を低速化します。

Flow Controlの解消時

十分に実行速度が落ちて、待機中のトランザクションが閾値を下回った場合、Flow Controlは解消されますが、すぐに元の書き込み速度に戻るわけではありません。

Flow Controlが解消された後も、1期間ごとに処理能力を再計測し、徐々に書き込み速度を元に戻していきます。この時、すぐに元の速度に戻すと、再び遅延が発生する可能性があるため、1期間あたりにgroup_replication_flow_control_release_percentずつ増加させるようにして書き込み速度を戻します。

example:
  • ノードA: 300tx/秒書き込み
  • ノードB: 225tx/秒書き込み
  • Flow Control 解消
  • group_replication_flow_control_release_percent: 50%
  • ノードA: 450tx/秒書き込み
  • ノードB: 338tx/秒書き込み

ノードA、Bともに50%ずつ増加させた値で書き込み速度を戻しています。この後も計測期間ごとに50%ずつ増加させていき、最終的に元の書き込み速度に戻します。group_replication_flow_control_release_percentのデフォルト値は50%に設定されています。

まとめ

MySQL Group Replication の Flow Controlは、ノード間のデータ同期を保つための重要な仕組みです。しかし同時にパフォーマンスの低下にもつながります。そのため、Flow Controlが頻繁に実行される場合、ワークロードの見直しや設定値を最適化し、システムの負荷やネットワークの状態に応じて最適なパフォーマンスを維持することが重要です。

参考情報

おすすめ記事

記事・ニュース一覧