CLOVER🍀

That was when it all began.

Apache IgniteをUbuntu Linux 16.04 LTSにインストールする

ちょっと使ってみたい用途があって、Apache Igniteを試してみることにしました。

Apache Ignite

Apache Igniteとは?

いわゆる、インメモリ・データグリッドの一種です。Javaで作られています。

説明としては、このページを見るとよいでしょう。特に、「Ignite Facts」。

What is Ignite?

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

インストール

Apache Igniteの動かし方としては、Javaアプリケーション内に組み込んで使用する方法と、起動済みのApache Igniteに接続する
Client/Serverとしての使い方があります。

今回は、オーソドックスな感じでClient/Serverとして使ってみましょう。

ドキュメントは、こちらに倣って。

Getting Started

環境はこちら。

$ 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についてはこちらを参考に。

Clients and Servers

で、書いてみたコードがこちら。簡単に、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を検出する
方法を設定します。

Cluster Configuration

今回は、もっとも単純なマルチキャストの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にしました。

Partitioning and Replication

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のインメモリ・データグリッドと違うところもあって戸惑うところもありましたが、とりあえず導入はこんなところですね。