あーかいぶすハイディフィニション

ここはもう更新しとらんのじゃ

MySQL Cluster をプロダクション運用開始してひと月たった感想

MySQL Cluster (7.1.19 ->) 7.2.5 でウェブサービスのプロダクション運用初めてひと月経過したんで、それぞれの感想を書いてみたと思います。

実際の運用環境

 ハードウェアロードバランサの直下に Nginx を立てて、その下で Unicorn が動いてる。ちなみに Rails 3.2 で構築してます。Nginx から Rails までを一台のウェブサーバにして、二台構成でロードバランサが等倍バランシングしてる。んで SQL node と MGMD node もその中に同居させてそれぞれ一台ずつ立てて、localhost:3306 で参照してる。
 その下に更に二台別鯖として NDB node 立ててる、合計四台構成です。ちなみにこの鯖は、CPU 16core 32thread のうえ、物理メモリ 128Gbyte とか頭おかしい構成なんだけど、メモリこんないらんかった。NDB node として一台丸々使うなら、8 とか 16Gbyte とかで十分だった。その分、普通の 7.2k HDD と RAID カードとかじゃなくて、SSD にすればよかったと思ってる。

MySQL Cluster 7.1.x はよっぽどの理由がない限り使う必要なくね?

 いきなりだけど、もう既に運用してるからのバージョンアップ以外の理由では使わない方がいい、というか使ってる人がこんな辺境見に来るとは思わないけど。公式とかその手の界隈でもよく言われてるけど join されると途端にモサーリし出すのが一番の原因です。最初から考えて DB 問い合わせとかしてればいいけど、前述の通り今回の環境は Rails 3.2 で構築した(開発開始当初は Rails3)ので、実際のクエリを ActiveRecord が作成すると、たまに壮絶な join が……(アプリケーションエンジニアいわく、Rails3 なりたての頃と比べると相当改善した、とは言ってたけど)。今回ももれなく要件の追加がクズのように色々あったため、一部でひどいことになっていたのですが初期構築後利用していた 7.1.19 -> 7.2.5 にして、極端に性能良くなるパターンがありました。公式で 70 倍の速度向上?とか言ってた気がするけど、うちでも確か 5 倍くらい早くなったパターンがあった気がします、はやくなったー!って嬉しくなってて、今じゃもうよく覚えてないわwwwww
 あとは、7.1.19 で LIKE が特定の条件下で動いてないってバグがあって以下のエントリでも書いたけど、これ判明するまで意味がわからなくて結構ビキビキきてた。Twitterで愚痴ばっかりつぶやいててすんませんした!
MySQL Cluster 環境で LIKE 検索が仕事してない - ARCHIVESDRIVE HD

7.2.5 って本当に 70 倍速い?

MySQL Cluster 7.2 リリース - 70倍のパフォーマンス向上と NoSQL 機能
 上記は infoq の記事だけど、まあ実際使ってどうなん?って聞かれたら、7.1.x 系よりは速い気がする(一部では確実に早くなった)けど、全体として見たら誤差内じゃね?って感じです。そもそもリリース時のなんかのビデオストリーミング見たんだけど、公式で 70 倍早くなった!とか言ってる条件が、Infiniband 利用したサーバ群での結果だったりとか前提条件からしてチートすぎるのでちょっと…ってレベル。確かチャットでの質疑応答で、「まあ GbE でも最適化してれば 10 倍くらいは速度改善見込めるんじゃね?」みたいな事言ってた気がするけどよく覚えてない。この時の資料Oracleのなんかで見れた気がするけど忘れた!すまんな!

