memcached の Java の client

memcached は分散キャッシュ機構だけど、それを実現しているのはあくまでクライアント側によって。ということで、クライアントも重要なんだろう。


プロトコルが単純なだけに、クライアントも各言語いろいろ実装されている。(memcached の開発元の danga も把握していない独自のクライアント実装も一杯ある)

とりあえず、danga で Java client を探す。

A Java API is maintained by Greg Whalin from Meetup.com. You can find that library here:


http://www.whalin.com/memcached/ -- Java API for memcached


An improved Java API maintained by Dustin Sallings is also available. Aggressively optimised, ability to run async, supports binary protocol, etc. See site for details:


http://bleu.west.spy.net/~dustin/projects/memcached/ -- Improved Java API for memcached

http://www.danga.com/memcached/apis.bml

「Aggressively optimised」とかアツイこと書いてるなー。単純にシリアライズしたやつをストアするんじゃなくて、可能な限り小さくしたものを入れますとか。同じ人(?)が作った、
http://bleu.west.spy.net/~dustin/projects/spyjar/

これを内部で使用して、シングルインスタンスで非同期にリクエストを受付し、ちょっとしたキューイングもやっているようだ。アプリケーションサーバから使う場合はこれらの処理は必須と思う。

とりあえず、com.danga.MemCached の方を使ってみた。私のcore2duoのノートパソコンにmemcachedインスタンスを2つ3つ起動し、以下のような適当なテスト用コードで、動かしてみる。

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;


public class Main {
	public static void main(String args[]) {
		System.out.println("memcached");
		SockIOPool pool = SockIOPool.getInstance();
		pool.setServers(new String[]{
//				"localhost:11211",
				"localhost:11212",
				"localhost:11213",
				});
		pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);
		pool.initialize();
		
		MemCachedClient mc = new MemCachedClient();
		for (int i=0; i< 1000000; i++) {
			int[] name = (int[])mc.get("name" + i);
			if (name == null) {
				int[] a = {i, 1,2,3,4,5,6,7,8,9,10};
				mc.set("name" + i, a);
			}
			if (i % 1000 == 0) System.out.println(i);
//			System.out.println(mc.get("name" + i));
		}
	}
}

動かしてみると、大体一件のget,setあたり 0.23ms 程度で動作する。
ただ、この数字、top で cpu 使用率を確認すると、上記javaクライアントが cpu 時間の8割を使用し、memcached 2 つが残りの2割を分け合っているという状態。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                
13725 kamei     20   0  736m 100m 7252 S   77  5.0   2:06.33 java                                   
13502 kamei     20   0 45388  42m  568 S   11  2.1   0:16.70 memcached                              
13501 kamei     20   0 44360  41m  568 S   10  2.1   0:16.02 memcached

巷でいわれる、「memcached は cpu あんま使わない」って話に納得。


別マシンのmemcachedにも振り分けてみたが、不思議なことにかえってcpu使用率が下がってしまった(速度もそれに伴い低下)。ネットワークの帯域を使い切ったとも思えないんだけどなー。別マシンはかなりマシン性能は低いのだが、そちらも cpu 使用率は低いまま。。。この辺はちょっと謎。


時間があったら、spy 版も試して見たい所だけど。