Slide 1

Slide 1 text

MyRaft論⽂紹介 第5回MySQLアンカンファレンス (2024/06/22) tom__bo

Slide 2

Slide 2 text

MyRaft論⽂概要 • タイトル: MyRaft: High Availability in MySQL using Raft • 発表: EDBT 2024 • リンク: https://openproceedings.org/2024/conf/edbt/paper-199.pdf

Slide 3

Slide 3 text

概要 • Metaのソーシャルグラフのデータを含む数⼗ペタバイト(tens of petabytes)のデータはMySQLで管理されている • これまではMySQLの準同期レプリケーションと⾮同期レプリ ケーションを使って、フェイルオーバなどのコントロールプ レーン操作は外部のプロセスに依存していた • この仕組みは複雑でエッジケースに対して論理的は保証ができ なかった

Slide 4

Slide 4 text

概要2 • 著者等はMySQLのレプリケーションスタックからRaftベースの コンセンサスプロトコルに移⾏することを決めた • この論⽂ではレプリケーションプラグインとしてMySQLにRaft プロトコルを統合した"MyRaft"を紹介する • さらに低レイテンシと⾼可⽤性を実現するために⼊れた複数の強化機 能(FlexiRaftやProxying)なども紹介する • そしてMetaの環境でMyRaftをデプロイ(rollout)した経験も紹介する • (この発表では省略(5章部分))

Slide 5

Slide 5 text

Introduction • MetaではMySQLが最も利⽤されているOLTPデータベース • 障害耐性、⾼可⽤性とスケーラビリティのため地理分散してデプロイされ ている(図1a) • 通常のPrimary, replica, ログだけを持つLogtailerで1つのReplica set • Single Primary構成(Sourceは1台) • すべてのMySQL ReplicaがPrimaryに昇格できるわけではない

Slide 6

Slide 6 text

Motivation • MySQLのレプリケーションプロトコルはコントロールプレーン操作 (Primaryの決定, メンバーの変化)をサポートしていない • コントロールプレーン操作は"Automation"として外部のプロセスが実⾏す る必要があるが、Split Brainを起こさないようにコーナーケースに対応する のは難しい • コンセンサスアルゴリズムを利⽤して、MySQLサーバでReplica Set中のメ ンバ管理を⾏うようにした • 特にRaftはシンプルで理解しやすいことで知られていて、実装のため の完全な仕様がある

Slide 7

Slide 7 text

Contribution • MySQLのレプリケーションプロトコルにRaftを統合した 1. RaftでReplicated Logとして利⽤されるMySQLのbinlogを管理する抽象 化レイヤを構築 2. トランザクションのコミット時にRaftとやり取りするための複数の フックを実装し、Raftのコンセンサス後にコミットするように変更 3. Raft内部でPrimaryの昇格が起きたらコールバックを通じてMySQLの Primary<->Replicaへの変更を⾏うオーケストレーションを⾏う • 地理分散した環境でも利⽤できるように様々な改善を⾏った • FlexiRaft, Proxying, etc...

Slide 8

Slide 8 text

MyRaft Topology • MyRaftではLogtailerを含むレプリカセットの全メンバが Raftリングのメンバ (Fig 1b, 1aは参考のため掲載)

Slide 9

Slide 9 text

MyRaft Topology • メンバは投票者と⾮投票者に分かれ、⾮投票者はログを受信するのみ • logtailerはデータを持っていないが投票に参加する • logtailerを持たないMySQL Replicaは投票に参加せず、Primaryになることもない

Slide 10

Slide 10 text

Main Operation in Raft • データレプリケーション • クライアントの書き込みはRaftリーダー(プライマリ)に送信される • リーダの昇格 • リーダーはメンテナンス中に全フォロワーがすべてのログエントリを持っていることを確認し、 次のリーダを決定する投票を開始する • フェイルオーバ • リーダーは定期的に全てのフォロワーにハートビートを送信する • フォロワーはハートビートがなければリーダが死んだと判断して新しいリーダーの投票を⾏う • 最⻑のログを持つものが勝つため、⼀時的にログテーラーがリーダになることもある • ログテーラーは通常の昇格⼿順でリーダシップをレプリカに移⾏する • メンバーシップの変更 • メンバーシップの変更はAutomationによって実⾏される • 新しいメンバーを割り当てて準備ができたらRaftのAddMember操作を呼び出し、削除は RemoveMemberを呼び出す

