MySQLの5.6で登場し一部で話題になったmemcached互換プロトコルを試して見ました。
結論から言うと「一応動く」というレベルで、memcached互換というコンセプトに無理があるように思いました。逆に改めてDeNAのhandler-socket-plugiinの良さを感じました。
セットアップ
memcached互換プロトコルは、厳密にはMySQLではなくinnoDBのプラグインです。また、ステータスがBetaでもなくlabsなので、mysql-labsからコンパイル済みのバイナリを入手する必要があります。
MySQL :: MySQL Server Snapshots より、mysql-5.6-labs-innodb-memcachedを選択すると、各プラットフォーム向けのバイナリが出ていますので、それをダウンロードします。
ダウンロード後は、このエントリを読みながら進めます。
libeventを入れるように書いているので、少々古いですがyumでいれました。ダメだったらちゃんとソースでやろうと思ったんですが、今回はこれで。またlibaioもあとで必要になるので入ってない人はインストール。
$ yum -y install libevent libaio
そして、ダウンロードしたバイナリを展開し、/usr/local/mysqlに配置します。
同梱のINSTALL-BINARYを読みながら普通にセットアップします。
$ groupadd mysql
$ useradd -r -g mysql mysql
$ chown -R mysql:mysql .
$ scripts/mysql_install_db --user=mysql
$ chown -R root .
$ chown -R mysql data
$ cp support-files/my-large.cnf /etc/my.cnf
$ cp support-files/mysql.server /etc/init.d/mysqld
※/usr/local/binに必要なコマンドのシンボリックリンクを設置
innodb-pluginの有効化
このようにエントリ通りプラグインが正しく存在されているかチェックします。
設定用のスクリプトを流し込みます。
同梱のREADME-innodb_memcachedをみつつ、pulginのインストールを実行します。
$ mysql < scripts/innodb_memcached_config.sql
$ mysql -u root
mysql> install plugin daemon_memcached soname "libmemcached.so";
Telnetでテストし、テスト結果が入っていることを確認します。
$ mysql -u root
mysql> set session TRANSACTION ISOLATION LEVEL
mysql> -> read uncommitted;
mysql> select * from demo_test;
無事入っていましたね。よかったよかった。
一番の問題、1サーバ1テーブル制限
現状普通に使えないなと思うことが2つありまして、1つは、任意のテーブルにmemcachedプロトコルでアクセス出来ないところ。もうひとつは複数のカラムに値をセットするときが | で区切られた一つのテキストを投げないといけないこと。
今のところ1つのmemchached経由の応答を担当するのは、1つのテーブルに限定されており、それをmysql内の設定テーブルで管理しています。つまり、それ以外のテーブルにアクセスすることができません。そのうち出来る様になると書いていますが、memcachedプロトコルにこだわるあたり、キー名のprefixで判断とかになりそうな予感がしています。
文字区切りですが、明示的に値が隔離されていないのは、なんとも使いにくいように感じます。|をエスケープしないとバグるし。
そういう残念な感じを味わったあとに、handler-socket-pluginをみると、独自のプロトコルで通信するだけあってこれらの問題が解決されていると感じました。プラグインやドライバのメンテを誰がするんだという問題が解決すれば、こちらは非常に良い選択肢だと思いましたので、ぜひとも本家に吸収してほしいなあと思います。
ちなみに速度ですが、接続ー切断のコストはmysqlよりmemcachedのほうが4割ほど高く(phpの場合)接続後の読み書きは memcachedのほうが2〜3倍早い感じでした。