ちょっと使ってみたい用途があって、Apache Igniteを試してみることにしました。
Apache Igniteとは?
いわゆる、インメモリ・データグリッドの一種です。Javaで作られています。
説明としては、このページを見るとよいでしょう。特に、「Ignite Facts」。
ざっと、こんな感じの雰囲気です。
- データをメモリ、メモリとストレージの両方に持てる
- インメモリ・データベースかつインメモリ・データグリッド
- 分散キャッシュ
- キーバリューストア
- SQLが使えるが、トランザクションサポートは限定的(Key-Value APIのみサポート、SQLでは未サポート&計画中)
- データの配置を意識した処理(collocated processing)が可能
もともとGridGainという製品があったのですが、それがApacheに寄贈されたのがApache Igniteです(GridGain自体は商用製品として残っていますが)。
GridGain Becomes Apache Ignite
GridGain Software Editions - GridGain Systems
分散キャッシュとして使われたり、最近ではOff-Heapを中心としたアーキテクチャになったりして、少し名前を見かけて
いるような気がします。
Apache Igniteを分散キャッシュに利用したシステム負荷軽減
Apache Ignite新メモリアーキテクチャ - Yahoo! JAPAN Tech Blog
Nikita Ivanov氏に聞く - Apache Igniteインメモリ・コンピューティング・プラットフォーム
また、GitHub上のStarもけっこう増えてきた感じが…?
インストール
Apache Igniteの動かし方としては、Javaアプリケーション内に組み込んで使用する方法と、起動済みのApache Igniteに接続する
Client/Serverとしての使い方があります。
今回は、オーソドックスな感じでClient/Serverとして使ってみましょう。
ドキュメントは、こちらに倣って。
環境はこちら。
$ java -version openjdk version "1.8.0_171" OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11) OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode) $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"
こちらのページから、バイナリをダウンロードします。今回は使うApache Igniteのバージョンは、2.4.0です。
Apache Ignite Downloads / Binary Releases
ダウンロード&展開。
$ wget http://ftp.meisei-u.ac.jp/mirror/apache/dist//ignite/2.4.0/apache-ignite-fabric-2.4.0-bin.zip
$ unzip apache-ignite-fabric-2.4.0-bin.zip
$ cd apache-ignite-fabric-2.4.0-bin
起動は、「bin/ignite.sh」を使います。
$ bin/ignite.sh
コンソールにこんなロゴを表示しつつ、Apache Igniteが起動します。
[16:19:49] __________ ________________ [16:19:49] / _/ ___/ |/ / _/_ __/ __/ [16:19:49] _/ // (7 7 // / / / / _/ [16:19:49] /___/\___/_/|_/___/ /_/ /___/ [16:19:49] [16:19:49] ver. 2.4.0#20180305-sha1:aa342270 [16:19:49] 2018 Copyright(C) Apache Software Foundation [16:19:49] [16:19:49] Ignite documentation: http://ignite.apache.org
構成は、Server 1 Node。
[16:19:51] Ignite node started OK (id=9d32ec5f) [16:19:51] Topology snapshot [ver=1, servers=1, clients=0, CPUs=8, offheap=1.8GB, heap=1.0GB]
Clientから接続してみる
それでは、簡単にClientから接続してみましょう。
コードは、こちらを参考に。
Getting Started / First Ignite Service Grid Application
あと、Client/Serverについてはこちらを参考に。
で、書いてみたコードがこちら。簡単に、Groovy+Grapeです。
getting-started.groovy
@Grab('org.apache.ignite:ignite-core:2.4.0') import org.apache.ignite.Ignition Ignition.setClientMode(true) def ignite = Ignition.start() def cache = ignite.getOrCreateCache('cache') cache.put('key', 'value') assert cache.get('key') == 'value' ignite.close()
ローカルで動作しているApache Ignite Serverに接続しているので、特別なにか設定を書かなくても良い感じです。
あと、Clientとして使うには、次の1行がポイントのような。
Ignition.setClientMode(true)
今回はCacheを利用しています。
def cache = ignite.getOrCreateCache('cache') cache.put('key', 'value')
Clientを起動すると、Topologyに入っていることが確認できます。
[15:59:33] Topology snapshot [ver=4, servers=1, clients=1, CPUs=8, offheap=1.8GB, heap=3.0GB]
これは、Server側から見ても同じですが。
[16:19:51] Topology snapshot [ver=1, servers=1, clients=0, CPUs=8, offheap=1.8GB, heap=1.0GB]
クラスタを構成してみる
もうちょっと試してみようということで、今度はServer側でクラスタを構成してみます。
デフォルトの状態では、いくつNodeを起動してもクラスタを構成してはくれないので、こちらを見ながらNodeを検出する
方法を設定します。
今回は、もっとも単純なマルチキャストのDiscoveryを使いましょう。
Cluster Configuration / Multicast Based Discovery
Apache Igniteのdistributionに含まれている、「config/default-config.xml」を次のように設定しました。
default-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Alter configuration below as needed. --> <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"> <property name="multicastGroup" value="228.10.10.157"/> </bean> </property> </bean> </property> </bean> </beans>
まあ、これを入れ込んだだけなんですけど。
<property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"> <property name="multicastGroup" value="228.10.10.157"/> </bean> </property> </bean> </property>
で、これをDockerイメージにして3 Node起動…。
ignite_1 | [07:37:03] Ignite node started OK (id=be6dc3a5) ignite_1 | [07:37:03] Topology snapshot [ver=3, servers=3, clients=0, CPUs=24, offheap=5.4GB, heap=3.0GB]
クラスタが構成されたようです。
Clientからつないでみましょう。
getting-started-clustered.groovy
@Grab('org.apache.ignite:ignite-core:2.4.0') import org.apache.ignite.Ignition import org.apache.ignite.cache.CacheMode import org.apache.ignite.configuration.CacheConfiguration import org.apache.ignite.configuration.IgniteConfiguration import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder Ignition.setClientMode(true) def tcpDiscoverySpi = new TcpDiscoverySpi() def ipFinder = new TcpDiscoveryMulticastIpFinder() ipFinder.setMulticastGroup('228.10.10.157') tcpDiscoverySpi.setIpFinder(ipFinder) def configuration = new IgniteConfiguration() configuration.setDiscoverySpi(tcpDiscoverySpi) def cacheConfiguration = new CacheConfiguration('cache') cacheConfiguration.setCacheMode(CacheMode.PARTITIONED) configuration.setCacheConfiguration(cacheConfiguration) def ignite = Ignition.start(configuration) def cache = ignite.getOrCreateCache('cache') cache.put('key', 'value') assert cache.get('key') == 'value' assert cache.getConfiguration(CacheConfiguration.class).getCacheMode() == CacheMode.PARTITIONED ignite.close()
Cacheの種類は、せっかくなのでPartitioned Modeにしました。
def cacheConfiguration = new CacheConfiguration('cache') cacheConfiguration.setCacheMode(CacheMode.PARTITIONED) configuration.setCacheConfiguration(cacheConfiguration)
Client側から見ても認識されていますし、
[16:45:25] Ignite node started OK (id=c59e4e1a) [16:45:25] Topology snapshot [ver=4, servers=3, clients=1, CPUs=32, offheap=5.4GB, heap=5.0GB]
Serverから見てもServerが3、Clientが1として認識できています。
ignite_1 | [07:44:33] Topology snapshot [ver=4, servers=3, clients=1, CPUs=32, offheap=5.4GB, heap=5.0GB]
Client/Serverといっているくらいなので、「クラスタへの接続設定はどう書くのかな?」と思ってドキュメントを探してみても、どうもそれらしいものは
見つからず。
で、いろいろ悩んだ結果、「これはClientというより、データを持たないNodeだと考える方がよいのだな」ということに気づき、普通にNode Discoveryの
設定をすれば通りました、と。
Ignition.setClientMode(true) def tcpDiscoverySpi = new TcpDiscoverySpi() def ipFinder = new TcpDiscoveryMulticastIpFinder() ipFinder.setMulticastGroup('228.10.10.157') tcpDiscoverySpi.setIpFinder(ipFinder) def configuration = new IgniteConfiguration() configuration.setDiscoverySpi(tcpDiscoverySpi) def cacheConfiguration = new CacheConfiguration('cache') cacheConfiguration.setCacheMode(CacheMode.PARTITIONED) configuration.setCacheConfiguration(cacheConfiguration) def ignite = Ignition.start(configuration)
ちょっといままで遊んでいたOSSのインメモリ・データグリッドと違うところもあって戸惑うところもありましたが、とりあえず導入はこんなところですね。