- 内容提要
- 序
- 前言
- 第一部分 背景知识
- 第 1 章 Spring Data 项目
- 第 2 章 Repository:便利的数据访问层
- 第 3 章 使用 Querydsl 实现类型安全的查询
- 第二部分 关系型数据库
- 第 4 章 JPA Repository
- 第 5 章 借助 Querydsl SQL 实现类型安全的 JDBC 编程
- 第三部分 NoSQL
- 第 6 章 MongoDB: 文档存储
- 第 7 章 Neo4j:图数据库
- 第 8 章 Redis:键/值存储
- 第四部分 快速应用开发
- 第 9 章 使用 Spring Roo 实现持久层
- 第 10 章 REST Repository 导出器
- 第五部分 大数据
- 第 11 章 Spring for Apache Hadoop
- 第 12 章 使用 Hadoop 分析数据
- 第 13 章 使用 Spring Batch 和 Spring Integration 创建大数据管道
- 第六部分 数据网格
- 第 14 章 分布式数据网格:GemFire
- 关于封面
14.4 通过 Spring XML 命名空间配置 GemFire
Spring Data GemFire 包括一个专有的 XML 命名空间来全面地配置数据网格。事实上,使用 Spring 命名空间来配置 GemFire 是代替其内置 cache.xml 文件的首选方式。由于历史遗留原因,GemFire 将继续支持 cache.xml 配置,但这些都可以通过 Spring XML 来实现,并且可以充分利用 Spring 提供许多高级特性,如模块化的 XML 配置、属性占位符、SpEL 以及环境配置文件(profile)。在命名空间中,Spring Data GemFire 扩展了 Spring FactoryBean 模式来简化 GemFire 组件的创建与初始化。
GemFire 提供几个回调接口,如 CacheListener、CacheWriter 及 CacheLoader,从而允许开发者添加自定义的事件处理器。使用 Spring IoC 容器,它们可以配置成普通的 Spring Bean 并注入到 GemFire 组件之中。cache.xml 提供的配置选项则相对受限制,而且需要回调机制来实现 GemFire 的 Declarable 接口,因此这是对 cache.xml 的一个重大改进。
此外,诸如 Spring Tool Suite(STS)这样的 IDE 对 XML 命名空间提供了良好的支持,例如代码补全、弹出式注解、实时验证等功能都使得它们更容易使用。
以下各节将使用 GemFire 的 Spring XML 命名空间。若需要更全面的信息,可参阅项目网站的 Spring Data GemFire 参考指南( http://www.springsource.org/spring-gemfire/ )。
14.4.1 缓存配置
配置 GemFire 缓存,需要创建一个 Spring Bean 定义文件,并添加 Spring GemFire 命名空间。在 STS 工具中,如图 14-3 所示,选择项目并打开上下文菜单(按右键),选择 New→Spring Bean Configuration file,然后填入文件名称并单击“Next”按钮。
图 14-3 在 STS 创建 Spring Bean 定义文件
在 XSD 命名空间视图窗口,选择 gfe 命名空间,如图 14-4 所示。
图 14-4 选择 Spring XML 命名空间
除了 gfe 命名空间之外,还有一个 gfe-data 命名空间可用于 Spring Data POJO 映射和以及对 Repository 的支持。gfe 命名空间则用于 GemFire 的核心配置。
单击“Finish”按钮,在 XML 编辑器中会打开 Bean 定义文件,它包含正确的命名空间声明,如示例 14-1 所示。
示例 14-1 在 Spring 配置文件声明一个 GemFire 缓存
现在可以使用 gfe 命名空间添加一个 cache 元素。就这样,这个简单的缓存声明将创建一个内嵌的缓存,在 Spring 的 ApplicationContext 注册为 gemfireCache,并在初始化上下文时创建它。
Spring Data GemFire 之前版本在创建 Bean 时,默认名称采用连字符(如 gemfire-cache)。在 1.2 版本之后,替换为采用驼峰名称(camelCase),并通过注解(@Autowired)进行自动装配。为了提供向后兼容性,旧式的名称将被注册为别名。
你可以很容易通过设置 cache 元素的 id 属性来改变 Bean 的名称。然而,所有其他的命名空间元素都会使用默认的名称,除非使用 cache-ref 属性来显式覆盖。所以可以依循惯例节省一些工作量。
cache 元素提供了一些额外的属性,在 STS 工具中可以按 Ctrl-Space 键获取友好的提示。最重要的是 properties-ref 属性。除了 API 之外,GemFire 通过外部属性暴露了一些全局的配置选项。在默认情况下,GemFire 会在所有常见的地方(用户的主目录、当前目录及类路径)查找一个名为 gemfire.properties 的文件。这虽然方便,但如果任意放置这些文件的话,可能会导致意想不到的后果。Spring 通过标准的属性加载机制提供了一系列更好的可选方案用以解决这个问题。例如,可以简单地构建一个 java.util.Properties 内联对象或从类路径、文件系统加载它。示例 14-2 使用属性来配置 GemFire 日志输出。
示例 14-2 引用属性来配置 GemFire
定义内联属性:
或引用资源的位置:
最好的选择通常是将系统管理员所关心的属性存储在文件系统中约定的位置,而不是将它们定义在 Spring XML 之中或是打包在.jar 文档里面。
注意使用 Spring 的 util 命名空间创建 Properties 对象的方法。这跟 Spring 的属性占位符机制有关系但是又不相同,它使用基于 token 的替换方式,使得可以通过各种来源在外部定义任意 Bean 里的属性。此外,cache 元素包含 cache-xml-location 属性,可以使用 GemFire 的内置配置模式来设置缓存。如前所述,这些主要是由历史遗留原因造成的。
cache 元素也提供了一些 pdx-*属性来启用和配置 GemFire 特有的序列化功能(PDX),在 14.6 小节“使用 Repository”中会讨论 PDX。
关于缓存的高级配置,cache 元素提供额外的属性来调整内存和网络通信配置(如图 14-5 所示),并且通过子元素注册回调,如 TransactionListers、TransactionWriters 等(如图 14-6 所示)。
图 14-5 在 STS 中显示缓存属性列表
图 14-6 在 STS 中显示子元列表
use-bean-factory-locator 属性(以上图中未显示)是值得说明一下的,这个工厂 Bean 使用 Spring 内部的 BeanFactoryLocator 负责创建缓存,这样用户声明在 GemFire 内置 cache.xml 文件中的类就会注册为 Spring Bean。对于给定的 id 的 cache,BeanFactoryLocator 的实现只允许存在一个 Bean 的定义,在某些情况下,如在 Eclipse 中运行 JUnit 集成测试,则必须将这个值设置为 false 来禁用 BeanFactoryLocator 以防止异常。这个异常也可能在构建脚本中的 JUnit 测试运行期间发生。在这种情况下,测试运行器应该配置为每个测试启用新 JVM(在 Maven 中的配为:<forkmode> always </ forkmode>)。通常将这个值设置为 false 不会发生任何问题。
14.4.2 域配置
如本章开头所述,GemFire 提供了多种类型的域。XML 命名空间定义 replicated-region、partitioned-region、local-region 以及 client-region 元素来创建域,再次强调,这并不能涵盖所有可用的功能,但是突出介绍了一些较为常见的功能。示例 14-3 所示是一个入门级的简单域声明示例。
示例 14-3 基本域声明
该域需要依赖缓存。在内部,会通过缓存来创建域。依照惯例,命名空间会被隐式式织入。默认缓存声明会创建一个名为 gemfireCache 的 Spring Bean。默认域声明使用相同的约定。换句话说,示例 14-3 等同于:
如果愿意的话,可以更改为任何有效的 Bean 的名字,但要确保按需将 cache-ref 设置为相应 Bean 的名称。
通常 GemFire 部署为一个分布式数据网格,复制域或分区域托管在缓存服务器上。客户端应用程序使用客户域来访问数据。对于开发和集成测试,这是一种最佳实践,以消除任何依赖于外部的运行环境。如示例代码所示,可以通过简单声明内嵌缓存的复制域或本地域。Spring 环境配置文件在配置 GemFire 的不同环境时非常有用。
在示例 14-4 中,dev 配置文件的目的是进行集成测试,而 prod 配置文件用于已部署的缓存配置。缓存和域的配置对应用程序代码是完全透明的。同时也要注意使用属性占位符从外部的属性文件指定定位器的主机和端口的方法。缓存客户端配置将在 14.4.3 小节“缓存客户端配置”中进一步探讨。
示例 14-4 用于开发环境和生产环境的 XML 配置示例
Spring 提供了一些方法来激活相应的环境配置文件,可以在系统属性中设置 spring.profiles.active 属性或 servlet 上下文参数或通过 @ActiveProfiles 注解。
如图 14-7 所示,有一些共同的域配置选项以及针对每种不同类型域的特殊配置选项,例如,可以配置将所有域的数据以同步或异步的方式备份到本地磁盘存储。
图 14-7 在 STS 工具中显示复制域属性
此外,可以对域进行配置,从而将所选的条目通过 WAN 网关同步分发到遥远的地理区域。也可以注册 CacheListener、CacheLoader 与 CacheWriter 来处理域事件。这些接口是用来实现相应调用的回调。CacheListener 是通用的事件处理器,每当条目被创建、更新、销毁时会被调用。例如,可以编写一个简单的 CacheListener 来记录缓存事件,这在分布式环境中特别有用(参见示例 14-5)。缓存加载器当缓存未命中(即请求的条目不存在)时 CacheLoader 会被调用,允许到数据库或其他系统资源去读取数据。CacheWriter 当条目更新或创建时被调用,提供“写过程”或“写之后”的能力。
示例 14-5 LoggingCacheListener 实现
其他的选项包括缓存过期(expiration),也就是域或条目在缓存中保留的最长时间,以及缓存回收(eviction),也就是当达到所定义的最大内存或最大的缓存条数限制时,确定那些条目从缓存中删除的策略。移除的缓存条目可以存储在磁盘溢出区。
可以通过分区域的配置来限制每个分区节点本地内存的分配量、定义使用的桶数等。甚至可以实现自己的 PartitionResolver 来控制数据在分区节点之中如何分布。
14.4.3 缓存客户端配置
在客户端/服务器配置中,应用程序是缓存客户端(cache client),它们生产和消费数据,但不直接分发到其他程序。缓存客户端也不会看到远端程序所进行的更新,正如你现在所期望的那样,这完全是可配置的。示例 14-6 展示了使用 client-cache、client-region 及 pool 来设置基本的客户端(client-side)。client-cache 是一个轻量级实现,尤其适用于客户端服务,如管理一个或多个客户域。pool 表示连接池,作为分布式系统的桥梁,它在配置的时候需要任意数量的定位器。
通常情况下,两个定位器已经足够了。第一个是主定位器,另外一个在故障转移切换时使用。每一个分布式系统的成员应使用相同的定位器配置。定位器是一个独立的进程并运行在指定 JVM 中,但这没有严格要求。对于开发和测试,pool 也提供了直接访问缓存服务器的 server 子元素。这对设置简单的客户机/服务器环境非常有用(例如,在本地计算机上),但不建议用于生产系统。正如本章开头介绍的,需要安装完整 GemFire 才能使用定位器,但可以使用 gemfire.jar 所公开的 API 来直接连接服务器进行开发,它最多支持 3 个缓存成员。
示例 14-6 配置缓存池
可以配置 pool 来控制连接和网络通信的线程分配,值得注意的是 subscription-enabled 属性,必须将其设置为 true 以同步远程程序所发起的域条目事件,如示例 14-7 所示。
示例 14-7 启用缓存池订阅
启用订阅之后,client-region 就可以注册感兴趣的所有键或特定键。订阅可能是持久的,也就是说 client-region 要更新客户端离线期间有可能发生的任何事件。此外,在某些情况下,它还可以通过限制传输值来提高性能,除非对值的获取是显式执行的。比如,在这个示例中新键是可见的,但要取出值的话,必须显式地调用 region.get(key)。
14.4.4 缓存服务端配置
借助于 Spring,只需声明 cache 和 region 并使用额外的 cache-server 元素,即可创建与初始化缓存服务器进程。要启动缓存服务器,只需使用命名空间来配置它并启动应用程序上下文即可,如示例 14-8 所示。
示例 14-8 启动一个 Spring 应用程序上下文
图 14-8 显示 Spring 配置的缓存服务器,它管理了两个分区域和一个复制域。cache-server 暴露了许多参数,可用来调整网络通信、系统资源等。
图 14-8 配置缓存服务器
14.4.5 WAN 配置
对于地域分布式系统来说,需要 WAN 的配置。例如,一个全球的组织可能需要跨越东京、伦敦和纽约的办公室来共享数据。每个地点都在本地端管理它的事务,但是远程的地点需要与其进行同步。因为从性能和可靠性方面来说 WAN 通信是非常昂贵的,所以 GemFire 会将事件放入到队列中并通过广域网的网关处理,以达到最终的一致性。我们可以控制每一个远程位置要对哪个事件进行同步,也可以调整内部的队列大小、同步调度、持久化备份等。深入讨论 GemFire 的 WAN 网关架构已超出了本书的范围,但需要特别注意的是 WAN 同步必须在域级别启用,如示例 14-9 所示的配置。
示例 14-9 GemFire WAN 配置
这个示例展示了使用 GemFire 6 的 API 来启用域的 WAN 通信,必须设置 enable-gateway 属性为 true(或者通过 hub-id 属性来标示),而且 hub-id 必须引用 gateway-hub 元素。在这里,我们看到 gateway-hub 配置了两个网关。第一个配置了可选的 GatewayListener,用来处理网关事件,另外它还配置网关队列,第二个定义了两个远程网关端点。
即将发布 GemFire 7.0 将会修改 WAN 架构,会包括一些新功能以及 API,通常也会改变网关配置方式。Spring Data GemFire 计划同时发布一个支持所有 GemFire 7.0 新功能的版本,而目前的 WAN 架构不建议使用。
14.4.6 磁盘存储配置
GemFire 可以配置磁盘存储来保存域备份、磁盘溢出时回收缓存、WAN 网关等。因为磁盘存储可以用于多种目的,所以它在命名空间中被定义为最顶层元素,使用它的组件可对它进行引用。磁盘写操作可选择同步或异步。
对于异步写入,条目保存在队列中,这是可配置的。其他可选项能够用来控制调度(例如,磁盘写操作之前可消耗的时间或以 MB 表示的最大文件大小)。在示例 14-10 中,配置了一个溢出磁盘存储来保存被移除的条目。对于异步写入,可在队列中最多存储 50 个条目,每隔 10 秒或者当队列达到容量时会进行刷新。该域配置为如果总的内存大小超过 2GB 就进行回收。自定义 ObjectSizer 用来估算每个条目所分配的内存。
示例 14-10 磁盘存储配置
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论