1.0.0-incubatingがリリースされて久しいApache Geodeですが、クラスタ環境を簡単に構築するような
Docker Composeを書いてみようかなと思いまして。
あくまで手元で簡単に確認したいがための内容なので、あんまりがっちりとした内容ではありません。
次のことをやります。
- Dockerイメージは、Apache Geode提供のものを使う
- LocatorとServerでコンテナを分ける
- Locatorは、とりあえずひとつ
- Serverは複数起動可能にする
- Cache XMLは、volumeでコンテナ外から与える
Apache GeodeのDockerイメージは、こちら。
で、できあがったファイルはこちら。
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 20.10 ドキュメント
では、起動してみましょう。
動作確認用に、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を使ってやりましょうか。