首页 > 解决方案 > Spring Data GemFire DiskStore

问题描述

我需要Region使用 Spring Data GemFire 将数据保存到磁盘中。

使用下面的配置(LocatorServer使用Gfsh启动):

@EnablePdx
@ClientCacheApplication
@EnableDiskStore(name = "disk_store")
@EnableClusterConfiguration(useHttp = true)
@EnableEntityDefinedRegions(basePackages = "xxx.entity")
@EnableGemfireRepositories(basePackages = "xxx.repository")
public class GeodeClientConfiguration {

}

配置如下:

spring.data.gemfire.disk.store.name=disk_store
spring.data.gemfire.disk.store.directory.location=C:\\apache-geode-1.9.0\\diskstore

上面的配置创建了一个DiskStore(一旦运行存储数据的代码)。问题是一旦服务器停止,磁盘存储就会被删除。

查看 John Blum 的文档和示例无济于事。

还尝试DiskStore使用Gfsh创建,但最终在GfshDiskStores创建的磁盘存储中有多个且没有数据。

知道我可能会错过什么吗?

谢谢

标签: spring-bootgemfirespring-data-gemfiregeode

解决方案


即使您使用上面的 Java 配置,您的安排对我来说仍然有点不清楚/模棱两可。但是,让我们从我们所知道的开始。

ClientCache首先,从上面的 Java 配置中可以清楚地看出,您正在创建一个Spring应用程序来连接到独立的 GemFire 集群并从其发送/接收数据。

您还声明您正在使用Gfsh启动定位器服务器。到目前为止一切都很好。

然而,你有...

1)用(这很好)注释您的客户端应用程序类,而不使用该属性@EnableEntityDefinedRegions指定备用数据策略。clientRegionShortcut默认情况下,clientRegionShortcut设置为PROXY(参见此处),这意味着您的客户端应用程序保持 NO 本地状态。

2) 然后,您DiskStore使用注释在客户端上定义一个(即“disk_store”)@EnableDiskStore,这可能不是您想要的,因为客户端区域上当前没有保存本地状态。

注意:@EnableClusterConfiguration不会将配置元数据DiskStores从客户端推送到服务器。目前,它只将元数据推送RegionIndex配置到服务器,如客户端所定义的那样。

否则,其余的 Spring(用于 GemFire)配置(使用 Annotations)似乎很好。

注意:还请记住,@EnableClusterConfiguration注释小心不要踩到服务器端的现有区域。如果同名的区域已经存在,那么服务器在声明@EnableClusterConfiguration注解时将不会应用客户端发送的定义(即注解不会“nuke-and-pave”)。这是设计使然,主要是为了防止数据丢失。

注意:我还建议您在basePackages属性@EnableEntityDefinedRegions@EnableGemfireRepositories注释中使用属性的类型安全替代方案basePackageClasses。它可以引用 1 个或多个 Classes,但该类类型仅用于确定从哪个包开始扫描。例如,您可以将@EnableEntityDefinedRegionsbasePackageClassestoexample.app.customers.model.Customer.classexample.app.products.model.Product.classas 设置为 in @EnableEntityDefinedRegions(basePackageClasses = { Customer.class, Product.class }),SDG 将使用这些类的包声明开始扫描实体类(包括子包)。您不需要列出包中的所有(或多个)类;您要扫描的每个(顶级)包 1 个就足够了。最好限制扫描。

因此,在您的情况下,您可能需要执行以下操作:

在客户端:

@EnablePdx
@ClientCacheApplication
@EnableClusterConfiguration(useHttp = true)
@EnableEntityDefinedRegions(basePackageClasses = EntityType.class)
@EnableGemfireRepositories(basePackageClasses = RepositoryType.class)
public class GeodeClientConfiguration {

}

然后,在服务器上,要“持久化”数据,您要创建“持久性”区域。您可以通过以下两种方式中的一种来完成:

1) 首先,您可以配置客户端,使用@EnableClusterConfiguration注解,告诉服务器在创建匹配的区域(按名称)时,根据客户端的定义,创建一个“PERSISTENT”区域。默认情况下,客户端@EnableClusterConfiguration注释告诉服务器创建一个非持久PARTITION区域(见这里)。因此,您可以将@EnableClusterConfiguration客户端配置中的注释更改为:

@ClientCacheApplication
@EnableClusterConfiguration(useHttp = true, serverRegionShortcut = RegionShortcut.PARTITION_PERSISTENT)
...
class GeodeClientConfiguration { ... }

您可以使用任何非本地、“PERSISTENT” RegionShortcut、区域(数据策略)类型(请参见此处)...主要是 [PARTITION_PERSISTENT* 和 REPLICATE_PERSISTENT*]。

然后,当客户端将 Region 配置元数据推送到服务器时,服务器将创建一个具有相同名称和指定(数据策略)类型(由@EnableClusterConfiguration注解的serverRegionShortcut属性定义)的 Region。

同样,请记住,如果 Region 已经存在,则不会重新创建 Region。如果您想让客户端在(每个应用程序)重新启动时创建区域,您需要使用Gfsh销毁该区域。

2) 或者,您可以使用Gfsh创建区域,使用:

gfsh> create region --name=Example --type=PARTITION_PERSISTENT

最后,当涉及到 时DiskStore,由于您没有本地状态区域,即使您这样做了,您也可能希望数据“持久化”服务器端,然后如果您什么都不做,只声明服务器端区域(s ) 使用上述 2 种方法之一的“PERSISTENT”数据策略,然后 GemFire 默认写入“DEFAULT” DiskStore

如果您想将“特定” DiskStore(按名称)与区域(例如“示例”)相关联,那么您必须首先创建DiskStoreusing Gfsh

gfsh> create disk-store --name=disk_store ...

这里

然后,使用Gfsh创建区域:

gfsh> create region --name=Example --type=PARTITION_PERSISTENT --disk-store=disk_store ...

这里

如果您将 Eviction 配置为“OVERFLOW_TO_DISK”(请参见此处),DiskStore则它用于“持久化”数据以及将数据溢出到磁盘。

从#2(创建区域)开始(创建区域DiskStore),都是服务器端的。

无论如何,我希望所有这些都有意义并有所帮助。

如果您还有其他疑问或问题,请随时在评论中跟进。

谢谢。


推荐阅读