MySQL の負荷分散に LVS + keepalived を使う

あとで書く、と言った手前なので書くとします。

DSASの中の人がすごい勢いで LVS の話を書いてくれてます。この辺。LVS を使うと Linux と箱でロードバランサが作れちゃいます。普通に買ったら数百万とかしちゃうやつ。

DSAS の中のひとに感謝しつつ、いい機会なのでやってみよう! と思っていろいろ試して昨日あたりからはてなの中でも LVS + keepalived で動かしはじめてます。いまのところ問題なし。

そのロードバランサをどこに使ってるかですが、普通ロードバランサというとインターネットからの入り口のところに置いてウェブサーバーの負荷分散に使うイメージがあります。が、今回ははてなでは MySQL のスレーブの手前に置くという役割でとりあえず使いはじめました。

+-----------+   +-----------+ 
| mod_perl  |   | mod_perl  |
+-----------+   +-----------+
      |               |
      +---------------+
              |
        +-----------+ 
        |    LVS    | 
        +-----------+ 
              |
      +---------------+
      |               |
+-----------+   +-----------+ 
|MySQL slave|   |MySQL slave|
+-----------+   +-----------+
      |               |
      +---------------+
              |
        +-----------+ 
        |   master  | 
        +-----------+ 

こういう感じです。この絵だと NAT みたいに見えますが実際には DSR でやってます。

MySQL をレプリケーションさせて作ったスレーブサーバーを複数作って負荷分散する場合、ウェブアプリケーションからその複数のスレーブに繋ぐときにランダムに振ってやるとかするわけですが、そこに LVS を挟んでみたというもの。

もともと Flickr のシステム をみて、MySQL の手前にロードバランサを挟んで使うというのを知ったんですが、それを LVS でやってみました。(Flickr では BIGIP か何かの箱モノを使っていた気がします。)

LB を挟む利点は以下の3つでしょうか。

とにかく一番の利点は、アプリケーションから見た場合にスレーブプールが LB によって抽象化されること。何台もあるスレーブを一台のマシンに見せかけて使うことができ、管理が非常に楽になります。これまで Perl のコードで振り分けしてたときは、アプリケーションが DB の IP アドレスを知っている必要があったのでスレーブにマシンを追加する場合アプリケーションのメンテが必要でした。これが、LB があるとアプリケーションの側を気にせず、スレーブからマシンをはずしたり、追加したりできる。アプリケーションは LB の IP (VIP) を知っていればいいだけになります。

二つ目、これもかなり大きいんですが keepalived でヘルスチェックができるようになりました。Perl 側でヘルスチェックしようとすると色々考えることがあって大変なのですが、keepalived に任せてしまえばその辺をアプリケーションで面倒見る必要がなくなる。すばらしい。これでスレーブが突然落ちたりしてもサービスが問題なく継続できます。

三つ目、バランシングのアルゴリズムが改善される。Perl でやろうとすると、つなぎにいく MySQL のコネクションの数や負荷状況をチェックするのは大変ですが LVS であればその辺をよしなにやってくれます。なので、より均等に接続を分散できる。今はコネクション数が一番すくないところを優先的に割り振るアルゴリズムを採用してます。

今のところ keepalived で TCP 接続をチェックすることしかしてませんが、自分で作ったスクリプトでのチェックも可能なので SQL のレベルで接続可能かなどをチェックしてやるようにすれば耐障害性が向上するでしょう。LVS のサーバは一応ディスクレスにしてあるので故障確率は低いものの何があるかわからないし VRRP で冗長化させるのをいま試してます。

主なところはこの三つかなと思います。耐障害性も高まり、メンテナンスの手間も減る。導入してよかった。なお、今のところはてなブックマークのバックエンドとダイアリーの一部で使ってますが LVS の負荷はほぼないに等しいです。

ヘルスチェック、VRRPな機能が搭載されてて且つ DSR に対応したロードバランサというと高価なイメージがあって、MySQL のバランシングに使うってのはちょっと難しいなーという気もしますが LVS なら箱(と人件費)のコストだけでそれができちゃう。Oracle だと高いけど MySQL ならコストかかんないからストレージ代わりに気軽に使っちゃえ というのと似てますね。

しかしあれですね LVS やってみっかーと言って、

  • 「試験環境必要じゃない?」「マシン作るわ」
  • 「ディスクレスのマシン必要じゃない?」「ビックでパーツ買ってくるわ」
  • 「フレームワークにちょっと手いれなきゃいけなくない?」「パッチ書くわ」

というのをあうんの呼吸でできる自分とこのチームはすばらしいと思った。

フットワーク軽くないとこの手のを導入するのはなかなか難しいですしね。よくわかんないおじさんがでてきて「負荷は大丈夫なのか? 実績はどうなんだ」とか。んなのやってみなきゃわかりませんよ、という。

あ、そうだついでだから書いておこう。この手のタスクをすごい勢いでやってくれちゃったりする技術者を絶賛大募集してます。その辺がいま一番手を必要としてる層だったりします。

それから

この本に LVS とか keepalived の話が How To 交えていろいろ載ってます。他にも High Availability に関する話がたくさん。

では、アサマシしたところで締めくくるとします。