ウェブアプリケーションとの食い合せ

 実際ウェブアプリケーション作成しようとすると、言語は色々あるけど DB は MySQL(MyISAM/InnoDB) 使っておけばいいよって感じで、次にライセンス気になったり MySQL Sxxk!! みたいな人は PostgreSQL 使うのかな?あとはまあ要件とか。そんなレベルまで予算出ないとか、テストだし SQLite でいいやとかそういう。Oracle ちゃんとか高いし、 DB2 とかはそもそも触ったことないからしらん!んで、ウェブアプリと運用するのはどうなん?って話だけど、性能はもとより、ウェブアプリ設計の点で見ても正直オーバースペックかなあ、と思ってる。事前のウェブアプリへのアクセス数とか、想定される最長のクエリを元にコンフィグ作ったりとかっていうのが案外あってだるい、まあサーバの性能にまかせて大きめの値設定すれば細かい事考えなくてもぶん回せるから、予算があれば楽。
 だけどなんでもかんでも DB に格納するような設計だと、後半メモリ容量との戦いとか出てくるからやばい。メモリに積みきれなかった分は、ハードディスクに逃がすっていう方法もあるんだけど、その部分シークしなくても全体が性能劣化して引っ張られるからもう無理、素直に MySQLDUMP して、Replication 環境にしたほうがいいってなっちゃう。
 ぶっちゃけ設計によるところが大きいです。構築前にちゃんと設計できて、構築後リリースしても事前計画を大きく外れることなく運用できてれば、十全にさいきょーでしょう、⑨です。けど text や blob をよく参照されるところに配置したり、ディスクにデータを出した瞬間おしまいです、致命的です、しにたくなります。
 まあなんか、マニュアル見ながらガンダムうごかして「こいつすげえー!ほしいいいいいい!」とか言ってるアムロっぽい感じです。障害起こるとブライトに殴られて「よくもぶったね!」とか言ってる、こいつ非常にめんどくさい、つんでれ。
 あとちょっとずれるけど、NDBD node に問い合わせできるネットワークの中に入れば、アプリケーションから問い合わせ先として利用する SQL node をいくつでも作れるので、SPOF をなくすことができます。MySQL Replication だと、マスタとスレーブに参照はできるけど、更新はできないしね(マスタ複数立てる方法しらないんだけど、あったらすまん)。
 PostgreSQL だったら、pgpool(-II) が外出しミドルウェアのお陰で、pgpool 複数台と PostgreSQL 複数台とかで SPOF 防げるね、っていうかそういうシステムも別で運用してる。こっちはこっちで結構問題あるんだけど、そのうち MySQL Clusterと比較して記事書くか。

インデックスなくても速いとかいう噂

 オンメモリなので当然速いです、全部オンメモリならね。と思っていた時期が僕にもありました。なんかプロダクション環境にリリースしたらクッソ遅いの、ステージングで用意したサーバと動作違って慌てたね。原因究明で二徹くらいしたけど、結局オンメモリって言葉過信すんなって結論にしか至らなかったので、素直にインデックス構築してもらいました。そしたらはえーの。インデックス重要だわ、要らないとかないわー、みんなもインデックス構築してくださいね!まじで。
 ちなみに、今プロダクション環境でも slow-query の検出に確か 3sec とか設定してた気がするけど、csv 出力とかのような、テーブル全件参照系を実行しない限り、slow-query 検出されることはないです。インデックス構築前は余裕のタイムアウトですよ、馬力が違います。って感じだったので。

バックアップとリストア

 バックアップは mysqldump みたいな専用のコマンドはありませんが、MGMD node を管理するコマンドもしくはシェルから特定の引数を渡すことで作成できます。あとは、なんか GCP と LCP っていう機構と出力されているそれぞれの差分ログで、メモリクラッシュしてもディスクに吐き出されていた部分まで復旧が可能で、バックアップ作ってあった一日前までデータまるごと巻き戻ります!みたいなのよりはマシらしい。そういう状況になってないのでまだ試してなくてよくわからん、すまんな!
 あ、リストアは専用のコマンドというか、SQL node の代わりに(その一種であるらしい) RESTORE node のようなものを立てる必要があるんだけど、その御蔭かクッソ速いです。1Gbyte 弱のデータをリストアするのに10分もあればお釣りが来ます、はえええええー。けど最初にデータベースのメタデータ流し込んだり、使用してる NDB node 分のバックアップが必要だったりと手順化しないとめんどくせーです。

