memcached client for Java + kumofs 0.3.4 での接続確認

引き続きkumofsネタ。Twitter上で色々助けてもらってるのでブログに書かなければなるまい。

天の助け

古橋さん(id:viver@frsyuki、kumofsの作者)
  |l、{   j} /,,ィ//|     / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  i|:!ヾ、_ノ/ u {:}//ヘ     | あ…ありのまま 今 起こった事を話すぜ!
  |リ u' }  ,ノ _,!V,ハ |     < 『kumofsとmemcached client for Javaの
  fト、_{ル{,ィ'eラ , タ人.    |  組み合わせではプログラムが動かないと
 ヾ|宀| {´,)⌒`/ |<ヽトiゝ   |  Twitterでつぶやいていたら いつのまにか
  ヽ iLレ  u' | | ヾlトハ〉.   |  動作するようにkumofs自体が改良されていた』
   ハ !ニ⊇ '/:}  V:::::ヽ. │ 催眠術だとか超スピードだとか(ry
  /:::丶'T'' /u' __ /:::::::/`ヽ \____________________

kumo-gateway -Fオプションの実装およびmemcached client for Javaの変なクセ(電文に余計なスペースが付けられてしまう)への対応をして頂きました。ありがとうございますありがとうございます><

@zopeさん

同様に悶絶していたのを拾ってくれたらしく、以下の情報を教えて頂いた。

@terurou いまさらかもですがkumofsでMemcached-Java-Clientを使う時はMemCachedClient#setPrimitiveAsString(true)を設定すると使えますよ。

http://twitter.com/zope/status/12622952828

@terurou あと、MemCachedClient#setCompressEnable(),setSanitizeKeys()はfalseに設定しておいた方がいいと思います。

http://twitter.com/zope/status/12626355186

もしかしてオプションを設定するとflagsが付かなくなる・・・?コードを流し見た感じではそんな風には見えなかったけど・・・。

動作確認

kumo-gateway -Fを試す(kumofs >= 0.3.4 が必要)

以下がmemcached client for Javaを使ったkumofs接続テストコードである。

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

public class Main {

    public static void main(String[] args) {
        SockIOPool pool = SockIOPool.getInstance();
        pool.setServers(new String[]{"localhost:11222"});
        pool.initialize();

        MemCachedClient mcc = new MemCachedClient();

        // 値をセット
        boolean result = mcc.set("foo", "hoge");
        System.out.println(result);

        // 値を取得して表示
        System.out.println((String) mcc.get("foo"));
    }
}

-Fオプションを付けずにkumo-gatewayを起動し、テストコードを実行すると以下のような結果になった。正常に動作していない。

false
null

-Fオプションを付けてkumo-gatewayを起動し、同様に実行すると以下のような結果になった。今度は正常に動作している。

true
hoge

kumo-gateway -Fであればmemcached client for Javaが動作することを確認できた。

memcached client for Javaのオプションを試してみる

先程のテストコードにsetPrimitiveAsString(true)、setSanitizeKeys(false)、setCompressEnable(false)を追加した。

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

public class Main {

    public static void main(String[] args) {
        SockIOPool pool = SockIOPool.getInstance();
        pool.setServers(new String[]{"localhost:11211"});
        pool.initialize();

        MemCachedClient mcc = new MemCachedClient();

        // コレを追加
        mcc.setPrimitiveAsString(true);
        mcc.setSanitizeKeys(false);
        mcc.setCompressEnable(false);

        // 値をセット
        boolean result = mcc.set("test", "テスト");
        System.out.println(result);

        // 値を取得して表示
        System.out.println((String) mcc.get("test"));
    }

}

-Fオプションを付けずにkumo-gatewayを起動しテストコードを実行してみたところ、以下のような結果になった。正常に動作していないようだ。

false
null

いったんkumo-gatewayを停止してから以下のようなコマンドを実行し、クライアントからのメッセージをダンプしてみる。

nc -l 11211 > log.txt

やはりflagsをOFFにするオプションではないようだ。やはりkumo-gatewayに-Fオプションは必須な模様。

set test 32 0 9      
テスト

では先程のオプションは何なのかとダンプを取りながらコードを書いていたら違いがわかった。要はintやらの値をテキストとして保存するかバイナリとして保存するかを設定するオプションのようだ。Java以外の言語からもkumofsを利用したい場合に必須なオプションらしい。(参考: java で memcached に入れたものを ruby で取り出す (その逆も) - Learning to be Me

追記

指摘いただいた件は、どうやらmemcached client for Javaのバージョン間の差異だった模様。

何故かなと思ったらclientが2.5.0で大幅に書き変わっているのですね。ざっとソース読んだ感じですが2.5.0以降だとflagが設定されてしまいますね。2.0.1ではflagは設定されていなかったのですが…

http://twitter.com/zope/status/12684206336

結論

memcached client for Java + kumofsを使う場合、以下のようにする。

  • kumofs >= 0.3.4を使う
  • kumo-gatewayを-Fオプション付きで起動する
  • クライアントコードは以下のように書く
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

public class Main {

    public static void main(String[] args) {
        SockIOPool pool = SockIOPool.getInstance();
        pool.setServers(new String[]{"localhost:11211"});
        pool.initialize();

        MemCachedClient mcc = new MemCachedClient();

        // テキストとして値を保存する
        mcc.setPrimitiveAsString(true);
        mcc.setSanitizeKeys(false);
        mcc.setCompressEnable(false);

        // 値をセット
        boolean result = mcc.set("test", "テスト");
        System.out.println(result);

        // 値を取得して表示
        System.out.println((String) mcc.get("test"));
    }

}