Slide 11

Slide 11 text

mysql_raft_repl: Raft as a MySQL Plugin • MySQLとRaftの統合をmysql_raft_replプラグインで実装した • Raftライブラリとしてkuduraftを使⽤し、MySQLはMySQL Plugin APIを通じて プラグインとやり取りをする

Slide 12

Slide 12 text

mysql_raft_repl: Raft as a MySQL Plugin • コールバック(RaftからMySQLへの呼び出し)のために別のAPIも作成した • コールバックAPIはMySQLのロール変更のための操作のために利⽤される • 昇格時にMySQLをプライマリとして設定(クライアントの書き込みを有効化など) • 降格時にMySQLをレプリカとして設定(アプライヤースレッドを開始し、クライアントの書き込みを無 効化など) • kuduraftがbinlogを読み書きするためのヘルパーを作成 • プラグイン内にbinlogの抽象化レイヤを作成することで、kuduraftはbinlogのフォー マットを気にせずトランザクションを読み書きできる

Slide 13

Slide 13 text

Relay-Log and Binlog Modes • binlog, relay_logの書き込みはRaft(mysql_raft_replプラグイン)経由で⾏う • Primaryの場合はbinlogに、Replicaの場合はrelaylogを指す • この後の説明を読んでいると、log_replica_update = onでbinlogにも書いている様⼦ • (確かにReplicaでのbinlogは再適⽤時に出⼒されるので、MyRaftではないかも) • 上記の出⼒先の違いのため、MyRaftはPrimaryではBinlogモード、Replicaで はRelay-Logモードで動作する

Slide 14

Slide 14 text

MySQL state change during Raft role change • Raftによる投票とタームの変更で、Raft内でのリーダ、フォロワーの⼊れ 替えが発⽣するが、MySQLのプライマリ、レプリカロールはこの時点では 変わっていない • Raftはコールバックを介してMySQLのロール変更を⾏う必要がある

Slide 15

Slide 15 text

ReplicaからPrimaryへの昇格ステップ • リーダーへの移⾏時、Raftプラグインは以下のステップを通じてMySQLを レプリカからプライマリに移⾏する 1. クラスタ上のリーダーシップを主張し、ログの末尾をコンセンサスコミットするためにNo- Opイベントをログに追加 2. アプライヤーを使⽤してNo-Opイベントまでのすべてのトランザクションをキャッチアップ およびコミット 3. ログをリレーログモードからバイナリログモードに切り替え 4. プライマリでのクライアント書き込みを許可 5. ロール変更をプライマリとしてサービスディスカバリーシステムに更新

Slide 16

Slide 16 text

Primary からReplicaへの降格ステップ • 降格ステップ 1. 進⾏中のすべてのトランザクションを中⽌(Abort) 2. クライアント書き込みの無効化 3. MySQLのログをバイナリログモードからリレーログモードに切り替え 4. コンセンサスコミットされていない保留中のトランザクションがある場合、Raftは レプリケートされたログを切り捨てる • コンセンサスコミットと⾒なされなかったトランザクションを削除 • 切り捨てられたトランザクションのGTIDをメタデータから削除 5. アプライヤースレッドを開始し、リレーログの適切な開始点を指す • (エンジンで最後にコミットされたトランザクションを使⽤してアプライヤーの開始カーソルを決定)

Slide 17

Slide 17 text

Write Transaction on MySQL Primary 1. クライアントはMySQLプライマリに書き込みを送信する 2. トランザクションは最初にストレージエンジンで処理され、バイナリログを⽣成する 3. トランザクションのコミット時にGTIDが割り当てられ、その後、RaftがログエントリにOpIdを割 り当てる 4. Raftはトランザクションを圧縮し、メモリ内キャッシュに保存して、未圧縮のログをログファイ ルに書き込む 5. リーダはログエントリに対する投票を⾏う 6. ⾮同期でトランザクションログをフォロワーに送信し、ack投票が返ったら"consensus commit"に 到達する

Slide 18

Slide 18 text

