memcached は C 言語で記述されたインメモリ型の KVS なデータキャッシュミドルで、高速なデータアクセスを実現するため、twitter や Facebook、mixi で使われているようです。軽量でシンプルなのが売りですね。一方、gemcached は、VMware 社の KVS 実装である vFabric GemFire をベースとした、memcached の Java 実装といえるでしょう。
本ブログエントリでは、memcached 用に作成したクライアントアプリケーションが、gemcached でも改変することなく動くということを確認したいと思います。また、最後に、何で gemcachd なの?というところを書きたいと思います。
1. memcached をビルドしてみる
当方、memcached は全く弄ったことがないので、ソースコードから Mac OS X 上でビルドして動かしてみましょうというところから始めたいと思います。
まずは、memcached のソースコード一式を以下の本家サイトからダウンロードしてきます。
#ちょうど昨日(2012/7/30)、v1.4.14 がリリースされたようです。
configure スクリプトが用意されているので、Mac OS X に Xcode(gcc とかが必要なんで) と MacPorts あたりをインストールしておきましょう。
さて、configure 実行!おっと、libevent がないと怒られました。では、MacPorts 使って libevent をインストールしましょう。
% sudo port install libevent
#なお、当方の場合、MacPorts の定義ファイルが古すぎと怒られたので事前に "sudo port selfupdate" の実行が必要でした。MacPorts 実行したの久々だったのがバレバレ。
それでもなお、configure 実行しても libevent がないと怒られたので、libevent のインストール箇所も明示的に設定してやったら通りました。最終的な configure のコマンドラインは以下です(/opt/memcached 配下へのインストールを想定)。
% ./configure --prefix=/opt/memcached --with-libevent=/opt/local
# libevent のインストール箇所は MacPorts の場合、/opt/local/lib 配下ですが、--with-libevent には /opt/local だけ指定することで通りました。
あとは、以下のコマンドでビルド・インストールです。
% make
% sudo make install
memcached の実行は超簡単です。インストールディレクトリ配下の bin に memcached という名前のバイナリができているので、ターミナルからデフォルト動作(リスンポート番号: 11211)で良ければ引数なしで実行するだけです。
Ctrl + C で終了します。オプションとかはドキュメントなり、引数 -h で memcached を実行するとでてきますので適宜好きなように弄りましょう。
2. Java で memcached クライアントを作ってみる
memcached はシンプルなプロトコルなので、telnet で接続して文字列を流してやれば動きますが、既存の Java ベースの Web アプリケーションのキャッシュとしてアクセスすることとか考えると、Java API が欲しくなりますね。まー、もう、すばらしい御仁がそういったものは開発済みでございます。今回は、そのうちの一つである Memcached-Java-Client を使用してみようと思います。まずソースコード一式を、以下の github サイトからダウンロードします。
https://github.com/gwhalin/Memcached-Java-Client
# ZIP ボタンを押せばよいようです。
ダウンロードしたものを展開すると、build.xml があるので何も考えずに ant でビルドしてやります。で、当方の環境の ant のバージョン(1.8.2)が悪いのか ant スクリプトがあれなのかわかりませんが、以下のようなファイルがいくつかできます。
memcached-${ver}.*
拡張子 jar なファイルが Memcached-Java-Client 本体です。気持ち悪いのでファイル名を memcached-2_0.jar(今回使用したもののバージョン 2.0 なんで)とか変更して所定の場所に配備し、CLASSPATH に通してクライアントアプリを実行すれば OK です。
クライアントアプリケーションは以下のサイト様のものをもろパクリ参考にして作成しました。
memcached client for java - Javaでmemcachedを使おう
memcached の Java の client
以下、当方のサンプルクライアントコードです。
MyMemCachedClient.java
#上述のサイト様のサンプルとは、Memcached-Java-Client のクラスのパッケージ名が違ってますね。
使用方法は以下のとおりです。
java quitada.MyMemCachedClient [memcached 稼働ホスト名 or IP]:[リスンポート]
memcached を引数無しで起動して、ローカルホストからアクセスする場合は以下の感じですね。
単に、10 個の key-value ペアなデータを memcached に set して、それらを get するだけの簡単なプログラムです。
何もしてないのに、set メソッドを実行すると標準出力にどさどさとログメッセージがでてきてうるさいなぁ。ant でビルドするときに、ロガーとして log4j を使うようにビルドすることができる風なので、そうした方がよいかも。
3. gemcached を起動して上述の Java クライアントを実行してみる
まずは、以下のサイト様の内容に従って vFabric GemFire のインストーラーのダウンロード・インストールを行います。
# GemFire 本体は pure java プロダクトなんで、Java がインストールされていれば、Mac OS X でも動きます。
で、必要なのはインストールしたディレクトリ配下の lib にある gemfire.jar のみです。
次に、gemcached 本体を以下のサイトからダウンロードしてきます。
# 2012 年 7 月現在、version 0.2 なので、ファイル名が gemcached-0.2.tar.gz。
ダウンロードした tar.gz ファイルを展開すると、以下のファイルが抽出されますので、所定の場所に配備します。
gemcached-{version}-RELEASE.jar
# 2012 年 7 月現在、version 0.2 なので、gemcached-0.2-RELEASE.jar。
これと上述の gemfire.jar を CLASSPATH に通して以下のコマンドを実行すると gemcached がコマンド実行ホストにてデフォルトのリスンポート(11212)で起動します。
以下のような起動スクリプトを用意しておくと、起動が楽でしょう。
#! /bin/sh export GEMFIRE=/opt/vFabric/vFabric_GemFire_663 export GEMCACHED=/opt/gemcached/lib/gemcached-0.2-RELEASE.jar java -cp $CLASSPATH:$GEMFIRE/lib/gemfire.jar:$GEMCACHED com.gemstone.memcached.GemFireMemcachedServer
ちなみに、上述のコマンドの引数として以下が用意されいて、リスンポートを変更可能とありますが…
-port=[リスンポート番号]
これを指定すると version 0.2 は以下の例外が出力されてリスンポートの設定、起動ができないようです。
Exception in thread "main" java.lang.NumberFormatException: For input string: "=11211" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:449) at java.lang.Integer.parseInt(Integer.java:499) at com.gemstone.memcached.GemFireMemcachedServer.getPort(GemFireMemcachedServer.java:184) at com.gemstone.memcached.GemFireMemcachedServer.main(GemFireMemcachedServer.java:165)
# -port= に指定したポート番号を parseInt する前に、"=" のトリムをし忘れているといった類いの、つまらないバグ風…。
とりあえず、デフォルトのリスンポートで起動したとして、標準出力に GemFire 由来のログメッセージがどさどさとでてきます。一通り起動が完了すると、最後のメッセージに gemcached の起動ホスト・リスンポートが表示されるので、それにそって上述の Java クライアントを実行してみます。たとえばこんな感じ。
java quitada.MyMemCachedClient 192.168.0.1:11212
おー、動きました。ということで、memcached 用に作成したクライアントコードを書き換えることなく、gemcached で動くことを確認しました。つまり、memcached をそのまま gemcached へ移行できるということですね。
4. なぜ gemcached なの? - memcached を gemcached へ移行する意義
vFabric GemFire は有償製品なので、それをベースとした gemcached を(特に商用システムで)使おうとすると有償となります(今回のように弄ってみるだけなら無償ですが)。そういう観点で見ると、memcached で動いているシステムをわざわざ gemcached へ移行するといったモチベーションはでてきません。
別の観点では、gemcached の作者である Swapnil 氏の以下のブログエントリ(英語)の、gemcached の優位点が魅力的にうつれば、gemcached を使用する意義はあるのではないかと思います。
Gemcached - Improved Memcached
かいつまんでお話しすると、GemFire 由来の機能を使って、フレキシブルにデータ格納ノードを設定できたり、混在クライアント環境でのデータ保全の実現、HA の実現、ダイナミックにノード追加・スケールができたりと、ミドルウェアとして memcached + αの価値を提供しますよということのようで。