Spring Data GemFire学习
英文手册:http://docs.spring.io/spring-data/gemfire/docs/1.5.2.RELEASE/reference/html/(Spring Data GemFire Reference Guide)
新版本不用配置Gemfire自带的cache.xml直接用引用名空间的方式,配置Spring配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlxsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
<bean id ... >
<gfe:cache ...>
</beans>
注解说明:
<gfe:cache/>创建一个默认的cache:首先Spring会注册一个CacheFactoryBean来创建一个实现了Cache接口的gemfireCache对象。
这个Cache可以是一个既存的也可以是个已经在服务器上存在连接上去的
<gfe:cache id="cache-with-xml" cache-xml-location="classpath:cache.xml"/>
也可以指定用Gemfire本地的配置文件配置。
<gfe:cache properties-ref="props"/> <util:properties id="props" location="file:/vfabric/gemfire/gemfire.properties"/> </beans>
也可以这样外化配置,通过引用的properties
文件配置
这些配置只有在创建的时候才会应用,如果JVM中已经有Cache了,则会忽略
高级Cache配置
<gfe:cache copy-on-read="true" critical-heap-percentage="70" eviction-heap-percentage="60" lock-lease="120" lock-timeout="60" pdx-serializer="myPdxSerializer" pdx-disk-store="diskStore" pdx-ignore-unread-fields="true" pdx-persistent="true" pdx-read-serialized="false" message-sync-interval="1" search-timeout="300" close="false" lazy-init="true"> <gfe:transaction-listener ref="myTransactionListener"/> <gfe:transaction-writer> <bean class="org.springframework.data.gemfire.example.TransactionListener"/> </gfe:transaction-writer> <gfe:dynamic-region-factory/> 允许Gemfire动态region factory <gfe:jndi-binding jndi-name="myDataSource" type="ManagedDataSource"/> 声明jdni接口绑定外部数据源 </gfe:cache>
更多的配置信息可以看Gemfire官网 http://gemfire.docs.pivotal.io/index.html
close属性表明cache是否和Spring application context 一起关闭
lazy-init是不是等到用的时候才init
TransactionListener
中引用的bean必须实现TransactionListener接口
use-bean-factory-locator属性代表用Spring内部类型BeanFactoryLocator来让定义在cache.xml中的locator注册成一个 Spring beans
在某些情况下,比如UT和IT时,设置use-bean-factory-locator为false,来防止异常,这个异常也会在用Maven build 脚本启动test的时候。测试人员要fork给每个testFork一个新的JVM。
(in maven, set<forkmode>always</forkmode>
)
允许PDX序列化
PDX是Gemfire增强系列化框架。
设置pdx-serializer属性就启用了PDX序列化Gemfire提供了一个PDX的实现com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer(基于反射的自动序列化)具体参考Working with GemFire Serialization
配置一个Gemfire Cache Server
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gfe="http://www.springframework.org/schema/gemfire" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <gfe:cache /> <!-- Advanced example depicting various cache server configuration options --> <gfe:cache-server id="advanced-config" auto-startup="true" bind-address="localhost" port="${gfe.port.6}" host-name-for-clients="localhost" load-poll-interval="2000" max-connections="22" max-threads="16" max-message-count="1000" max-time-between-pings="30000" groups="test-server"> <gfe:subscription-config eviction-type="ENTRY" capacity="1000" disk-store="file://${java.io.tmpdir}"/> </gfe:cache-server> <context:property-placeholder location="classpath:cache-server.properties"/> </beans>
CacheServer会在container完全初始化完成后启动,这允许潜在的regions,listeners,writers或者实例定义在server开始接受连接时声明已经完全初始化并注册
配置Gemfire Client Cache
和Cache用法和配置一样,也是org.springframework.data.gemfire.client.ClientCacheFactoryBean提供的(里面有Pool)
<beans> <gfe:client-cache /> </beans>
和Cache不同的是Client cache通过Pool连接remote cache server。默认创建一个Pool(localhost
port40404
)这个默认pool被client region用,除非client region设置使用另外的pool
client pool可以配置连接为单独的entity或者整个cache连接server
<beans> <gfe:client-cache id="simple" pool-name="my-pool"/> <gfe:pool id="my-pool" subscription-enabled="true"> <gfe:locator host="${locatorHost}" port="${locatorPort}"/> </gfe:pool> </beans>
4.2.4使用Gemfire数据连接名空间
其中包括ready-for-events属性。通知服务器,这种持久的客户准备接收更新ClientCache.readyForEvents().
除了核心名空间gfe,Spring Data Gemfire提供gfe-data名空间主要为了简化Gemfire客户端程序的部署。
他包括<datasource>标签来方便的连接data grid
<gfe-data:datasource> <locator host="somehost" port="1234"/> </gfe-data:datasource>
datasource创建client cache 和 connection pool 他将查询所有存在的root regions中的server的数量并且为每个server创建client region的代理
这个标签的语法和<gfe:pool>很像。他可能和一个或多个locator或server tags配置在一起来连接一个存在的data grid,此外所有配置pool的属性都是支持的。
这个配置会为每个连接到locator定义在member上的region自动创建ClientRegion Bean。所以可以无缝的使用Spring Data mapping 注解,GemfireTemplate,织入程序中
<gfe-data:datasource> <locator host="somehost" port="1234"/> </gfe-data:datasource> <gfe:client-region id="Customer" shortcut="CACHING_PROXY"/>
4.2.5配置Gemfire Region
region是用来存储cache中检索的数据。Region是一个继承了java.util.Map,可以使用键值对访问的接口。
相当于关系型数据库中的table
Gemfire实现了以下几个类型的region
1、Replicated-数据在每个cache member中存在一个备份,这提供了很高的读性能,但是写比较耗时
2、Partioned-数据分别储存在多个cache member中的bucket中,这提供了高的读写性能,并且适用于非常大的数据集(对于单点来说很大的数据集)
3、Local-数据只存储在本地节点
4、Client-从技术上说,client region是一个扮演者代理到远程服务器上的replicated或partitioned region的本地region,
他将持有数据,在本地创建和查询,他可以是空的。本地的更新会同步到远程cache server,并且Client region可以接受事件来保持和远端同步
使用外部配置Region
<gfe:lookup-region id="region-bean" name="Orders"/>
用lookup-region来关联在cache.xml中配置好的Region(Orders是既存的Region名)
<!-- lookup for a region called 'Orders' --> <gfe:lookup-region id="Orders"/>
如果没有配置name 就会用id属性,如果Region不存在,就会抛出初始化异常
<gfe:cache id="cache"/>
<gfe:lookup-region id="region-bean" name="Orders" cache-ref="cache"/>
用cache-ref来关联某个cache
lookup-region提供了一个简单的方法检索存在的,预配置好的region。不暴露Region语义和设置基础设施
自动Region查找
Spring Data Gemfire1.5以后可以自动查找定义在cache.xml中的Region,并且使用<gfe:cache>中的‘cache-xml-location’来引入
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<region name="Parent" refid="REPLICATE">
<region name="Child" refid="REPLICATE"/>
</region>
</cache>
<gfe:cache cache-xml-location="cache.xml"/>用这句话来映入cache.xml
用<gfe:lookup-region id="Parent"/>来关联某个region到Spring上下文
<gfe:auto-region-lookup/>自动创建关联到Region的Beans
Spring Data Gemfire使用BeanPostProcessor接口来发送Cache处理,将Region加到Spring上下文
package example;
import ...
@Repository("appDao")
@DependsOn("gemfireCache")
public class ApplicationDao extends DaoSupport {
@Resource(name = "Parent")
private Region<?, ?> parent;
@Resource(name = "/Parent/Child")
private Region<?, ?> child;
...
}
也可以用XML定义:
<bean class="example.ApplicationDao" depends-on="gemfireCache"/>
用<gfe:auto-region-lookup>来加载cache.xml中的Region
配置Region
Spring Data Gemfire 提供综合的支持来通过以下元素来配置各种类型的Region
-
Local Region
<local-region>
-
Replicated Region
<replicated-region>
-
Partitioned Region
<partitioned-region>
-
Client Region
<client-region>
一般的Region属性
cache-ref Cache名。。。。表省略
Cache Listeners
Cache Listeners 和一个Region一起注册来处理region事件,例如创建条目、更新、删除。Cache Listener是一个实现了CacheListener接口的类。
一个Region可能有许多个listener,用cache-listener对象来添加到*-region对象中。下面的例子中有两个'CacheListener'
<gfe:replicated-region id="region-with-listeners"> <gfe:cache-listener> <!-- nested cache listener reference --> <ref bean="c-listener"/> <!-- nested cache listener declaration --> <bean class="some.pkg.AnotherSimpleCacheListener"/> </gfe:cache-listener> <bean id="c-listener" class="some.pkg.SimpleCacheListener"/> </gfe:replicated-region>
Cache Loaders和Cache Writers
和cache-listener相似,名空间提供了cache-loader和cache-writer元素来注册各自组建到Region中
CacheLoader调用一个Cache允许从外部数据源添加条目。CacheWriter在条目被穿件或者更新,需要同步外部数据源时被调用
Subregions
在1.2.0后,Spring Data Genfire添加了对Sub region的支持。允许region被组织在一个层次关系中
例如:Gemfire允许/Customer/Address region和另一个/Employee/Address region。并且一个subregion有自己的subregions和他自己的配置。
一个subregion不会从parent region中继承属性。Region的类型可能是混合的匹配除Gemfire约束,一个subregion 会自然地声明为region的子元素,subregion的名字一般是简单名。
<beans> <gfe:replicated-region name="Customer"> <gfe:replicated-region name="Address"/> </gfe:replicated-region> <gfe:replicated-region name="Employee"> <gfe:replicated-region name="Address"/> </gfe:replicated-region> </beans>
注意,Monospaced ([id])属性在subregion中是不被允许的。subregion使用名字
/Customer/Address region和/Employee/Address region创建的,所以别的bean,例如GemfireTemplatez在调用他们的时候需要使用全名,在使用OQL时也要使用全路径名
Region Templates
Spring Data Gemfire1.5版本后提供Region Templates。这一特性允许开发者来一次性定义通用的Region设置和属性并在Spring上下文中声明Region时多次使用。
Region Template有5个标签
表略。。。。
<gfe:*-region>元素和<gfe:*-region-template>元素有template属性来定义从Region配置中继承的Region Template.
甚至,Region template可以从其他的Region Template中继承。
下面有个例子
<gfe:async-event-queue id="AEQ" persistent="false" parallel="false" dispatcher-threads="4">
<gfe:async-event-listener>
<bean class="example.AeqListener"/>
</gfe:async-event-listener>
</gfe:async-event-queue>
<gfe:region-template id="BaseRegionTemplate" cloning-enabled="true"
concurrency-checks-enabled="false" disk-synchronous="false"
ignore-jta="true" initial-capacity="51" key-constraint="java.lang.Long"
load-factor="0.85" persistent="false" statistics="true"
value-constraint="java.lang.String">
<gfe:cache-listener>
<bean class="example.CacheListenerOne"/>
<bean class="example.CacheListenerTwo"/>
</gfe:cache-listener>
<gfe:entry-ttl timeout="300" action="INVALIDATE"/>
<gfe:entry-tti timeout="600" action="DESTROY"/>
</gfe:region-template>
<gfe:region-template id="ExtendedRegionTemplate" template="BaseRegionTemplate"
index-update-type="asynchronous" cloning-enabled="false"
concurrency-checks-enabled="true" key-constraint="java.lang.Integer"
load-factor="0.55">
<gfe:cache-loader>
<bean class="example.CacheLoader"/>
</gfe:cache-loader>
<gfe:cache-writer>
<bean class="example.CacheWriter"/>
</gfe:cache-writer>
<gfe:membership-attributes required-roles="readWriteNode" loss-action="limited-access" resumption-action="none"/>
<gfe:async-event-queue-ref bean="AEQ"/>
</gfe:region-template>
<gfe:partitioned-region-template id="PartitionRegionTemplate" template="ExtendedRegionTemplate"
copies="1" local-max-memory="1024" total-max-memory="16384" recovery-delay="60000"
startup-recovery-delay="15000" enable-async-conflation="false"
enable-subscription-conflation="true" load-factor="0.70"
value-constraint="java.lang.Object">