単なるネタです。別に活用しようとか、そういうわけではないです。いつ使えなくなるとも限りませんし。
HazelcastがPayaraに同梱されていることと、設定まわりの実装を見ているとこの機能はオフにされていなさそうだったので。
Hazelcastには、Memcachedプロトコルを話す機能があります。
Memcache Client
http://docs.hazelcast.org/docs/3.4/manual/html-single/hazelcast-documentation.html#memcache-client
インメモリ・データグリッドって、Memcachedプロトコルを使えるものがけっこう多いですよね。Memcachedプロトコルのうち、だいたいのものはテキストプロトコルのみのサポートですが、Apache Igniteは珍しくバイナリプロトコルのみのサポートだったり(Coherenceも?)。
Hazelcastは、テキストプロトコルのみのサポートです。ただ、クラスタ化ができるので、分散構成で利用することができます。
では、ちょっと試してみましょう。
Payara MicroでHazelcastクラスタを構成する
まずはPayara Microをダウンロードします。
Downloads
http://www.payara.co.uk/downloads
で、特に何もアプリケーションをデプロイせず、2つNodeを起動してみます。
## Node 1 $ java -jar payara-micro-4.1.152.1.jar ## Node 2 $ java -jar payara-micro-4.1.152.1.jar --port 8180
HTTPリッスンポートはNode 2でずらしました。
この時、Hazelcastの機能でクラスタが構成されますが
Members [2] { Member [192.168.254.129]:5900 Member [192.168.254.129]:5901 this }
ここで表示されるポートが、Memcachedとして使えるポートになります。
また、Payara Microの起動引数「--startPort」で変えることもできます。以下の例だと、7000ポートになります。
--startPort 7000
今回は、デフォルトと自動インクリメントの結果である、5900、5901ポートを使います。
アクセスしてみる
では、telnetを使って試してみましょう。
コマンドは
## データの保存 # set key,flag,expires,byte # value ## データの取得 # get
なので、まずはNode 1にデータの保存、取得。
$ telnet localhost 5900 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set key1 0 120 6 value1 STORED get key1 VALUE key1 0 6 value1 END quit Connection closed by foreign host.
有効期限は、120秒。
続いて、Node 2側でNode 1で保存したデータを読み出して、さらにデータを追加してみます。
$ telnet localhost 5901 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get key1 VALUE key1 0 6 value1 END set key2 0 120 6 value2 STORED quit Connection closed by foreign host.
Node 2で追加したデータを、Node 1で読み出してみます。
$ telnet localhost 5900 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get key2 VALUE key2 0 6 value2 END quit Connection closed by foreign host.
OKそうですね。
Javaクライアントでも試してみましょう。
spymemcached
https://code.google.com/p/spymemcached/
Javadoc
http://www.couchbase.com/autodocs/couchbase-java-client-1.4.4/index.html
<dependency> <groupId>net.spy</groupId> <artifactId>spymemcached</artifactId> <version>2.11.7</version> </dependency>
テストコード。データを登録して、別のNodeから読み出すようなコードになっています。
package org.littlewings.memcached; import java.io.IOException; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import net.spy.memcached.MemcachedClient; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; public class MemcachedClientTest { @Test public void testSpyMemcachedClient() throws IOException, InterruptedException { MemcachedClient clientNode1 = new MemcachedClient(new InetSocketAddress("localhost", 5900)); MemcachedClient clientNode2 = new MemcachedClient(new InetSocketAddress("localhost", 5901)); clientNode1.set("key-from-node1", 5, "value-from-node1"); clientNode2.set("key-from-node2", 5, "value-from-node2"); TimeUnit.MILLISECONDS.sleep(100); // たまに読み出しに失敗する… assertThat(clientNode1.get("key-from-node2")) .asString() .isEqualTo("value-from-node2"); assertThat(clientNode2.get("key-from-node1")) .asString() .isEqualTo("value-from-node1"); TimeUnit.SECONDS.sleep(5); assertThat(clientNode1.get("key-from-node1")) .isNull(); assertThat(clientNode2.get("key-from-node2")) .isNull(); clientNode1.shutdown(); clientNode2.shutdown(); } }
こちらもOKです。が、データ登録後あまりもすぐに他Nodeにアクセスすると、たまにNGな時がありました…。
途中でNodeを減らしてみる
せっかくなので、Nodeを減らした時の挙動もみてみましょう。
まず、Node 1にデータ登録。
$ telnet localhost 5900 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set key1 0 120 6 value1 STORED set key2 0 120 6 value2 STORED quit Connection closed by foreign host.
Node 1をシャットダウンします。
当然、Node 2だけが残ります。
Members [1] { Member [192.168.254.129]:5901 this }
この状態で、Node 2にアクセスすると
$ telnet localhost 5901 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get key1 VALUE key1 0 6 value1 END get key2 VALUE key2 0 6 value2 END quit Connection closed by foreign host.
Node 1で登録したデータを、失われずに見ることができます。
Hazelcast側で、バックアップも持っているので。