こんにちは。kimukimuです。
Android4.0は。。。実機待ちです。
なので、Infinispanを実際的に使用するためのやり方を調べてみました。
1.実際に使用される状況ってどんな感じでしょうか?
Infinispanが実際に使用される環境を考えると、
『キャッシュサーバ』と、『キャッシュサーバを利用するプロセス』は
下の図のように別プロセスになる可能性が高いと考えています。
理由は、キャッシュサーバには複数のプロセスがアクセスするため。
1プロセス内でだけキャッシュにアクセスを行う場合なら、
機能的にはInfinispanはファイルに保存できるMapにすぎません。
なので、複数プロセスからInfinispanにアクセスする方法を確認します。
2.Infinispanをバッチから起動する方法
Infinispanを解凍したときに出来るbin配下にある「startServer.bat」を使用します。
#Linuxの場合は「startServer.sh」
中身は下記の通り。
■startServer.bat
setlocal enabledelayedexpansion set LIB= for %%f in (..\lib\*.jar) do set LIB=!LIB!;%%f for %%f in (..\modules\memcached\lib\*.jar) do set LIB=!LIB!;%%f for %%f in (..\modules\hotrod\lib\*.jar) do set LIB=!LIB!;%%f for %%f in (..\modules\websocket\lib\*.jar) do set LIB=!LIB!;%%f rem echo libs: %LIB% set CP=%LIB%;..\infinispan-core.jar;..\modules\core\infinispan-server-memcached.jar;%CP% set CP=..\modules\memcached\infinispan-server-memcached.jar;%CP% set CP=..\modules\hotrod\infinispan-server-hotrod.jar;%CP% set CP=..\modules\websocket\infinispan-server-websocket.jar;%CP% java -classpath "%CP%" -Dbind.address=127.0.0.1 -Djava.net.preferIPv4Stack=true -Dlog4j.configuration=..\etc\log4j.xml org.infinispan.server.core.Main %*
簡単に言ってしまうと、
ライブラリを読み込んで引数をMainクラスに渡して起動、というだけですね。
引数には起動形態、設定ファイルパスなどを与えることができます。
尚、このMainクラス、ファイルパス的には下記の場所に存在します。
/server/core/src/main/scala/org/infinispan/server/core/Main.scala
ええ。JavaではなくScalaです。
そんなわけで、最初Main.javaを探して見つかりませんでした^^;
Written in Javaとありますが、実際のところは「JVM言語」で書かれているようです。
Scalaは最近注目度が高まっていますが、こういうところでもつかわれているようですね。
で、実際に「外部からアクセス可能、設定ファイルを指定して起動」の場合は
下記のコマンドで実行します。
startServer.bat -r hotrod -c ..\config\infinispan-local.xml
ちなみに、今回用いた設定ファイルは下記の通り。
2つキャッシュを設定して、各々がファイルに出力する方式を取っています。
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:infinispan:config:5.0 http://www.infinispan.org/schemas/infinispan-config-5.0.xsd" xmlns="urn:infinispan:config:5.0"> <global> </global> <default> <!-- Configure a synchronous replication cache --> <clustering mode="local"> <sync /> </clustering> </default> <!-- localUserCacheという名称のキャッシュ設定 --> <namedCache name="localUserCache"> <clustering mode="local"> <async/> </clustering> <loaders passivation="false" shared="false" preload="true"> <loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="true" ignoreModifications="false" purgeOnStartup="false"> <properties> <property name="location" value="store" /> </properties> </loader> </loaders> </namedCache> <!-- localServiceCacheという名称のキャッシュ設定 --> <namedCache name="localServiceCache"> <clustering mode="local"> <async/> </clustering> <loaders passivation="false" shared="false" preload="true"> <loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="true" ignoreModifications="false" purgeOnStartup="false"> <properties> <property name="location" value="store" /> </properties> </loader> </loaders> </namedCache> </infinispan>
3.起動したInfinispanに対して外部からアクセスする方法
hotrodでInfinispanを起動したため、
次はhotrod-clientを用いて起動したInfinispanに対してアクセスを行います。
その際、modules/hotrod-client配下にある下記の2つのjarをライブラリに追加する必要があります。
infinispan-client-hotrod.jar
commons-pool-1.5.4.jar
値を設定するプログラムと、値を取得するプログラムに分けて記述します。
■InfinispanRemoteGetMain.java
package jp.gr.t3.infinispan.remote; import org.infinispan.Cache; import org.infinispan.client.hotrod.RemoteCacheManager; public class InfinispanRemoteGetMain { public static void main(String[] args) throws Exception { new InfinispanRemoteGetMain().run(); } public void run() { RemoteCacheManager cachemanager = new RemoteCacheManager("localhost"); Cache<String, InfinispanUser> userCache = cachemanager .getCache("localUserCache"); Cache<String, InfinispanService> serviceCache = cachemanager .getCache("localServiceCache"); int counter = 0; while (true) { InfinispanUser getUser = userCache.get("UserKey"); System.out.println("Get User : " + getUser); InfinispanService getService = serviceCache.get("ServiceKey"); System.out.println("Get Service : " + getService); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } counter++; } } }
■InfinispanRemotePutMain.java
package jp.gr.t3.infinispan.remote; import org.infinispan.Cache; import org.infinispan.client.hotrod.RemoteCacheManager; public class InfinispanRemotePutMain { public static void main(String[] args) throws Exception { new InfinispanRemotePutMain().run(); } public void run() { RemoteCacheManager cachemanager = new RemoteCacheManager("localhost"); Cache<String, InfinispanUser> userCache = cachemanager .getCache("localUserCache"); Cache<String, InfinispanService> serviceCache = cachemanager .getCache("localServiceCache"); int counter = 0; while (true) { InfinispanUser putUser = new InfinispanUser(); putUser.userId = "UserId" + Integer.toString(counter); putUser.userName = "UserName" + Integer.toString(counter + 1); userCache.put("UserKey", putUser); InfinispanService putService = new InfinispanService(); putService.serviceId = "ServiceId" + Integer.toString(counter * 2); putService.serviceName = "ServiceName" + Integer.toString(counter * 3); serviceCache.put("ServiceKey", putService); System.out.println("Put Counter : " + counter); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } counter++; } } }
すると、結果は下記のようになります。
■Put側
Put Counter : 0 Put Counter : 1 Put Counter : 2 Put Counter : 3 Put Counter : 4 Put Counter : 5 Put Counter : 6 Put Counter : 7 Put Counter : 8 Put Counter : 9 Put Counter : 10 Put Counter : 11
■Get側
Get User : UserId=UserId1,UserName=UserName2 Get Service : ServiceId=ServiceId2,ServiceName=ServiceName3 Get User : UserId=UserId2,UserName=UserName3 Get Service : ServiceId=ServiceId4,ServiceName=ServiceName6 Get User : UserId=UserId3,UserName=UserName4 Get Service : ServiceId=ServiceId6,ServiceName=ServiceName9 Get User : UserId=UserId4,UserName=UserName5 Get Service : ServiceId=ServiceId8,ServiceName=ServiceName12 Get User : UserId=UserId5,UserName=UserName6 Get Service : ServiceId=ServiceId10,ServiceName=ServiceName15 Get User : UserId=UserId6,UserName=UserName7 Get Service : ServiceId=ServiceId12,ServiceName=ServiceName18 Get User : UserId=UserId7,UserName=UserName8 Get Service : ServiceId=ServiceId14,ServiceName=ServiceName21 Get User : UserId=UserId8,UserName=UserName9 Get Service : ServiceId=ServiceId16,ServiceName=ServiceName24
これで、複数プロセスからサーバとして立ち上げたInfinispanにアクセスすることが確認できました。
また、その際に複数のキャッシュに別途アクセスできることも確認できました。
4.何が嬉しいの?
一番良くあるモデルだと思われる、下記のモデルが実現できるようになります。
Infinispanをサーバとして起動
多数のクライアントプロセスから必要な分だけアクセス
複数プロセス間でのデータ共有がマップに対するGet/Putだけで
出来るようになるわけです。
これなら、いろんな場面で実際に使えそうですね。