Infinispanでクラスタを構成する際のNode Discoveryの方法のひとつとして、JGroupsのGossip Routerを使ってみます。
こちらを使うことで、クラスタに参加するNodeを探索するNode Discoveryの仕組みを、Gossip Routerで行うことができます。
Gossip Routerとは?
Gossip Routerについては、こちらに記載があります。
JGroupsGossipRouter |JBoss Developer
もともとは、クラスタにいるNodeがファイアーウォールがあるなど事情で、直接Node間で接続できない場合に利用するようです。
その代替として、各NodeはGossip Routerとさえ通信できればよい、という感じみたいです。
Gossip Routerそのものは、クラスタを構成するNodeとは別の、単独のプロセスです。JGroupsのJARの中に含まれています。
この目的の場合、TUNNELプロトコルを使用して、Gossip Router越しにNode間のやり取りをするようです。
通信自体には、TCPを使用するようですね。
で、これはクラスタ内の通信に制限がある場合に、どうにかするためにGossip Routerを使用するようなのですが、
Node Discovertyだけでも使用することができます。
これが、TCPGOSSIPです。
Node Discoveryでは、マルチキャストを使ったPING、TCPでの接続先を並べるTCPPINGなどがありますが、TCPGOSSIPの場合はGossip Routerへの
接続先を並べることになります(initial_hosts)。
あとは、接続タイムアウトや再接続の間隔などを設定することができます。
クラウド環境ではマルチキャストが使えないものが多いので、それ以外の手段でNode Discoveryを行う必要がありますが、
その選択肢のひとつとして上がっています。
ところで、利用するGossip Routerはinitial_hostsで指定するのですが、初期の接続先というより、実行時にそれ以上増やせないですよね…?
実際に使う時には、複数のGossip Routerを使用して、プロセスダウンとかに備えるのかなぁと思います。
Gossip Routerを使って、Infinispan Serverでクラスタを構成してみる
それでは、Gossip Routerを使ってInfinispan Serverのクラスタを構成してみましょう。
$ java -version openjdk version "1.8.0_171" OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.18.04.1-b11) OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
JGroupsは4.0.13を使い、Infinispan Serverは9.3.1.Finalを使用します。
クラスタに参加するNodeや、Gossip Routerの情報は以下の通り。
- Gossip Router … 3つ(172.17.0.2〜4)
- Infinispan Server … 3 Node(172.17.0.5〜7) ※ホスト名は、infinispan1〜3としました
準備
まず、JGroupsをダウンロードしてきて、Gossip Routerを起動します。「org.jgroups.stack.GossipRouter」を指定して起動してあげれば、OKです。
## Gossip Router 1 $ wget https://search.maven.org/remotecontent?filepath=org/jgroups/jgroups/4.0.13.Final/jgroups-4.0.13.Final.jar -O jgroups.jar $ java -cp jgroups.jar org.jgroups.stack.GossipRouter ## Gossip Router 2 $ wget https://search.maven.org/remotecontent?filepath=org/jgroups/jgroups/4.0.13.Final/jgroups-4.0.13.Final.jar -O jgroups.jar $ java -cp jgroups.jar org.jgroups.stack.GossipRouter ## Gossip Router 3 $ wget https://search.maven.org/remotecontent?filepath=org/jgroups/jgroups/4.0.13.Final/jgroups-4.0.13.Final.jar -O jgroups.jar $ java -cp jgroups.jar org.jgroups.stack.GossipRouter
Gossip Routerの起動引数は今回指定しませんが、起動クラスであるGossipRouterクラスのフィールドは、起動引数でいろいろ設定することができます。
http://www.jgroups.org/javadoc4/org/jgroups/stack/GossipRouter.html
オプションの指定方法は、ソースコードを参照することになるでしょう。
https://github.com/belaban/JGroups/blob/JGroups-4.0.13.Final/src/org/jgroups/stack/GossipRouter.java#L545-L589
ログ出力などは特にしていませんが、Docker HubにあるGossip RouterはApache Log4j2を使ってログ出力するように設定されているので、こちらを
参考にしてもよいでしょう。
JGroups Gossip Router Docker Image
Infinispan Serverは、各Nodeでzipファイルを展開しておきます。
$ unzip infinispan-server-9.3.1.Final.zip
$ cd infinispan-server-9.3.1.Final
起動
では、Infinispan ServerをGossip Routerを使うようにして起動してみましょう。
クラスタ構成とすることができる設定ファイル、「clustered.xml」にはすでにGossip Routerを使う設定が含まれています。
https://github.com/infinispan/infinispan/blob/9.3.1.Final/server/integration/jgroups/src/main/resources/subsystem-templates/infinispan-jgroups.xml#L45-L63
他にUDPとTCPもありますが、これがデフォルトで「udp」stackを選択するようになっています。
https://github.com/infinispan/infinispan/blob/9.3.1.Final/server/integration/jgroups/src/main/resources/subsystem-templates/infinispan-jgroups.xml#L10
これは、システムプロパティ「jboss.default.jgroups.stack」で「tcp-gossip」を指定することで、stackを切り替えることができます。
また、TCPGOSSIPの場合は「initial_hosts」を指定する必要がありますが、これはシステムプロパティ「groups.gossip.initial_hosts」で指定することができます。
https://github.com/infinispan/infinispan/blob/9.3.1.Final/server/integration/jgroups/src/main/resources/subsystem-templates/infinispan-jgroups.xml#L48
「initial_hosts」の書式は、以下の通りです。
## 単数 host[port] ## 複数 host[port],host[port],host[port]
以上を踏まえると、各Infinispan Serverの起動引数は、以下のようになります。
## Node 1 $ bin/standalone.sh -c clustered.xml -Djboss.bind.address=172.17.0.5 -Djboss.default.jgroups.stack=tcp-gossip -Djgroups.gossip.initial_hosts=172.17.0.2[12001],172.17.0.3[12001],172.17.0.4[12001] ## Node 2 $ bin/standalone.sh -c clustered.xml -Djboss.bind.address=172.17.0.6 -Djboss.default.jgroups.stack=tcp-gossip -Djgroups.gossip.initial_hosts=172.17.0.2[12001],172.17.0.3[12001],172.17.0.4[12001] ## Node 3 $ bin/standalone.sh -c clustered.xml -Djboss.bind.address=172.17.0.7 -Djboss.default.jgroups.stack=tcp-gossip -Djgroups.gossip.initial_hosts=172.17.0.2[12001],172.17.0.3[12001],172.17.0.4[12001]
これで、クラスタが構成されます。
2018-08-05 10:00:14,884 INFO [org.infinispan.CLUSTER] (jgroups-11,infinispan1) ISPN000094: Received new cluster view for channel cluster: [infinispan1|2] (3) [infinispan1, infinispan2, infinispan3]
ispn-cliで確認する場合。
$ bin/ispn-cli.sh -c [standalone@localhost:9990 /] /subsystem=datagrid-infinispan/cache-container=clustered:read-attribute(name=members) { "outcome" => "success", "result" => "[infinispan1, infinispan2, infinispan3]" }
1度クラスタが構成された後は、Gossip RouterがダウンしていてもNodeがクラスタから離脱することはありません(もちろん、Node本体が落ちたりしたら
別ですが)。
また、「initial_hosts」で指定したGossip Routerは、すべてが接続可能である必要はなく、どれかが起動していれば機能してくれます。「initial_hosts」に
列挙されていても起動していないGossip Routerがあっても、あとで起動すれば検出してくれます。
例えば、クラスタ構成 → Gossip Router全ダウン → クラスタにNode追加(Gossip Routerがないのでクラスタ参加できず) → Gossip Router復旧…という
ステップを踏むと、あとで追加したNodeもしばらくするとGossip Routerを検出してクラスタに参加してくれます。
Embedded Modeの場合
Embedded Mode用のデフォルトのTCPGOSSIP用の設定ファイルは作成されていませんが、TCP用のものを参考に、MPINGの部分をTCPGOSSIPに変更したものを
作成すればよいと思います。
https://github.com/infinispan/infinispan/blob/9.3.1.Final/core/src/main/resources/default-configs/default-jgroups-tcp.xml