ehcache集群详解三(RMI集群)

来源:互联网 发布:手机代理上网软件 编辑:程序博客网 时间:2024/06/11 01:08

一、通过RMI来进行缓存集群

通过RMI来进行集群的好处:

1.RMI是java默认的远程调用机制。

2.他可以对TCP套接字进行优化设置。

3.Ehcache元素的key和value如果要存在磁盘上都需要实现Serializable接口,于是缓存可以直接通过RMI进行传输而不需要转成其他格式,比如转为XML。

4.RMI可以通过配置来穿越防火墙。



RMI是一个端对端的协议,他会产生许多网络流量。Ehcache需要通过大量的通讯来实现异步的数据复制。

为了实现RMI集群,需要对CacheManager配置PeerProvider 和 CacheManagerPeerListener。

为了让集群的每个节点进行同步,我们需要添加 RMI cacheEventListener来发送信息。我们也可以配置一个缓存节点来引导其他缓存。

二、合适的元素类型

只有允许序列化的元素才能在集群里进行传输。像一些操作,比如删除,只需要删除元素的键而不是整个元素,只需要key是需要可以被序列化的,就算整个元素没有被序列化这样这些操作也能在集群里进行同步。


三、PeerProvider配置

1.成员发现

Ehcache集群有一个叫做组的概念,每个缓存都是组的一个成员,他们之间是平等的,每个master这个概念。我们是怎么发现一个缓存在一个集群里呢?这个问题我们叫做“成员发现”。Ehchace提供能两套机制来实现成员发现:自动、手动。

2.自动成员发现

自动成员发现使用TCP组播来连接和维护一个组播组。他最大的特点就是配置是最少的并且可以自动的添加和删除成员,而且你不需要了解服务器集群的其他知识。这种集群方式是默认推荐的。成员每秒都会给集群组发送一个心跳,如果一个成员超过5秒都没有发送心跳,缓存组将把他移除集群,一旦成员开始向组发送心跳信号,缓存组又将把他添加进集群。

我们将每个缓存配置为允许被其他成员发现。设置自动发现成员,需要配置cacheManagerPeerProviderFactory和下面相关的属性

peerDiscovery=automaticmulticastGroupAddress=multicast address | multicast host namemulticastGroupPort=porttimeToLive=0-255 (设置之前请看下面的常见描述)hostName=用来接收和发送多播套接字的主机名或者IP地址

例子

假设你在集群里有两台服务器,名字叫servier1和server2。你希望同步sampleCache11 和 sampleCache12,每个服务器上面的配置都是一样的

<cacheManagerPeerProviderFactory          class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"         properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,         multicastGroupPort=4446,         timeToLive=32"/>

3.手动的成员发现

手动成员发现需要给监听器配置ip地址和端口。任何成员不能在运行的时候添加和移除。手动的成员发现推荐在组播不能实现的时候使用,比如集群的路由不允许发送组播报文的时候。你也可以单向的缓存数据同步,比如让server2可以同步server1的数据,但sever1不能同步server2的。

配置手动发现成员时需要配置cacheManagerPeerProviderFactory的如下属性

peerDiscovery=manual
rmiUrls=//server:port/cacheName, ...

 rmiUrls是缓存成员的列表,但是不包括自己,也就是被配置的这台服务器的地址。

案例

比如你的集群里有server1和server2两台服务器,你希望同步sampleCache11 and sampleCache12。

下面是server1的配置

<cacheManagerPeerProviderFactory       class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"       properties="peerDiscovery=manual,       rmiUrls=//server2:40001/sampleCache11|//server2:40001/sampleCache12"/>

下面是server2的配置

<cacheManagerPeerProviderFactory       class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"       properties="peerDiscovery=manual,       rmiUrls=//server1:40001/sampleCache11|//server1:40001/sampleCache12"/>

四、配置CacheManagerPeerListener

CacheManagerPeerListener用来监听从其他成员发送过到当前CacheManager的信息。

我们需要配置CacheManagerPeerListenerFactory 通过插件机制来生成一个 CacheManagerPeerListener。

CacheManagerPeerListenerFactory有以下属性:

class - factory类的全限定名
properties - 仅对工厂有意义的属性,用逗号隔开。


Ehcache自带了一个基于RMI的分布式系统,他的监听组件就是 RMICacheManagerPeerListener,是用于配置RMICacheManagerPeerListenerFactory的。

他的配置方式如下

