CLOVER🍀

That was when it all began.

Infinispanで、キャッシュをファイルに保存する

続いて、Embedded Cacheでキャッシュをファイルに保存することを試してみました。

まずは、build.sbt。

name := "infinispan-embedded-file-store"

version := "0.0.1"

scalaVersion := "2.10.0"

organization := "littlewings"

fork in run := true

resolvers += "jboss repository" at "http://repository.jboss.org/nexus/content/groups/public-jboss/"

libraryDependencies += "org.infinispan" % "infinispan-core" % "5.2.0.Final"

プログラム中で設定する

前回同様、最初はConfigurationBuilderを使って設定してみます。
src/main/scala/EmbeddedFileStoreCache.scala

import org.infinispan.configuration.cache.ConfigurationBuilder
import org.infinispan.eviction.EvictionStrategy
import org.infinispan.manager.DefaultCacheManager

object EmbeddedFileStoreCache {
  def main(args: Array[String]): Unit = {
    val manager = new DefaultCacheManager
    manager.defineConfiguration(
      "fileStoreCache",
      new ConfigurationBuilder()
        .eviction
        .strategy(EvictionStrategy.LIRS)
        .maxEntries(5)
        .loaders
        .passivation(false)
        .addFileCacheStore
        .ignoreModifications(false)
        .fetchPersistentState(false)
      // .purgeOnStartup(true)  // => これを付けると、次回起動時に空になる
        .location("cache-store")
        .build
    )

    val cache = manager.getCache[String, String]("fileStoreCache")

    val range = 1 to 10
    range foreach { v =>
      val key = "key" + v
      println(s"$key => ${cache.get(key)}")
    }

    Thread.sleep(3000L)

    range foreach { v =>
      val key = "key" + v
      cache.put(key, new java.util.Date().toString)
    }

    range foreach { v =>
      val key = "key" + v
      println(s"$key => ${cache.get(key)}")
    }
  }
}

この辺りでファイルに保存する設定を行っています。

        .loaders
        .passivation(false)
        .addFileCacheStore
        .ignoreModifications(false)
        .fetchPersistentState(false)
      // .purgeOnStartup(true)  // => これを付けると、次回起動時に空になる
        .location("cache-store")

実行すると1回目は

[info] key1 => null
[info] key2 => null
[info] key3 => null
[info] key4 => null
[info] key5 => null
[info] key6 => null
[info] key7 => null
[info] key8 => null
[info] key9 => null
[info] key10 => null
[info] key1 => Thu Feb 07 00:36:40 JST 2013
[info] key2 => Thu Feb 07 00:36:40 JST 2013
[info] key3 => Thu Feb 07 00:36:40 JST 2013
[info] key4 => Thu Feb 07 00:36:40 JST 2013
[info] key5 => Thu Feb 07 00:36:40 JST 2013
[info] key6 => Thu Feb 07 00:36:40 JST 2013
[info] key7 => Thu Feb 07 00:36:40 JST 2013
[info] key8 => Thu Feb 07 00:36:40 JST 2013
[info] key9 => Thu Feb 07 00:36:40 JST 2013
[info] key10 => Thu Feb 07 00:36:40 JST 2013
[success] Total time: 7 s, completed 2013/02/07 0:36:40

ですが、2回目は

[info] key1 => Thu Feb 07 00:36:40 JST 2013
[info] key2 => Thu Feb 07 00:36:40 JST 2013
[info] key3 => Thu Feb 07 00:36:40 JST 2013
[info] key4 => Thu Feb 07 00:36:40 JST 2013
[info] key5 => Thu Feb 07 00:36:40 JST 2013
[info] key6 => Thu Feb 07 00:36:40 JST 2013
[info] key7 => Thu Feb 07 00:36:40 JST 2013
[info] key8 => Thu Feb 07 00:36:40 JST 2013
[info] key9 => Thu Feb 07 00:36:40 JST 2013
[info] key10 => Thu Feb 07 00:36:40 JST 2013
[info] key1 => Thu Feb 07 00:36:49 JST 2013
[info] key2 => Thu Feb 07 00:36:49 JST 2013
[info] key3 => Thu Feb 07 00:36:49 JST 2013
[info] key4 => Thu Feb 07 00:36:49 JST 2013
[info] key5 => Thu Feb 07 00:36:49 JST 2013
[info] key6 => Thu Feb 07 00:36:49 JST 2013
[info] key7 => Thu Feb 07 00:36:49 JST 2013
[info] key8 => Thu Feb 07 00:36:49 JST 2013
[info] key9 => Thu Feb 07 00:36:49 JST 2013
[info] key10 => Thu Feb 07 00:36:49 JST 2013
[success] Total time: 7 s, completed 2013/02/07 0:36:49

となり、前回の結果を覚えていることが分かります。

ここで、

        .passivation(false)

を

        .passivation(true)

とすると、動作結果が変わります。

保存時は変わりませんが

