株式会社ミクシィの前坂です。第1回でmemcached 1.4の簡単な紹介をしました。今回は新しく正式導入されたバイナリプロトコルの扱い方をご紹介いたします。
バイナリプロトコルの扱い
バイナリプロトコルを扱うには,アプリケーションのプログラミング言語に合ったバイナリプロトコル対応のクライアントライブラリが必要です。バイナリプロトコルは最近導入されたこともあり,ネイティブ対応していると報告されているクライアントライブラリはC言語のlibmemcachedとJavaのspymemcachedだけです(2009年8月時点)。ただし,世の中にはlibmemcachedをwrapした,さまざまの言語で記述されたクライアントライブラリがいくつかあり,それらを使ってバイナリプロトコルを扱うことが可能です。
今回の記事ではそれらのクライアントも含めて, C,Java,Python,PHPでのデモコードを紹介いたします。
バイナリプロトコルを扱うデモコード
バイナリプロトコルを扱うにはバイナリモードに適応するというコードを1行追加するだけで, ほとんどの場合は従来のテキストプロトコルと扱いは変わりません。以下が今回の検証に使ったクライアントライブラリ集です。
デモコードはmemcachedがlocalhostのデフォルトポート(11211)に立ち上がっている事を想定しており,単純に1つのレコードをSET/GETします。
libmemcached(C言語)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libmemcached/memcached.h>
int main(int argc, char **argv) {
memcached_st *memc = NULL;
memcached_return rv;
const char *key = "some_key";
const char *val = "this is a value";
int data;
if ((memc = memcached_create(NULL)) == NULL) {
fprintf(stderr, "failed to allocate memory\n");
return 1;
}
rv = memcached_server_add(memc, "localhost", 11211);
if (rv != MEMCACHED_SUCCESS) {
fprintf(stderr, "failed to set server\n");
return 1;
}
rv = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, data);
if (rv != MEMCACHED_SUCCESS) {
fprintf(stderr, "failed to enable binary protocol\n");
return 1;
}
rv = memcached_set(memc, key, strlen(key), val, strlen(val), 0, 0);
if (rv != MEMCACHED_SUCCESS) {
fprintf(stderr, "failed to set record\n");
return 1;
}
char *result;
uint32_t flags;
size_t result_length;
result = memcached_get(memc, key, strlen(key), &result_length, &flags, &rv);
if (rv != MEMCACHED_SUCCESS) {
fprintf(stderr, "failed to fetch record\n");
return 1;
}
printf("Key: %s\n", key);
printf("Fetched: %s\n", result);
printf("Data Length: %d\n", (int)result_length);
free(result);
memcached_free(memc);
return 0;
}
spymemcached(Java)
import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.MemcachedClient;
public class BinaryProtocolExample {
public static void main(String[] args) {
MemcachedClient memc = null;
try {
memc = new MemcachedClient(new BinaryConnectionFactory(),
AddrUtil.getAddresses("localhost:11211"));
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
memc.set("some_key", 0, "this is a value");
System.out.println(memc.get("some_key"));
memc.shutdown();
}
}
pylibmc(Python)
#!/usr/bin/python
import sys
import pylibmc
memc = pylibmc.Client(["localhost:11211"])
if memc is None:
print "failed to create client"
exit(1)
memc.behaviors["binary_protocol"] = 1;
if memc.set("some_key", "this is a value") is None:
print "failed to set record"
exit(1)
print memc.get("some_key")
PECL memcached(PHP)
<?php
$memc = new Memcached();
if (!$memc) {
echo("failed to instantiate memcached object\n");
exit(1);
}
$memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memc->addServer('localhost', 11211);
if (!$memc->set('some_key', 'this is a value')) {
echo("failed to set an item\n");
exit(1);
}
echo($memc->get('some_key') . "\n");
?>

