Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Infinispanのデータはプロセスが落ちたら消える?

こんばんは。kimukimuです。

前回にInfinispanのデータが複数プロセス間で同期されることを確認しました。

1.『データを蓄える』という機能に求められること

なんですが、キャッシュサーバ/データグリッドと言っても、
『データを蓄える領域』という位置付けには変わりありません。

そのため、当然ながら『データがどこかに永続化することができるのか?』が気になります。
システムを開発する際、何かデータを永続化したい場合、
ファイルやデータベースに保存して残すというのが一般的です。

そんなわけで、Infinispanもファイルやデータベースからデータを読み出したり、
保存したりする機能を持っています。

今回はファイルにデータを保存する方法について説明しましょう。

2.設定ファイルの記述内容

Infinispanでファイルを『Infinispan以外の何か』に書きこみ/保存する場合、
CacheLoaderという仕組みを使用します。

前回の「infinispan-replication.xml」を下記のように修正します。
下記の修正によって、「replicationCache」という名前のキャッシュがファイルと同期するようになります。

infinispan-replication.xml
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="urn:infinispan:config:5.0 http://www.infinispan.org/schemas/infinispan-config-5.0.xsd"
  xmlns="urn:infinispan:config:5.0">
  <global>
    <transport>
      <properties>
        <property name="configurationFile" value="jgroups.xml" />
      </properties>
    </transport>
  </global>
  <default>
    <!-- Configure a synchronous replication cache -->
    <clustering mode="replication">
      <sync />
    </clustering>
  </default>

  <!-- replicationCacheという名称のキャッシュ設定 -->
  <namedCache name="replicationCache">
    <clustering mode="replication">
      <sync />
    </clustering>
    <!-- 外部リソースとの同期設定 -->
    <loaders passivation="false" shared="false" preload="true">
      <!-- ファイルと同期するキャッシュローダーをセット -->
      <loader class="org.infinispan.loaders.file.FileCacheStore"
        fetchPersistentState="true" ignoreModifications="false"
        purgeOnStartup="false">
        <properties>
          <!-- ファイルを保存するパスを設定。Java実行パス配下の「store」ディレクトリに保存 -->
          <property name="location" value="store" />
        </properties>
      </loader>
    </loaders>
  </namedCache>
</infinispan>

では、実際に使用するプログラムを書きましょう。

3.確認用プログラム

前回の確認プログラムPutNodeを下記のように
『値を取りだして、値をインクリメントして保存』を繰り返すように修正しました。
これで、『起動時にファイルから値を読み出して、読みだした値に対して加算し続ける』
という動作になりました。

PutNode.java
package jp.gr.t3.infinispan.synctest.replication;

import org.infinispan.Cache;

public class PutNode extends AbstractNode {
  public static void main(String[] args) throws Exception {
    new PutNode().run();
  }

  public void run() {
    Cache<String, String> cache = getCacheManager().getCache("replicationCache");

    int index = 0;

    while (true) {
      String getResult = cache.get("key");
      
      if(getResult != null)
      {
        index = Integer.parseInt(getResult);
      }
      
      index++;
      
      cache.put("key", Integer.toString(index));
      System.out.println(Integer.toString(index));

      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}

4.動作確認をしてみます

では、実行してみましょう。

実行してみると、言うまでもなく最初は下記のような結果になります。

1
2
3
4

実行を始めると、Javaを実行しているディレクトリ配下の「store」という
ディレクトリの下に「replicationCache」というディレクトリが作成されます。

replicationCacheディレクトリ配下を見てみると、ファイルが作成されています。

作成されたファイルの中身を見てみると、下記のようになっています。

「key」というものに対して数値が関連付けられている。。。のはわかりますね。

とりあえず、ファイルに保存できることが確認できました。
後は、保存したファイルから読み出すことができるか、になります。

そんなわけで、一度PutNodeを終了させます。

この状態で再度保存されたファイルの中身を見てみると下記のようになっていました。
終了したタイミングの値の「74」が保存されていることがわかります。

この状態でPutNodeを再度起動させます。すると・・・?

次に起動したときは前回の終了時の値である「74」を引き継いで、「75」から再開されています!
Infinispanのキャッシュをファイルとして保存/読み出しが出来ることがわかりました。
これで、プロセスを終了させたり、落ちてしまった場合にもデータを持ち越すことができますね。

まぁ、その分速度に影響は出ているんでしょうけど、
そのあたりへの対処はまた次回にでも。