[info] key1 => Thu Feb 07 00:36:49 JST 2013
[info] key2 => Thu Feb 07 00:36:49 JST 2013
[info] key3 => Thu Feb 07 00:36:49 JST 2013
[info] key4 => Thu Feb 07 00:36:49 JST 2013
[info] key5 => Thu Feb 07 00:36:49 JST 2013
[info] key6 => Thu Feb 07 00:36:49 JST 2013
[info] key7 => Thu Feb 07 00:36:49 JST 2013
[info] key8 => Thu Feb 07 00:36:49 JST 2013
[info] key9 => Thu Feb 07 00:36:49 JST 2013
[info] key10 => Thu Feb 07 00:36:49 JST 2013
[info] key1 => Thu Feb 07 00:38:34 JST 2013
[info] key2 => Thu Feb 07 00:38:34 JST 2013
[info] key3 => Thu Feb 07 00:38:34 JST 2013
[info] key4 => Thu Feb 07 00:38:34 JST 2013
[info] key5 => Thu Feb 07 00:38:34 JST 2013
[info] key6 => Thu Feb 07 00:38:34 JST 2013
[info] key7 => Thu Feb 07 00:38:34 JST 2013
[info] key8 => Thu Feb 07 00:38:34 JST 2013
[info] key9 => Thu Feb 07 00:38:34 JST 2013
[info] key10 => Thu Feb 07 00:38:34 JST 2013
[success] Total time: 7 s, completed 2013/02/07 0:38:34

次回起動時には、キャッシュが少し減っています。

[info] key1 => Thu Feb 07 00:38:34 JST 2013
[info] key2 => Thu Feb 07 00:38:34 JST 2013
[info] key3 => null
[info] key4 => Thu Feb 07 00:38:34 JST 2013
[info] key5 => null
[info] key6 => Thu Feb 07 00:38:34 JST 2013
[info] key7 => null
[info] key8 => Thu Feb 07 00:38:34 JST 2013
[info] key9 => Thu Feb 07 00:38:34 JST 2013
[info] key10 => null
[info] key1 => Thu Feb 07 00:38:41 JST 2013
[info] key2 => Thu Feb 07 00:38:41 JST 2013
[info] key3 => Thu Feb 07 00:38:41 JST 2013
[info] key4 => Thu Feb 07 00:38:41 JST 2013
[info] key5 => Thu Feb 07 00:38:41 JST 2013
[info] key6 => Thu Feb 07 00:38:41 JST 2013
[info] key7 => Thu Feb 07 00:38:41 JST 2013
[info] key8 => Thu Feb 07 00:38:41 JST 2013
[info] key9 => Thu Feb 07 00:38:41 JST 2013
[info] key10 => Thu Feb 07 00:38:41 JST 2013
[success] Total time: 6 s, completed 2013/02/07 0:38:41

一部、読み出せていないデータがあるみたいですね。

これを読むと…
https://docs.jboss.org/author/display/ISPN/Cache+Loaders+and+Stores#CacheLoadersandStores-CacheLoaderBehaviorwithPassivationDisabledvsEnabled
有効期限を設定しているかどうかで動きが変わるみたいですが…passivationを有効にすると、有効期限が切れたキャッシュを読み出す時に、メモリ上には残るけど永続化先からは消えちゃうってこと??

なお、保存先はlocationで指定していますが、

        .location("cache-store")

相対パスで書くと、Javaの起動ディレクトリからの相対位置になるようですね。もちろん、絶対パスで書いてもOKです。

XMLで設定する場合

やっていることは一緒なので、ソースと設定ファイルを載せておきます。
src/main/scala/EmbeddedXmlFileStoreCache.scala

import org.infinispan.manager.DefaultCacheManager

object EmbeddedXmlFileStoreCache {
  def main(args: Array[String]): Unit = {
    val manager = new DefaultCacheManager("infinispan.xml")

    val cache = manager.getCache[String, String]("xmlFileStoreCache")

    val range = 1 to 10
    range foreach { v =>
      val key = "key" + v
      println(s"$key => ${cache.get(key)}")
    }

    Thread.sleep(3000L)

    range foreach { v =>
      val key = "key" + v
      cache.put(key, new java.util.Date().toString)
    }

    range foreach { v =>
      val key = "key" + v
      println(s"$key => ${cache.get(key)}")
    }
  }
}

src/main/resources/infinispan.xml

<?xml version="1.0" encoding="UTF-8"?>
<infinispan
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:infinispan:config:5.2 http://www.infinispan.org/schemas/infinispan-config-5.2.xsd"
    xmlns="urn:infinispan:config:5.2">

  <namedCache name="xmlFileStoreCache">
    <eviction strategy="LIRS" maxEntries="5" />
    <loaders passivation="false">
      <loader class="org.infinispan.loaders.file.FileCacheStore"
              fetchPersistentState="false" ignoreModifications="false"
              purgeOnStartup="false">
        <properties>
          <property name="location" value="xml-cache-store" />
        </properties>
      </loader>
    </loaders>
  </namedCache>
</infinispan>