Garelaについての覚書
業務でPercona/Galeraで触る機会があり、いろいろと調べたので備忘的にメモです。
製品概要
- MySQLを使ったMultiAct型クラスタを実現するために、Codership社が開発した外付けプラグインが Galera , それをパッケージングしたのが Percona [1]
- 更新(CUD)系のトランザクションを WriteSet と呼ばれる単位に束ねて、リアルタイム同期(同期的なレプリケーション)する実装. クラスタを構成する各ノードが有するDBデータの完全性を判定するために、全てのトランザクションに Global Transaction ID という(全クラスタにおいて)一意な識別子を振って管理を行う。 ※GTIDはMySQL5.6で実装された機能として一般に認知されているが、それとは別機能としてGarelaに独自に実装されている。
- GTIDはまた、「分散システムを構成する各ノードが最後に処理をしたトランザクション」という情報特性を生かす形で、node stateを表現する情報としても利用される
- Garelaは内部的に持っている GTID を
State UUID
とOridinal Sequence Number
に分解して、grstate.dat
というファイルに書き出す。
WriteSet Replicaton の同期シーケンス
- 更新系の処理は、
Write Set Replication(WSREP)
という機構により同期される - cluster構成 あるいは DB recordが変わる度に state change が発生する。wsrep APIは state change をフックし、WSREP providerにfunction callを発行する。呼ばれたWSREP providerはトランザクションを write set にまとめ、cluster内の他ノードと通信、certificate と replicationを行う
- 所謂、
2段階コミット(Two-Phase Commit)
クラスタに新ノード加入時の初期同期処理
ノードがクラスタに対し加入する際に、加入するノードはドナーノード(同期するトランザクション情報を提供するノード)との間での、レプリケーション処理(transfer)を発火させる。レプリケーションには2種類あり、フル同期(SST)、差分同期(IST)のいずれかが実行される
SSTとISTのいずれを発火させるのかについては以下のような流れで判定される
スプリットブレインとgarbd
分散合意問題
- 一般に分散型のDBシステムには、 分散合意問題(Distributed Consensus) という設計上の解決すべき課題がある
総計100台のノードがあり、それがお互いに通信できない、40台と60台に分裂してしまった時に、それぞれのグループに対し、色々なアプリケーションが別々のCRUD=更新系処理ができてしまっていいのか?ダメなのか?(別の言い方をすると、更新処理はACID特性を満たす必要があるのか?)そういう状況でも、システムが全体として意図とおりに動作する設計にしたいとすると、どういう設計/実装にすべきか?データの一貫性はどの程度保証できる?みたいな話- シェアードナッシング型の分散システムにおいて、系全体の「状態」をどう導き出すのか?という問題(ビザンチン将軍問題[3])
Galeraにおける分散合意機構
- Galeraの場合、「あらかじめ全体の総数を覚えておき、自分が現在通信可能なノードの総数が過半数を割る(50%以下)時は、そのノードはトランザクション処理の実行機能を自主的にdisableする」という感じの点呼&多数決システム( Quorum )を採用している。
- 50%でもダメなので、クラスの総ノード数が偶数だと場合によっては全員死ぬ。なので、奇数ノードが良いとされている。
- じゃあ、お金の都合で2台しか用意できない人はどうすれば?という問題を解決するために
garbd
が用意されている。 garbd
はDB機能は持たないが、点呼の頭数に数えられるはノード。これを使うことでスプリットブレイン的な意味では、3ノードクラスタになる
- じゃあ、お金の都合で2台しか用意できない人はどうすれば?という問題を解決するために
[1] 参考: MySQLの専門家集団Perconaのビジネス戦略に迫る https://enterprisezine.jp/dbonline/detail/9542
[2] 参考:『データ指向アプリケーションデザイン』P156
[3] 参考:『データ指向アプリケーションデザイン』P330