前回やったこと
前回はSpringDataGeodeを使って、インメモリデータグリッドを使ったSpringBootアプリケーションを作成し、データがサーバに同期されたタイミングでイベント処理が行えるように実装を行いました。
・SpringDataGeodeを使用したアプリケーション作成
今回やること
インメモリデータグリッドのキャッシュに登録されたデータをディスクに永続化する
今回はSpringDataGeodeの機能を使い、インメモリキャッシュに登録されたデータをローカルのディスクに永続化し、更にキャッシュ組み込みアプリサーバの起動時に、永続化ファイルをロードしてキャッシュにデータを登録する実装をやります。
調べてみたところ、アノテーション一つ追加してやるだけで実現できそう。
-
SpringBootApplication
に以下のようにアノテーションを追加。
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
に直接設定することにしました。。
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登録してやることでやっと永続化が完了しました。
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
が提供してくれるという情報を得られなかったので、一旦ファイル永続化機能を使用して、永続化をやってみました。