LoginSignup
0
2

More than 5 years have passed since last update.

SpringBoot+インメモリデータグリッド入門 (データ永続化)

Posted at

前回やったこと

前回はSpringDataGeodeを使って、インメモリデータグリッドを使ったSpringBootアプリケーションを作成し、データがサーバに同期されたタイミングでイベント処理が行えるように実装を行いました。

・SpringDataGeodeを使用したアプリケーション作成

・SpringDataGeodeを使用したイベント処理実装

今回やること

インメモリデータグリッドのキャッシュに登録されたデータをディスクに永続化する

今回はSpringDataGeodeの機能を使い、インメモリキャッシュに登録されたデータをローカルのディスクに永続化し、更にキャッシュ組み込みアプリサーバの起動時に、永続化ファイルをロードしてキャッシュにデータを登録する実装をやります。

調べてみたところ、アノテーション一つ追加してやるだけで実現できそう。

  • SpringBootApplicationに以下のようにアノテーションを追加。
ServerGeodeApplication.java
package spring.geode.server.geodeServer;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.EnableDiskStore;
import org.springframework.data.gemfire.config.annotation.EnableDiskStore.DiskDirectory;
import org.springframework.data.gemfire.config.annotation.EnableLocator;
import org.springframework.data.gemfire.config.annotation.EnableManager;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.region.UserRegion;
import spring.geode.server.geodeServer.repository.UserRepository;

@SpringBootApplication
@PeerCacheApplication(name = "SpringGeodeServerApplication", locators = "localhost[40404]")
@EnableGemfireRepositories(basePackageClasses = UserRepository.class)
// 今回追加したデータ永続化アノテーション
@EnableDiskStore(
        name="SimpleDiskStore",
        autoCompact=true,
        diskDirectories = @DiskDirectory(location="/hoge/fuga/SpringGeodeData")
        )
public class GeodeServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(GeodeServerApplication.class, args);
    }

    @Configuration
    @EnableLocator(port = 40404)
    @EnableManager(start = true)
    static class LocatorManagerConfiguration {
    }

    @Configuration
    static class CacheInitializer {

        @Bean
        Region<Integer, User> userRegion(final GemFireCache cache) {
            return new UserRegion().createUserRegion(cache);
        }

        @Bean
        public ReplicatedRegionFactoryBean<Integer, User> replicatedRegion(GemFireCache cache) {
            return new UserRegion().createUserRegionFactory(cache);
        }
    }
}

@EnableDiskStoreを有効にすることによってdiskDirectoriesで指定した絶対パスの位置に永続化ファイルが吐き出される。

と、思いきや何故だかファイルが出力されず。。
アノテーションで解決する方法を模索しましたが、うまくいかず。。

仕方がないので、Beanに直接設定することにしました。。

UserRegion.java
package spring.geode.geodeCommon.region;

import java.io.File;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;

import spring.geode.geodeCommon.listener.UserRegionListener;
import spring.geode.geodeCommon.model.User;

/**
 * ユーザを管理する{@link Region}の設定を作成する
 *
 */
public class UserRegion {
    /**
     * {@link Region}の作成を行う
     * @param cache
     * @return
     */
    public Region<Integer, User> createUserRegion(final GemFireCache cache) {
        return cache.<Integer, User>getRegion("Users");
    }

    /**
     * {@link Region}に対する設定を行う
     * @param cache
     * @return
     */
    public ReplicatedRegionFactoryBean<Integer, User> createUserRegionFactory(GemFireCache cache) {
        ReplicatedRegionFactoryBean<Integer, User> replicatedRegionFactory = new ReplicatedRegionFactoryBean<>();
        UserRegionListener[] listeners = { new UserRegionListener() };

        listeners[0] = new UserRegionListener();
        replicatedRegionFactory.setCacheListeners(listeners);
        replicatedRegionFactory.setClose(false);
        replicatedRegionFactory.setCache(cache);
        replicatedRegionFactory.setRegionName("Users");
        replicatedRegionFactory.setPersistent(true);
        return replicatedRegionFactory;
    }

    /**
     * {@link Region}に対するファイル永続化設定を行う
     * @param cache
     * @param regionFactory
     * @return
     */
    public ReplicatedRegionFactoryBean<Integer, User> configDiskStore(GemFireCache cache,
            ReplicatedRegionFactoryBean<Integer, User> regionFactory) {
        File[] files = { new File("/hoge/fuga/SpringGeode/persistenceFile") };

        cache.createDiskStoreFactory()//
                .setAllowForceCompaction(true)//
                .setAutoCompact(true)//
                .setDiskDirs(files)//
                .create("SimpleDiskStore");

        regionFactory.setDiskStoreName("SimpleDiskStore");

        return regionFactory;
    }
}

configDiskStoreメソッドで永続化設定を行っています。
Cache内にDiskStoreを作成し、各種永続化方法に関する設定、永続化ファイルパスを設定しています。

詳しくはここを参照

このメソッドをアプリケーション内で呼び出し、Bean登録してやることでやっと永続化が完了しました。

GeodeServerApplication.java
package spring.geode.server.geodeServer;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.EnableLocator;
import org.springframework.data.gemfire.config.annotation.EnableManager;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;

import spring.geode.geodeCommon.model.User;
import spring.geode.geodeCommon.region.UserRegion;
import spring.geode.server.geodeServer.repository.UserRepository;

@SpringBootApplication
@PeerCacheApplication(name = "SpringGeodeServerApplication", locators = "localhost[40404]")
@EnableGemfireRepositories(basePackageClasses = UserRepository.class)
public class GeodeServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(GeodeServerApplication.class, args);
    }

    @Configuration
    @EnableLocator(port = 40404)
    @EnableManager(start = true)
    static class LocatorManagerConfiguration {
    }

    @Configuration
    static class CacheInitializer {

        @Bean
        Region<Integer, User> userRegion(final GemFireCache cache) {
            return new UserRegion().createUserRegion(cache);
        }

        @Bean
        public ReplicatedRegionFactoryBean<Integer, User> replicatedRegion(GemFireCache cache) {
            UserRegion region = new UserRegion();
            return region.configDiskStore(cache, region.createUserRegionFactory(cache));
        }
    }
}

これでRegionごとに永続化設定を行うことができ、アプリ起動時にはDiskStoreに設定したファイルからデータをロードしてキャッシュに登録することができるようになりました。

アノテーションでサクッと実装したかったのですが、うまくいかなかったのが悔やまれる。。
ReplicatedRegionFactoryBeanを自前でカスタムしているのがいけないのか。。

何はともあれ永続化はできたので良しとする。

RDBを永続化対象とした設定もできれば嬉しいけど、そのような機能をSpringDataGeodeが提供してくれるという情報を得られなかったので、一旦ファイル永続化機能を使用して、永続化をやってみました。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2