Write Transaction on MySQL Primary • トランザクションをコミットするスレッドには、パイプライン に3つのステージがある • 各ステージには独⾃のミューテックスがあり、⼀緒にグループ化されたトランザク ションのセットは⼀緒に次のステージに進⾏する 1. Flush: • トランザクションはRaftを介してバイナリログに記録 2. Wait for Raft Consensus Commit: • スレッドはグループ内の最後のトランザクションのコンセンサスコミットを待つためにブロックされ る • Raftが投票者の過半数から承認を得ると、コンセンサスコミットに到達する コンセンサスコミットに 達するとスレッドのブロックが解除され、グループの第3ステージに進⾏する 3. Storage Engine Commit: • 準備されたトランザクションをストレージエンジンでコミットする

Slide 19

Slide 19 text

Write Transaction on MySQL Replica 1. AppendEntries RPCを受け取ると、⾮リーダーはプラグインとログ抽象化を使⽤してトラ ンザクションをログに追加する 2. RaftプラグインはMySQLに新しいログエントリを通知します。また、アプライヤース レッドにも信号を送り、リレーログからトランザクションを取り出し、データベース に適⽤する 3. トランザクションペイロードの最後のイベントである"COMMITイベント"でコミットパ イプラインを進⾏する • コミットパイプライン 1. Flush: トランザクションをアプライヤーのログファイルに書き込む 2. Wait for Raft Consensus Commit: Raftがコミットマーカーに到達するのを待機 3. Storage Engine Commit: ストレージエンジンでコミット

Slide 20

Slide 20 text

IMPROVEMENTS TO RAFT (FlexiRaft) • Raftアルゴリズムはデータコミットクォーラムの選択に柔軟性がない • リーダー選挙とデータコミットクォーラムの両⽅は、レプリカセット内の投票メン バーの過半数が必要 • 複数の地理的に分散した多数のレプリカを持つ場合は低レイテンシと⾼スループッ トを実現できない • => FlexiRaftを提案 • (別論⽂) • FlexiRaftが提供する“single region dynamic”モードで解決 • データコミットクォーラムとリーダー選出クォーラムの両⽅を単⼀の地域に制限し、 数百マイクロ秒のレイテンシーを提供する

Slide 21

Slide 21 text

IMPROVEMENTS TO RAFT (Proxying) • Raftのhub-and-spokeネットワークアーキテクチャでは、 リーダーが直接フォロワー全台にレプリケーションする • この構成は複数のリージョンに分散したレプリカとログテーラーとは相性が悪い • => フォロワーがリーダーから下流ノードへのAppendEntriesリクエストを プロキシできる機能を追加 • さらに、RaftのAppendEntriesメッセージは、新しいタイプのメッセージである PROXY_OPをサポートするように機能追加 • PROXY_OPはリクエストのメタデータを含むが、ペイロードは含まない

Slide 22

Slide 22 text

IMPROVEMENTS TO RAFT (Mock Electon) • リーダーの選出が発⽣するたびに、リーダーを読み取り専⽤モードにしな いといけない • リーダー選出にはログのキャッチアップが必要なため、書き込みできない期間が⻑ 引くかもしれない • => OpIdのスナップショットに対する仮選出(Mock Election)を⾏うことで、 この問題を軽減 • (詳細省略)

Slide 23

Slide 23 text

Evaluation(Latency and Throughput)

Slide 24

Slide 24 text

Evaluation(Promotion and Failover Downtime) • MyRaftと以前のセットアップ間の昇格ダウンタイムの⽐較 • 30⽇間の本番環境のメトリクス • ⼿動のプライマリ昇格は平均で200ミリ秒以内に完了(以前は平均1秒) • フェイルオーバーは平均で約2秒で完了(以前のフェイルオーバは59秒) • 全体として、⼿動昇格時間は4倍の改善、フェイルオーバー時間は24倍の 改善

Slide 25

Slide 25 text

疑問・他 • Group replicationではだめだったのか? • => Group replicationのグループサイズ制限の9に引っかかりそう • 他には? • Group replicationを改善するのではだめだったのか? • Flexible Paxosの論⽂もMetaが出してる(要調査) • Group Replicationと⽐較してパフォーマンス劣化はどうか? • FlexiRaftの最適化があるので、台数が増えたらMyRaftのほうが速そう • そもそもGroup ReplicationのSemi-syncに対するパフォーマンス⽐って情 報ありましたっけ?

Slide 26

Slide 26 text

No content