今後の運用とかどう?

 まじ不安しかない。性能とかそーいう部分は心配してないんだけど、バグやばいのが多すぎる気がする。このあいだも下のバグで NDB node 全部落ちて風邪でげほげほしながら徹夜で監視してた。
MySQL Bugs: #65141: Data node crash in error 2341 in MySQL Cluster 7.2.5
 7.2.6 でそれっぽい修正があるんだけどどうなんだろう。プロダクション運用入れてるからすぐにアップデートできなくて、いつ落ちるのかわからないのが辛い。片肺運転でアップデートできるのは、7.1.19 -> 7.2.5 へのアップデートで確認してるから心配してないんだけど、アップデートの稟議が降りないのが辛い。見てる限りだとほぼ二ヶ月位でアップデートしてんのかな?常に最新版追って行かないと理不尽なバグですぐエンジニアが死に絶えそうな予感してる。NDB 自体のソースコード読めれば話は別なんだけど、そこまでのスキルないし、Oracle に4000ドルだか払ってサポートライセンス買った方がいい、まじで。そこまでして運用するのもどうよって感じはしてる。なんか過去のリリース見てると、コンフィグ入れ忘れたわてへぺろ☆みたいなのもあってこいつら本当に大丈夫かよって感じ。感じ何回書いたかわかんないけど、それくらいの危機感は感じてる。こうして今日もまた僕はバグを探すのだ。

 生の MySQL と比べると、比較的簡単に速度出すことが可能なので便利っちゃー便利です。あとは運用する人のスキル次第かな?最近は書籍も出たようなので、敷居は下がった感じがします。問題は開発の現場でどう利用させるか、バグとどう向き合うかだと思います。ローカルの InnoDB で開発してるアプリケーションエンジニアに「なんでこんな制限あんだよ!」と何回言われたかわかりません。事前に制限の書いてあるページ読んでおいてね、って言っても読まない奴は読まないで文句だけいうので、自分である程度アプリケーションの動作をこう直してね、って指摘できるくらいまでコード読み込む力も、場所によっては必要でしょう。辛い、しぬ。なんで CHAR(40) ですむ所に TEXT 使ってんだ○すぞ。UTF-8 の CJK は 2byte 計算じゃないぞ 3byte だぞよく見ろよ…、みたいなやり取りは結構した、毎回しにそうになった。

全然かんけーねー部分の使った感想

 オンメモリだけあって、アーキテクチャに詳しい人ならぺろっと出てくると思うけど、NUMA の影響を受けます。NUMA ってのは、すげーざっくり例えるとAくんちとBちゃんちがすげー近くて、それぞれの子供部屋の窓から行き来できる位の距離になってて、気づいたら結婚して子供までいたわ、って感じ。で、前述のサーバは libnuma 入れて NUMA による別メモリ同士の通信を行わないようにしてる。まあ ESXi 内のゲスト複数台でしか検証してねーけど、ms 単位での同期精度が必要なクッソシビアなシステムでもない限り、NUMA あってもなくてもほぼ一緒、そこ気にするくらいならクッソ速いメモリできる限り積むのと、速い RAID カード(もしくは SSD)積むほうがよっぽどいい。
 あ、さらっと書いたけど、Oracle は、MySQL Cluster 7.2 以降で、OracleVM 環境でのみ、仮想環境での動作を保証してます。それ以外はしらんよーってスタンスです。だけど一応 ESXi 4/4.1/5 それぞれで CentOS6 環境下で動いたよ、いけるいける。

 いまんとこはこれくらいかなー。あとは上記で書いたように、pgpool を使った PostgreSQL クラスタ環境との比較とか書いた時とか、半年か一年経ったあたりにまたなんか書くかも。