SQLノードに透過的に負荷分散する方法
出典: MySQL Practice Wiki
MySQL Clusterを使うにあたって直感的に理解しにくいことを一つ挙げると
- どうやってたくさんあるSQLノードに接続すればいいんだ?
- ロードバランスは?
- フェイルオーバーは?
ということがあると思う。このテーマを扱ったドキュメントはありそうだちょうど良いものが見あたらない。おそらくこの点が明確でないために「よし、最近サイトのトラフィックも増えてきたことだし、いっちょMySQL Clusterを試してみようか!」という気にならず、多くの人が利用を躊躇ってしまっているのではないだろうか?なので以下にこの点について3パターンのソリューションを紹介したいと思う。
mysqldをアプリと共存
恐らく最もシンプルかつ最も幸せになれるソリューションである。mysqldをアプリケーションと同じホストで動作させれば、アプリケーションは mysqldと1:1で通信するだけで良いので、ロードバランスやフェイルオーバーを考えなくて良い。アプリケーションに対してはDNSラウンドロビンなど安価な手法で負荷分散してやればいいのである。ホストがクラッシュしたときにはアプリもMySQLも一蓮托生であるが、セットで冗長化されていれば問題はない。
同じホストにmysqldがある場合、アプリケーションとmysqldとの通信はUNIXドメインソケットを利用出来るので、非常に高速に行われるというメリットがある。また、利用するストレージエンジンがNDBCLUSTERだけであれば、mysqldが消費するメモリは非常に少ない。もちろん消費するメモリ量は接続数やバッファの量にも因るが、1:1で通信するだけならばそれほど多くはならないので、500MBも見ておけば十分だろう。
mysqldを共存させる場合のデメリットは、ホストを一定数以上増設できないことである。MySQL Clusterを構成するホストの台数は最大で255台までという制限があり、これにはSQLノード(mysqld)も含まれる。即ち、この構成はあまり大規模なアプリケーションには向かないのである。(と言っても255台を超える規模ってなかなかないんだけど。)
この図では、アプリケーションとSQLノードが同じホストに同居している。負荷に応じて必要な数だけこのペアを用意するといいだろう。
Connector/J
http://dev.mysql.com/downloads/connector/j/5.1.html
アプリケーションの開発に利用している言語がJavaであればこの問題は非常に容易に解決できる。あまり知られてないことであるが、MySQLのJDBCドライバであるConnector/Jには、複数のmysqldに対して負荷分散を行うための機能が備わっているのだ。なのでConnector/Jを利用すれば、MySQL ClusterのSQLノードへの負荷分散や、レプリケーションによる参照系の負荷分散を容易に行う事が可能だ。MySQL ClusterのSQLノードに接続する時には、接続URLにおいてSQLノードを並べて記述し次のプロパティを設定する。
autoReconnect=true failOverReadOnly=false roundRobinLoadBalance=true
3 つめのプロパティはloadBalanceStrategy=randomまたは loadBalanceStrategy=bestResponseTimeでもOKだ。どれにしてもそれほど大差はないし、どれにすればいいかということについて明確なガイドラインはない。従って実際に負荷をかけてみて、最も性能の良いものを選択するといいだろう。また、この手法を利用する場合にはコネクションプーリングを利用する必要がある。何故ならば、コネクションを張った状態にしておかないと、SQLノードに障害が発生している場合でもそのノードに接続しにいってしまう可能性があるからだ。
この場合も必要な数だけアプリケーションを用意しよう。ただし、1の場合とは違って利用出来る台数に制限はない。図ではSQLノードとデータノードが同居しているが、アプリケーションのノードがとても多くて同時接続数が増える場合には、SQLノードをデータノードから分離して台数を増やせばいい。
MySQL Proxy
https://launchpad.net/mysql-proxy
開発言語がJavaでなく、さらにmysqldをアプリと共存させたくないような場合には、MySQL Proxyをアプリケーションと同じホストにインストールすると良い。MySQL ProxyはMySQLサーバへのロードバランスとフェイルオーバーをおこなってくれるソフトウェアである。Luaスクリプトを使って高度な分散処理をさせることもできるが、ただ単にロードバランスとフェイルオーバーだけが必要なのであれば、別に高度なことは何もしなくていいので使い方は簡単である。アプリケーションはMySQL Proxyと1:1で通信するだけでいい。
MySQL Proxyは次のように起動する。
shell> mysql-proxy --proxy-backend-address=host1:3306 --proxy-backend-address=host2:3306 ... 中略 ... --proxy-backend-address=hostN:3306




