repcached-2.0リリースのお知らせと、超簡単なサンプルコード
repcached-2.0(memcached-1.2.5ベース) をリリースしましたのでお知らせします。
今回の目玉はマルチマスタ構成のサポートです。
以前のバージョンはマスタ/スレーブ構成だったので、必ずマスタへ書き込まなければいけませんでした。そのため、接続先のサーバがマスタなのかどうかをクライアントが判別しなければいけなかったり、keepalivedなどと併用するなどの工夫が必要でしたが、今回のバージョンではその必要がなくなります。両方のサーバに対してデータを書き込むことができるようになったので、かなり使いやすくなったと感じています。
repcachedはパフォーマンスを最重視しているため、レプリケーションは非同期で処理しています。したがって、setと同時にレプリケーションが完了する保証はありません。つまり、サーバAにsetした直後にサーバBからgetした場合、正しい値が返ってこない可能性があります。
しかし、memcachedのクライアントライブラリは負荷分散機能を持っていて、複数のサーバがある場合、キーのハッシュ値を元にして接続先のサーバが選択されます。そのため、同一のキーに対する操作は必ず同じサーバで処理されます。これを図にすると以下のような感じになります。
つまり、クライアントライブラリの負荷分散機能を利用すると、データを格納したサーバと同じサーバが参照されるので、非同期処理に起因するデータの不整合は発生しません。そして、すべてのデータは両方のサーバへ格納されているので、片方のサーバがダウンしてもすべてのデータが保持されます。
ただし、参照しようとしたサーバがダウンしていた時に、自動的にもう片方のサーバへ参照しにいくかどうかは、クライアントライブラリの実装に依存します。例えば、PHP の memcached extension で提供される Memcache::set 関数の場合は、Version3.0.0以上ならば自動的に再接続してくれますが、Version2.2.3ではエラーになってしまいます。そのような場合は、自分で再試行するなどの処理を実装する必要があるかもしれません。セッションハンドラ(session.save_handler="memcache")を利用する場合は、バージョン2.2.3でも再接続してくれます。
※この例は後ほどご紹介します。
ダウンしていたサーバが復旧して最初にやることは、既存のサーバの全てのデータを複製(以下、まるごとこぴー)することです。その間、復旧中のサーバはクライアントからの接続を受け付けないので、誤って中途半端な状態のデータを取得してしまうことはありません。また、まることこぴーの最中でも、コピー元のサーバに対しては正常にアクセスできるので、サービスが停止してしまう心配もありません。
まるごとこぴーが完了次第、レプリケーションを再開し、両方のサーバへアクセスできるようになります。まるごとこぴーの所要時間は、ギガビットイーサの環境で10万件で3秒程度、100万件で30秒程度でした。
簡単な使用例
簡単な使用例として以下のコードを紹介します。セッション変数を利用して、リロードするたびにカウンタが増えていくPHPです。 セッションハンドラとしてmemcacheを使い、データの保存先にrcd1とrcd2というサーバを指定しています。rcd1とrcd2ではrepcachedを起動しておきます。
[count.php]<?PHP $rcd1="tcp://rcd1?persistent=1&weight=1&timeout=1&retry_interval=15"; $rcd2="tcp://rcd2?persistent=1&weight=1&timeout=1&retry_interval=15"; $session_save_path = "$rcd1,$rcd2"; ini_set('session.save_handler', 'memcache'); ini_set('session.save_path', $session_save_path); session_start(); if(empty($_SESSION['count'])){ $_SESSION['count']=1; } else { $_SESSION['count']++; } echo "count=".$_SESSION['count']."\n"; ?>※PHP-5.2.5 + memcache-2.2.3で動作確認
ブラウザでこのページへアクセスすると、リロードする度にカウンタが増えていきます。 rcd1,rcd2のどちらかが動いている限りカウンタは増え続け、両方停止するとリセットします。
このように、repcached-2.0はmemcachedを2台で負荷分散するのと同じ感覚で利用できます。 すでにmemcachedを2台構成で運用しているシステムであれば、repcached-2.0に置き換えるだけで冗長構成になるかもしれません。 さすがにオリジナルのmemcachedと比べると若干パフォーマンスは落ちますが、それでも実用には支障のないレベルに仕上がっていると思いますので、もしよろしければご利用下さいませ。