<cacheManagerPeerListenerFactory       class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"       properties="hostName=localhost, port=40001,       socketTimeoutMillis=2000"/>
hostName (可选)-运行监听的服务器的主机名,指定了需要进行组播的主机和接受信息的集群。在CacheManager启动的时候就会检查主机是否可达,如果不可达将会跑出连接拒绝的异常。如果没有指定主机名,主机名将会使用 InetAddress.getLocalHost().getHostAddress()来作为默认的主机名。需要注意的时,除非你的集群配置同一台机器,千万不要把主机名设置为127.0.0.1,因为这个地址在网络是不可见的,所以无法接受远程主机发送的数据。

port(必选)-监听器监听的端口。

socketTimeoutMillis (可选)-同步超时时间,默认事2000ms。

五、配置CacheReplicators

每个cache在同步的时候需要有一个事件监听器,我们通过添加cacheEventListenerFactory配置来设置监听器。

<!-- Sample cache named sampleCache2. --><cache name="sampleCache2"      maxEntriesLocalHeap="10"      eternal="false"      timeToIdleSeconds="100"      timeToLiveSeconds="100"      overflowToDisk="false">  <cacheEventListenerFactory        class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"        properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,        replicateUpdatesViaCopy=false, replicateRemovals=true "  /></cache>
class - use net.sf.ehcache.distribution.RMICacheReplicatorFactory

这个监听工厂有以下属性:
replicatePuts=true | false - 当有新元素放进缓存时时候同步到其他成员. 默认为true.
replicateUpdates=true | false - 是否有元素被覆盖的时候同步. 默认为 true.
replicateRemovals=true - 是否有元素被移除的时候同步. 默认为true.
replicateAsynchronously=true | false - 数据复制的时候为异步 (true) 还是同步 (false). 默认为true.
replicateUpdatesViaCopy=true | false - 元素被复制到其他缓存或者删除时进行同步 (true), 默认为true.


如果你不想敲代码,你可以使用默认的配置,默认情况下所有复制都是异步的,你可如下减少RMICacheReplicatorFactory的属性配置

<!-- 缓存的名字叫 sampleCache4. 那些RMICacheReplicatorFactory没有说明的属相都默认为true --><cache name="sampleCache4"       maxEntriesLocalHeap="10"       eternal="true"       overflowToDisk="false"       memoryStoreEvictionPolicy="LFU">    <cacheEventListenerFactory       class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/></cache>

六、缓存的成员引导(初始化)

当一个缓存成员刚刚启动的时候,他与其集群的其他缓存是不一致的,当引导完(初始化)成后才会一致。引导会从任意一个集群成员里获取键值的列表,然后批量保存在自己的缓存里。如果引导失败缓存将不会启动。如果一个缓存正要进行同步,但在引导完成之前也有段时间数据时不一致的。下面有一些引导过程的例子

删除被引导覆盖的过程:

1.缓存A的key有:1,2,3,4,5

2.缓存B开始引导

3.缓存A删除Key2

4.缓存B删除key2,然后引导结束。

存放被引导覆盖的过程:

1.缓存A的key有:1,2,3,4,5

2.缓存B开始引导

3.缓存A更新了key2的值

4.缓存B启动引导然后将更新key2的值。

在引导获取键值并存放如缓存之后,事物才会进行提交。

这里可能会引起一个同步事物的回滚,为了解决这个问题,事物的提交在引导完成后才会写入缓存。这个过程中缓存之间还会保持一个关联,应为在引导完成并且提交事物后缓存才能使用。


七、我们需要注意的一些问题

Windows安装Tomcat:

在tomcat启动时如果tomcat的安装路径中有空格的话,在启动时RMI监听器会失败。由于在Windows上默认是装在Program Files文件夹里的,所以这个问题经常发生。

多播阻断:

自动的成员发现与多播联系紧密。多播可能被路由阻断,像Xen和VMWare这种虚拟机也可以阻断多播。如果设置的允许多播,你可能还在要将你的网卡的相关配置打开。一个简单的办法可以告诉多播是否有效,那就是使用ehcache remote debugger来看“心跳”是否有用。

广播传播的不够远或是传得太远:

你可以通过设置badly misnamed time to live来控制广播传播的距离。用广播IP协议时,timeToLive的值指的是数据包可以传递的域或是范围。约定如下:

0是限制在同一台主机

1是限制在同一个子网

32是限制在同一个场所

64是限制在同一个地区

128是限制在同一个大洲

255是不限制

在Java实现中默认值是1,就是说在同一个子网中传播。改变超时时间也就是改变timeToLive属性可以限制或是扩展传播的范围。


八、EHCACHE RMI 集群案例DEMO

需要注意的是各节点的缓存名字必须一样,不然不能同步,我就是之前没注意花了点时间。

demo地址:点击打开链接
















0 0
原创粉丝点击