CLOVER🍀

That was when it all began.

Docker Composeで、Apache Geodeの簡単なクラスタ環境を構築する

1.0.0-incubatingがリリースされて久しいApache Geodeですが、クラスタ環境を簡単に構築するような
Docker Composeを書いてみようかなと思いまして。

あくまで手元で簡単に確認したいがための内容なので、あんまりがっちりとした内容ではありません。

次のことをやります。

  • Dockerイメージは、Apache Geode提供のものを使う
  • LocatorとServerでコンテナを分ける
  • Locatorは、とりあえずひとつ
  • Serverは複数起動可能にする
  • Cache XMLは、volumeでコンテナ外から与える

Apache GeodeのDockerイメージは、こちら。

apachegeode/geode

で、できあがったファイルはこちら。
docker-compose.yml

version: "3"
services:
  locator:
    image: apachegeode/geode:1.0.0-incubating
    container_name: geodelocator
    hostname: geodelocator
    ports:
      - "10334:10334"
      - "40404:40404"
      - "1099:1099"
      - "7070:7070"
    command: sh -c "gfsh start locator --name=locator-`hostname` && tail -f /locator-`hostname`/locator-`hostname`.log"
  server:
    image: apachegeode/geode:1.0.0-incubating
    depends_on:
      - locator
    links:
      - locator
    volumes:
      - ./cache.xml:/cache.xml:ro
    command: >
      bash -c 'until gfsh start server --name=server-`hostname` --bind-address=`hostname -i` --locators=geodelocator[10334] --cache-xml-file=/cache.xml;\
               do \
                 sleep 3; \
               done && \
               tail -f /server-`hostname`/server-`hostname`.log'

ポイントは、次のあたり。

  • Serverが起動するにはLocatorが必要なので、Locatorのホスト名をとりあえず固定に
  • Locatorの起動は割と重く、Serverが先に起動すると接続に失敗するので、その時は3秒スリープしてリトライする
  • Serverのbind-addressをIPアドレスで明示(クライアントがDockerコンテナのホスト名でアクセスしにいこうとするので)

あと、Locatorの10334ポートはホスト側からも使えるようにしました。

けっこう困ったのがLocatorとServerの起動順序なのですが、depends_onではコンテナの起動順は制御できても、
中身の待ち合わせはできないのでこのような形になりました。

参考にしたのは、こちら。

Controlling startup order in Compose

Compose の起動順番を制御 — Docker-docs-ja 17.06.Beta ドキュメント

では、起動してみましょう。

動作確認用に、Cache XMLを用意。
cache.xml

<?xml version="1.0" encoding="UTF-8"?>
<cache
    xmlns="http://geode.apache.org/schema/cache"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://geode.apache.org/schema/cache
                        http://geode.apache.org/schema/cache/cache-1.0.xsd"
    version="1.0">
  <region name="myRegion" refid="PARTITION_REDUNDANT">
  </region>
</cache>

起動。

$ docker-compose up

最初にServerが起動してしまうのでこんなエラーが出ますが、リトライ後には接続してくれます。

server_1   | java.io.EOFException: Locator at /172.19.0.2:10334 did not respond. This is normal if the locator was shutdown. If it wasn't check its log for exceptions.

クラスタ内のメンバーを確認してみましょう。

$ docker exec -it geodelocator gfsh
    _________________________     __
   / _____/ ______/ ______/ /____/ /
  / /  __/ /___  /_____  / _____  / 
 / /__/ / ____/  _____/ / /    / /  
/______/_/      /______/_/    /_/    1.0.0-incubating

Monitor and Manage Apache Geode (incubating)
   
gfsh>connect --locator=localhost[10334]
Connecting to Locator at [host=localhost, port=10334] ..
Connecting to Manager at [host=geodelocator, port=1099] ..
Successfully connected to: [host=geodelocator, port=1099]

gfsh>list members
        Name         | Id
-------------------- | --------------------------------------------------------
locator-geodelocator | 172.19.0.2(locator-geodelocator:37:locator)<ec><v0>:1024
server-7c6760590428  | 172.19.0.3(server-7c6760590428:139)<v3>:1024

認識してそうですね。

Regionも認識しています。

gfsh>list regions
List of regions
---------------
myRegion

では、Serverを3つに変更してみます。

$ docker-compose scale server=3
Creating and starting geodecluster_server_2 ... done
Creating and starting geodecluster_server_3 ... done

こちらもOKそうです。

gfsh>list members
        Name         | Id
-------------------- | --------------------------------------------------------
locator-geodelocator | 172.19.0.2(locator-geodelocator:37:locator)<ec><v0>:1024
server-7c6760590428  | 172.19.0.3(server-7c6760590428:139)<v3>:1024
server-f8e155c5b221  | 172.19.0.4(server-f8e155c5b221:39)<v4>:1024
server-ecb6dccb021d  | 172.19.0.5(server-ecb6dccb021d:39)<v4>:1024

最後に、クライアントプログラムを書いて確認してみます。

Apache GeodeのGetting Startedを参考に、簡単なGroovyスクリプトを作成。

Index - Geode - Apache Software Foundation

client.groovy

@Grab('org.apache.geode:geode-core:1.0.0-incubating')
import org.apache.geode.cache.Region
import org.apache.geode.cache.client.*

def cache =
  new ClientCacheFactory()
    .addPoolLocator("localhost", 10334)
    .create()

def region = cache
      .createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
      .create('myRegion')

region.put('key', 'Hello Apache Geode!!')
println(region.get('key'))

cache.close()

実行

$ groovy client.groovy

いろいろ出力されますが、期待の結果は出力されました。

Hello Apache Geode!!

よさそうですね。

これからは、Client/Serverで書く時にはDocker Compose使ってやりましょうか。