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地址:点击打开链接
- ehcache集群详解三(RMI集群)
- EhCache RMI 集群模式
- ehcache之RMI集群配置
- ehcache 集群使用 rmi方式
- RMI方式Ehcache集群的源码分析
- ehcache 集群使用 rmi方式 有图有真想
- EhCache RMI 分布式缓存/缓存集群
- ehcache集群详解一(支持的集群类型)
- ehcache集群详解二(集群的最小配置)
- ehcache集群
- EhCache集群
- Ehcache集群
- [转]RMI方式Ehcache集群的源码分析
- ehcache的使用(2)-- 集群
- Ehcache分布式缓存实例(集群环境)
- ehcache缓存集群
- Ehcache集群环境配置
- Ehcache集群环境配置
- ChartServer
- 虚拟化的逆袭:OpenFlow和SDN
- leetcode - 字符串转换成数字(String to Integer)atoi
- java 建造者模式
- 回忆是一行行无从剪接的风景
- ehcache集群详解三(RMI集群)
- 欢迎使用CSDN-markdown编辑器
- Intellij IDEA创建Java Web工程以及部署
- java中生成32位随机ID
- makefile使用教程
- 初触Python,关于pyquery解析html(百度贴吧)
- 1081. Rational Sum (20)
- UVA_10739_StringToPalindrome
- 十大数据挖掘算法的R语言实现