今までずっとEmbedded CacheでInfinispanを使っていましたが、そろそろInfinispanを単独で起動して、クライアントプログラムからInfinispanを使うことにトライしたいと思います。
まずは、Infinispanをダウンロード。
https://www.jboss.org/infinispan/downloads
いつの間にか、5.2.1.Finalが出ています…。
とりあえず、落としたZIPファイルを展開。
$ unzip infinispan-5.2.1.Final-all.zip $ cd infinispan-5.2.1.Final-all $ ll 合計 2492 drwxr-xr-x 8 xxxxx xxxxx 4096 Feb 8 16:50 ./ drwxrwxr-x 3 xxxxx xxxxx 4096 Feb 10 17:36 ../ -rw-r--r-- 1 xxxxx xxxxx 1553 Feb 8 16:46 Copyright.txt -rw-r--r-- 1 xxxxx xxxxx 2213 Feb 8 16:46 README-Demo.txt -rw-r--r-- 1 xxxxx xxxxx 5409 Feb 8 16:49 README-EC2-demo.txt -rw-r--r-- 1 xxxxx xxxxx 537 Feb 8 16:46 README-Modules.txt -rw-r--r-- 1 xxxxx xxxxx 1618 Feb 8 16:49 README-NearCache-demo.txt -rw-r--r-- 1 xxxxx xxxxx 2416 Feb 8 16:49 README-distexec-demo.txt -rw-r--r-- 1 xxxxx xxxxx 966 Feb 8 16:46 README.txt drwxr-xr-x 2 xxxxx xxxxx 4096 Feb 8 16:50 bin/ drwxr-xr-x 4 xxxxx xxxxx 4096 Feb 8 16:50 doc/ drwxr-xr-x 6 xxxxx xxxxx 4096 Feb 8 16:50 etc/ -rw-r--r-- 1 xxxxx xxxxx 2471912 Feb 8 16:23 infinispan-core.jar drwxr-xr-x 2 xxxxx xxxxx 12288 Feb 8 16:50 lib/ drwxr-xr-x 2 xxxxx xxxxx 4096 Feb 8 16:50 licenses/ drwxr-xr-x 17 xxxxx xxxxx 4096 Feb 8 16:50 modules/ -rw-r--r-- 1 xxxxx xxxxx 395 Feb 8 16:23 runtime-classpath.txt
$ bin/startServer.sh --help usage: startServer [options] options: -h, --help Show this help message -V, --version Show version information -- Stop processing options -p, --port=<num> TCP port number to listen on (default: 11211 for Memcached, 11222 for Hot Rod and 8181 for WebSocket server) -l, --host=<host or ip> Interface to listen on (default: 127.0.0.1, localhost) -t, --worker_threads=<num> Number of threads processing incoming requests and sending responses (default: 20 * number of processors) -c, --cache_config=<filename> Cache configuration file (default: creates cache with default values) -r, --protocol= Protocol to understand by the server. This is a mandatory option and you should choose one of these options [memcached|hotrod|websocket] -i, --idle_timeout=<num> Idle read timeout, in seconds, used to detect stale connections (default: -1). If no new messages have been read within this time, the server disconnects the channel. Passing -1 disables idle timeout. -n, --tcp_no_delay=[true|false] TCP no delay flag switch (default: true). -s, --send_buf_size=<num> Send buffer size (default: as defined by the OS). -e, --recv_buf_size=<num> Receive buffer size (default: as defined by the OS). -o, --proxy_host=<host or ip> Host address to expose in topology information sent to clients. If not present, it defaults to configured host. Servers that do not transmit topology information ignore this setting. -x, --proxy_port=<num> Port to expose in topology information sent to clients. If not present, it defaults to configured port. Servers that do not transmit topology information ignore this setting. -k, --topo_lock_timeout=<num> Controls lock timeout (in milliseconds) for those servers that maintain the topology information in an internal cache. -u, --topo_repl_timeout=<num> Sets the maximum replication time (in milliseconds) for transfer of topology information between servers. If state transfer is enabled, this setting also controls the topology cache state transfer timeout. If state transfer is disabled, it controls the amount of time to wait for this topology data to be lazily loaded from a different node when not present locally. This value should be set higher than 'topo_lock_timeout' to allow remote locks to be acquired within the time allocated to replicate the topology. -a, --topo_state_trasfer= Enabling topology information state transfer means that when a server starts it retrieves this information from a different node. [true|false] Otherwise, if set to false, the topology information is lazily loaded if not available locally. -d, --topo_update_timeout=<num> Sets the maximum time (in milliseconds) to wait for topology information to be updated. This value should be set higher than 'topo_repl_timeout' to allow retries to happen if a replication timeout is encountered. -f, --cache_manager_class=<clazz> Cache manager class name to be used instead of the default one (it has to extend org.infinispan.manager.EmbeddedCacheManager). -D<name>[=<value>] Set a system property
binディレクトリにはその他サンプルアプリケーションの起動スクリプトがあったり、etcディレクトリには設定ファイルのサンプルがあったりすので、必要に応じて見てみるとよいと思います。
では、起動してみます。
$ bin/startServer.sh ERROR: Please indicate protocol to run with -r parameter usage: startServer [options] options: -h, --help 〜省略〜
「-rパラメータは必須だよ」と怒られました。「-r」は、通信に使うプロトコルを指定するパラメータです。
-r, --protocol= Protocol to understand by the server. This is a mandatory option and you should choose one of these options [memcached|hotrod|websocket]
ヘルプによると、
プロトコル | パラメータ値 | デフォルトポート |
Memcached | memcached | 11211 |
Hot Rod | hotrod | 11222 |
WebSocket | websocket | 8181 |
ということになるようです。その他、modulesにあるWARファイルを使用することで、RESTサーバとしても使える模様。
まずはMemcachedで試してみようと思ったのですが、Mavenリポジトリ上で使えるクライアントが…な感じだったので、ここはいきなりHot Rodにすることにしました。
Hot Rodは、Javaから使えるバイナリプロトコルらしいです。
https://docs.jboss.org/author/display/ISPN/Java+Hot+Rod+client
Hot Rod Clientを使ってみる
それでは、試してみましょう。
build.sbt
name := "infinispan-remote" version := "0.0.1" scalaVersion := "2.10.0" organization := "littlewings" resolvers += "JBoss Public Maven Repository Group" at "http://repository.jboss.org/nexus/content/groups/public-jboss/" libraryDependencies += "org.infinispan" % "infinispan-client-hotrod" % "5.2.1.Final"
src/main/scala/HotRodClient.scala
import org.infinispan.client.hotrod.{RemoteCache, RemoteCacheManager} object HotRodClient { def main(args: Array[String]): Unit = { val manager: RemoteCacheManager = new RemoteCacheManager("localhost:11222") // デフォルトポートを使うなら、以下でOK // val manager: RemoteCacheManager = new RemoteCacheManager("localhost") val cache: RemoteCache[String, Integer] = manager.getCache() val keys = (1 to 3) map (i => s"key$i") keys foreach (k => println(s"key[$k] => value[${cache.get(k)}]")) keys foreach (k => cache.get(k) match { case null => cache.put(k, 1) case v => cache.put(k, v.toInt + 1) }) keys foreach (k => println(s"key[$k] => value[${cache.get(k)}]")) } }
キャッシュの値をIntegerにして、単純にインクリメントしていくサンプルです。
では、InfinispanをHot Rodで起動。
$ bin/startServer.sh -r hotrod
プログラムを動かしてみます。
> run [info] Running HotRodClient 2 10, 2013 6:09:33 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final key[key1] => value[null] key[key2] => value[null] key[key3] => value[null] key[key1] => value[1] key[key2] => value[1] key[key3] => value[1] [success] Total time: 2 s, completed 2013/02/10 18:09:33 > run [info] Running HotRodClient 2 10, 2013 6:09:37 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final key[key1] => value[1] key[key2] => value[1] key[key3] => value[1] key[key1] => value[2] key[key2] => value[2] key[key3] => value[2] [success] Total time: 1 s, completed 2013/02/10 18:09:37 > run [info] Running HotRodClient 2 10, 2013 6:09:39 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final key[key1] => value[2] key[key2] => value[2] key[key3] => value[2] key[key1] => value[3] key[key2] => value[3] key[key3] => value[3] [success] Total time: 1 s, completed 2013/02/10 18:09:39
1回目は値がnullですが、実行を繰り返すにしたがって値がインクリメントされていきます。
プログラムが終了しても値がInfinispanに保持されたままですが、今回は別プロセスで起動しているので、そりゃそうですよね、と。
Infinispanを止める時は、とりあえずCtrl-Cで。
名前付きキャッシュを使う
今度は、名前付きキャッシュを使ってみます。キャッシュ取得の部分をこう変更して
val cache: RemoteCache[String, Integer] = manager.getCache("namedCache")
実行すると
> run [info] Running HotRodClient 2 10, 2013 6:18:55 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final 2 10, 2013 6:18:55 午後 org.infinispan.client.hotrod.impl.protocol.Codec10 checkForErrorsInResponseStatus WARN: ISPN004005: Error received from the server: org.infinispan.server.hotrod.CacheNotFoundException: Cache with name 'namedCache' not found amongst the configured caches
「そんな名前のキャッシュ、知らないよ」と怒られました…。RemoteCacheの場合は、あらかじめ定義しておく必要があるみたいですね。
というわけで、サーバ側に設定ファイルを作ります。1度Infinispanを終了して
$ bin/startServer.sh -r hotrod -c etc/infinispan-remote.xml
「-c」オプションを付けて作った設定ファイルのパスを指定して起動します。
設定ファイルの内容は最小設定で、これだけです。
<?xml version="1.0" encoding="UTF-8"?> <infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:infinispan:config:5.2 http://www.infinispan.org/schemas/infinispan-config-5.2.xsd" xmlns="urn:infinispan:config:5.2"> <namedCache name="namedCache" /> </infinispan>
では、再度実行。
> run [info] Running HotRodClient 2 10, 2013 6:24:40 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final key[key1] => value[null] key[key2] => value[null] key[key3] => value[null] key[key1] => value[1] key[key2] => value[1] key[key3] => value[1] [success] Total time: 1 s, completed 2013/02/10 18:24:41 > run [info] Running HotRodClient 2 10, 2013 6:24:42 午後 org.infinispan.client.hotrod.RemoteCacheManager start INFO: ISPN004021: Infinispan version: Infinispan 'Delirium' 5.2.1.Final key[key1] => value[1] key[key2] => value[1] key[key3] => value[1] key[key1] => value[2] key[key2] => value[2] key[key3] => value[2] [success] Total time: 0 s, completed 2013/02/10 18:24:42
今度は、うまくいきました。