このプラグインは、MySQL のレプリケーション機能を mysqlnd を使うすべての PHP MySQL 拡張モジュールで容易に使えるようにします。
PHP 5.3.3 以降で、PHP の MySQL Native Driver (mysqlnd) は C の内部プラグイン API を提供するようになりました。 レプリケーションおよびロードバランシング用プラグインのように C でプラグインを書いて、 mysqlnd の機能を拡張できるようになったのです。
MySQL Native Driver は C のライブラリで、PHP 5.3.0 以降で PHP に同梱されるようになりました。MySQL Client Library (libmysql/libmysqlclient) の代替として機能します。mysqlnd を使う利点はいろいろあります。 PHP に同梱されているので追加のダウンロードが不要であること、 PHP ライセンスで公開されていること、メモリの消費量が抑えられること、 そして非同期クエリなどの新たな機能が含まれていることなどです。
mysqlnd_ms のような mysqlnd 用プラグインの機能の大部分は、 ユーザーの視点からはプラグインの存在を意識せずに使えます。このプラグインはすべての PHP アプリケーションをサポートし、そしてすべての MySQL 用 PHP 拡張モジュールに対応します。既存の API には何も手を加えません。 そのため、既存の PHP アプリケーションにも容易に組み込めます。
PECL/mysqlnd_ms の主要な機能をまとめます。
透過的に組み込め、簡単に使える
すべての MySQL 用 PHP 拡張モジュールに対応
SSL のサポート
一貫性のある API
使う場面にもよるが、アプリケーション側の変更はほんの少しで済む (あるいは一切変更しなくてもかまわない)
遅延接続: マスタやスレーブへの接続は、 SQL 文を実行する時点までオープンされない
オプション: ウェブからの最初の書き込みリクエストの後は、自動的にマスタを使うようにする。 これにより、レプリケーションの遅延の影響を低く抑える。
MySQL クラスタリングソリューションとの併用
MySQL Replication: 読み書きの分離はプラグインが行う。 このプラグインが主に想定しているソリューションである。
MySQL Cluster: 読み書きの分離は無効化できる。 マルチマスタ構成に対応。
サードパーティのソリューション: このプラグインは MySQL Replication 用に最適化されているが、その他の MySQL クラスタリングソリューションとも併用可能。
読み込みと書き込みの分離機能
SELECT の自動検出
SQL ヒントを使った、自動処理の無効化
ユーザー定義
MySQL Cluster のような同期クラスタを使っている場合には無効化も可能
ロードバランシング機能
ラウンドロビン: スレーブへのすべてのリクエストに対して、ラウンドロビン方式でスレーブを選択する
ランダム: スレーブへのすべてのリクエストに対して、ランダムにスレーブを選択する
ランダムワンス (sticky): 最初にひとつのスレーブをランダムで選び、ひとつのウェブリクエスト内でのすべてのスレーブへのリクエストを同じスレーブで実行する
ユーザー定義: アプリケーション側で、mysqlnd_ms 用のコールバックを登録する
PHP 5.4.0 以降では、トランザクション制御のためだけの API コールについてはトランザクションを考慮する
重みつきロードバランシング: サーバーにさまざまな優先度を設定可能。高性能なマシンにより多くのリクエストを振り分けたり、 近くにあるマシンを優先してレイテンシーを軽減させたりすることができる。
グローバルトランザクション ID
クライアント側でのエミュレート: MySQL Replication のような非同期クラスタにおける、 手動でのマスタサーバーのフェイルオーバーそしてスレーブからの昇格を容易にする
組み込みのグローバルトランザクション ID 機能をサポートする。 MySQL 5.6.5-m8 以降で導入された機能。
セッション整合性を要求される読み込みでの、 トランザクション ID を使った最新の非同期スレーブの識別に対応
スロットリング: オプションで、スレーブの処理を待って「同期」 してから処理を続行させることもできる
サービスおよび整合性レベル
アプリケーション側からは、接続に対して 結果整合性・セッション整合性・強整合性 のいずれかのサービスレベルを要求できます。 それにあわせて、適切なクラスタノードを自動的に検索します。
結果整合性レベルの MySQL Replication スレーブへのアクセスを、 高速なローカルキャッシュアクセスに置き換えることができます。 透過的なアクセスで、サーバーの負荷を軽減します。
読み込み/書き込みの分離の仕組みとして組み込まれている機能は、非常に基本的なものです。 SELECT で始まるクエリは読み込みリクエストとみなして MySQL のスレーブサーバーに送り、それ以外のすべてのクエリは (SHOW ステートメントなども含めて) 書き込みリクエストとみなして MySQL マスタサーバーに送ります。 この組み込みの挙動を上書きするために、 SQL ヒント やユーザー定義の コールバック関数 を使えます。
読み込み/書き込みの分離機能は、複数ステートメントの場合を考慮しません。 複数のステートメントも単一のステートメントとみなします。 そして、その先頭の文字を見て、どこで実行させるのかを判断します。たとえば mysqli_multi_query() を使って SELECT id FROM test ; INSERT INTO test(id) VALUES (1) を実行したとすると、この処理はスレーブサーバーに送られます。先頭が SELECT で始まるからです。後半には INSERT ステートメントも含まれていますが、 これもそのままスレーブサーバー上で実行されます。
注意:
アプリケーション側では、ロードバランシングのための接続の切り替えが発生することを想定しなければなりません。 マニュアルの 接続プーリングと切り替え、 トランザクションの処理、 フェイルオーバー、 ロードバランシング そして 読み込み/書き込みの分離 を確認しましょう。
mysqlnd_ms は mysqlnd master slave plugin の略です。 概念実証のためのコードをざっと書きあげるときに、この名前を選びました。 当時は、まさかそのコードを使い続けることになるとは思わなかったのです。