`

分布式缓存ehcache

阅读更多

[转载自] http://blog.sina.com.cn/s/blog_6151984a0101816j.html

 

 

 

分布式EHCACHE系统在缓存同步上存在着不小的缺陷

 (2012-08-29 15:10:05)
标签: 

ehcache

 

同步

 

杂谈

分类: java和数据库

分布式EHCACHE系统,如何实现缓存数据同步?

  • 方式1: RMI组播方式

这也是最常用的方式,配置简单,关键一点,各EHCACHE的节点配置都是一样的

例子:

spring 配置中调用的ehcache文件
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
   <property name="configLocation">
     <value>classpath:ehcache_mc.xml</value>
   </property>
 </bean>
 
 <bean id="userCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
   <property name="cacheManager">
     <ref local="cacheManager"/>
   </property>
   <property name="cacheName">
     <value>userCache</value>
   </property>
 </bean> 

 ehcache_mc.xml:

    <cache name="userCache"
           maxElementsInMemory="10000"
           maxElementsOnDisk="0"
           eternal="true"
           overflowToDisk="true"
           diskSpoolBufferSizeMB="20"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
     <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" 
              properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy= true, replicateRemovals= true " />
         <cacheEventListenerFactory class="cn.com.gary.test.ehcache.EventFactory" /> <!-- 打印ehcache 动作日志 -->
    </cache>
   
 <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446,timeToLive=255"/>
 <cacheManagerPeerListenerFactory
         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

原理:
这样当缓存改变时,ehcache会向230.0.0.1端口4446发RMI UDP组播包

这种组播方式的缺陷:
EHCACHE的组播做得比较初级,功能只是基本实现(比如简单的一个HUB,接两台单网卡的服务器,互相之间组播同步就没问题),
对一些复杂的环境(比如多台服务器,每台服务器上多地址,尤其是集群,存在一个集群地址带多个物理机,每台物理机又带多个虚拟站的子地址),就容易出现问题.

究其原因, 组播/广播转发是一个很复杂的过程. 简单的说, 一个组播缺省只能在一个网段内传输,不能跨网段.
举个简单的例子, PC机网卡的自动获取地址,还有WINDOWS里的网上邻居,都属于典型的广播服务,所以这些服务都是不能跨网段(跨路由)的,当然也不是完全不行,借助一些工具,比如CISCO路由器上的udp-broadcast helper,或者微软的netBIOS on Tcp/ip,就可以实现.
我们自己安装一些软件时,也经常遇到比如"将网卡的广播转发打开"之类的操作.
 
而在多网卡的主机,或同一网卡多IP的主机上,尽管地址可能是一个网段内的,但其实地址间已经存在跳数了(hop),其实就是从一个地址向另一个地址跳. 这时广播/组播就容易被阻断.
比如: 我们自己的WINDOWS上装一个VMWARE虚拟机,尽管IP地址是一个网段的,但因为虚拟机采用的桥模式不是标准的网桥模式(也可能是需要配置一下,但说实话懒得研究VMWARE了),所以广播/组播也经常出现不通的情况.

更何况在一些云计算的环境,集群的分布往往是跨网段的,甚至是跨地域的.这时更难以依赖这种初级的组播同步.

总之,分布式集群架构,建议EHCACHE改为PEER-2-PEER的同步方式.

 

  • 方式2:p2p方式

其实就是每个节点和其他n-1个节点都建立TCP的P2P PEER.
下面是一个3节点的ehcache分布式部署:

节点1:
spring 配置中调用的ehcache文件
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
   <property name="configLocation">
     <value>classpath:ehcache_p2p_40001.xml</value>
   </property>
 </bean>
 
 <bean id="userCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
   <property name="cacheManager">
     <ref local="cacheManager"/>
   </property>
   <property name="cacheName">
     <value>userCache</value>
   </property>
 </bean>

ehcache_p2p_40001.xml
    <cache name="userCache"
           maxElementsInMemory="10000"
           maxElementsOnDisk="0"
           eternal="true"
           overflowToDisk="true"
           diskSpoolBufferSizeMB="20"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
          <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" 
              properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy= true, replicateRemovals= true " />
          <cacheEventListenerFactory class="cn.com.dwsoft.test.ehcache.EventFactory" />   
    </cache>
       <!--调用ehcache2的RMI-->
   <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
  properties="peerDiscovery=manual,rmiUrls=//192.168.0.251:40002/userCache|//192.168.0.251:40003/userCache"/>

 <!--RMI监听40001端口-->
    <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=192.168.0.122,port=40001,socketTimeoutMillis=2000"/> 

 节点2:
spring 配置中调用的ehcache文件
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
   <property name="configLocation">
     <value>classpath:ehcache_p2p_40002.xml</value>
   </property>
 </bean>
 
 <bean id="userCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
   <property name="cacheManager">
     <ref local="cacheManager"/>
   </property>
   <property name="cacheName">
     <value>userCache</value>
   </property>
 </bean>

ehcache_p2p_40002.xml
    <cache name="userCache"
           maxElementsInMemory="10000"
           maxElementsOnDisk="0"
           eternal="true"
           overflowToDisk="true"
           diskSpoolBufferSizeMB="20"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
          <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" 
              properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy= true, replicateRemovals= true " />
          <cacheEventListenerFactory class="cn.com.dwsoft.test.ehcache.EventFactory" />   
    </cache>

   <!--调用ehcache2的RMI-->
   <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
  properties="peerDiscovery=manual,rmiUrls=//192.168.0.122:40001/userCache|//192.168.0.251:40003/userCache"/>

 <!--RMI监听40001端口-->
    <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=192.168.0.251,port=40002,socketTimeoutMillis=2000"/>

节点3:
spring 配置中调用的ehcache文件
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
   <property name="configLocation">
     <value>classpath:ehcache_p2p_40003.xml</value>
   </property>
 </bean>
 
 <bean id="userCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
   <property name="cacheManager">
     <ref local="cacheManager"/>
   </property>
   <property name="cacheName">
     <value>userCache</value>
   </property>
 </bean>

ehcache_p2p_40003.xml
    <cache name="userCache"
           maxElementsInMemory="10000"
           maxElementsOnDisk="0"
           eternal="true"
           overflowToDisk="true"
           diskSpoolBufferSizeMB="20"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
          <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" 
              properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy= true, replicateRemovals= true " />
          <cacheEventListenerFactory class="cn.com.dwsoft.test.ehcache.EventFactory" />   
    </cache>

   <!--调用ehcache2的RMI-->
   <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
  properties="peerDiscovery=manual,rmiUrls=//192.168.0.122:40001/userCache|//192.168.0.251:40002/userCache"/>

 <!--RMI监听40001端口-->
    <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=192.168.0.251,port=40003,socketTimeoutMillis=2000"/>
 

测试

节点1添加一条缓存条目

节点1日志:
  2012-08-28 17:00:39,859 INFO CustomActionSupport.getParameter(188)-/admin/inputEntry.do?
submit=提交&cachekey=mac1228&cachevalue=1228
2012-08-28 17:00:39,859 INFO TestAction.inputEntry(97)-mac1228:1228
2012-08-28 17:00:39,875 INFO CacheEvent.log(65)-in notifyElementPut[ key = mac1228, value=1228, version=1, hitCount=0, CreationTime = 1346144439875, LastAccessTime = 1346144439875 ]
2012-08-28 17:00:39,875DEBUG ServletDispatcherResult.debug(57)-Forwarding to location /index.jsp  
节点2日志:
  2011-09-22 14:25:51,262 INFO CacheEvent.log(65)-in notifyElementPut[ key = mac1228, value=1228, version=1, hitCount=0, CreationTime = 1346144440000, LastAccessTime = 1316672751253 ] 
节点3日志:
  2011-09-22 14:25:51,198 INFO CacheEvent.log(65)-in notifyElementPut[ key = mac1228, value=1228, version=1, hitCount=0, CreationTime = 1346144440000, LastAccessTime = 1316672751198 ] 

节点2添加一条缓存条目

节点1日志:
  2012-08-28 16:54:55,890 INFO CacheEvent.log(65)-in notifyElementPut[ key = mac25181904, value=25181904, version=1, hitCount=0, CreationTime = 1316672407000, LastAccessTime = 1346144095890 ] 
节点2日志:
  2011-09-22 14:20:06,041 INFO CustomActionSupport.getParameter(188)-/admin/inputEntry.do?
submit=提交&cachekey=mac25181904&cachevalue=25181904
2011-09-22 14:20:06,042 INFO TestAction.inputEntry(97)-mac25181904:25181904
2011-09-22 14:20:06,050DEBUG ServletDispatcherResult.debug(57)-Forwarding to location /index.jsp 
节点3日志:
  2011-09-22 14:20:06,568 INFO CacheEvent.log(65)-in notifyElementPut[ key = mac25181904, value=25181904, version=1, hitCount=0, CreationTime = 1316672407000, LastAccessTime = 1316672406568 ]  
 

 

总结:
上面说了,组播方式同步不可靠.
P2P方式其实也存在不可靠的地方.这就是P2P要求每个节点的EHCACHE要指向其他的N-1个节点,
当在云环境,或集群域下, 多个子节点部署项目都是被自动发布的,这时很难做到不同节点有不同的配置,因为自动发布,配置往往都是相同的,这样P2P就很难实现.
总之,这种同步型应用是很难适应大规模分布式部署的,还是建议采用一些集中软件比如MEMCACHED.

分享到:
评论

相关推荐

    分布式缓存EhCache用户指南.docx

    【分布式缓存 EhCache 用户指南】 EhCache 是一个广泛使用的Java缓存库,自1.2版本开始,它引入了分布式缓存的功能,允许在多台机器间共享和同步数据,以支持大规模、高并发的应用场景。分布式缓存通过插件机制实现...

    Ehcache分布式缓存与其在SpringBoot应用

    在分布式环境中,Ehcache通过使用JGROUP来实现分布式缓存。JGROUP是一个用于构建可靠集群通信的库,可以提供组成员资格、故障检测、传输协议等多种功能,使得Ehcache能够在多个节点之间共享和同步缓存数据。Ehcache...

    基于JGROUPS的ehcache的分布式缓存复制

    本文将深入探讨基于JGROUPS的Ehcache实现的分布式缓存复制,这是一种在Java应用中广泛使用的缓存解决方案。 首先,Ehcache是一个开源的、高性能的Java缓存库,提供本地缓存以及分布式缓存功能。它支持多种缓存策略...

    分布式缓存.docx

    本文将深入探讨Ehcache作为JVM缓存和分布式缓存的角色,以及Redis作为分布式缓存的解决方案,包括其分片集群、哨兵系统、数据结构、主从复制以及避免缓存问题的策略。 首先,我们了解为什么需要使用缓存。缓存的...

    Ehcache分布式缓存与其在spring中的使用

    ### Ehcache分布式缓存及其在Spring中的应用 #### 一、Ehcache概述与原理 Ehcache是一款高效且轻量级的纯Java缓存框架,由于其出色的性能和易于集成的特点,在Java开发中有着广泛的应用。作为Hibernate的默认缓存...

    30_分布式缓存相关面试题的回答技巧总结.zip

    Java中常用的分布式缓存框架有Spring Cache、Ehcache、Hibernate Second Level Cache等,其中Spring Data Redis和Jedis提供了与Redis的集成。 4. **Redis和Memcached的区别** - Redis支持数据持久化,而Memcached...

    ehcache分布式缓存实例

    本实例将探讨如何利用Ehcache实现基于RMI(Remote Method Invocation)的分布式缓存。 一、Ehcache简介 Ehcache是Terracotta公司开发的一个高性能、可伸缩的本地和分布式缓存解决方案。它支持多种缓存策略,如LRU...

    分布式缓存

    分布式缓存是现代大型互联网应用中不可或缺的一部分,它在处理海量数据、提高系统性能和响应速度方面发挥着关键作用。本书“深入分布式缓存:从原理到实践”旨在全面解析分布式缓存的核心概念、工作原理及其在实际...

    Ehcache分布式缓存入门案例demo_文件转树结构_

    Ehcache是一个高性能、轻量级的Java分布式缓存库,它被广泛应用于提升应用程序的性能,通过存储经常访问的数据来减少对数据库的依赖,从而加快系统的响应速度。本入门案例将带你了解如何使用Ehcache实现分布式缓存,...

    分布式缓存测试框架 RadarGun.zip

    2. **插件化架构**:RadarGun采用插件化设计,允许用户自定义测试场景和负载生成器,以适应不同的分布式缓存技术,如Infinispan、Hazelcast、Ehcache等。 3. **灵活的测试配置**:测试配置可以通过YAML文件进行,...

    分布式缓存架构11.docx

    ### 分布式缓存架构与Ehcache集群详解 #### 一、为什么使用缓存? 在现代互联网系统中,为了提高系统的响应速度和降低数据库的压力,缓存技术被广泛应用。缓存通过暂时存储数据副本的方式来加快数据访问的速度,...

    EhCache用户指南(分布式缓存)

    超好的东西,分布式缓存所需配置都在里面,感谢为我们翻译的大牛~~

    ehcache实例

    Ehcache是一个开源的Java分布式缓存框架,广泛应用于提高应用程序性能和减少数据库负载。它提供了内存和磁盘存储,支持缓存数据的过期策略,以及缓存数据的自动同步。在本实例中,我们将深入探讨Ehcache的核心概念、...

    ehcache

    Ehcache 支持分布式缓存,通过 Terracotta 服务器实现跨节点的数据共享。这样,多台服务器上的应用可以共享同一份缓存,提高系统的可扩展性和性能。 ## 6. Ehcache 的升级与优化 随着技术的发展,Ehcache 也经历了...

    金民一期婚姻管理测试系统_开发框架功能点-分布式缓存.pdf

    Ehcache 是一种流行的分布式缓存框架,提供了高性能的缓存解决方案。我们可以通过以下方式配置 Ehcache 依赖项: ``` &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt; &lt;artifactId&gt;ehcache-core &lt;version&gt;2.6.11 ``` ...

    推荐5个强大的Java分布式缓存框架

    Ehcache 和 Cacheonix 均是优秀的Java分布式缓存框架,它们不仅能够显著提升应用程序的性能,还能提供高度可扩展性和灵活性。开发者可以根据项目的具体需求选择最适合的框架。接下来的文章中,我们将继续探讨另外三...

    SpringBoot redis分布式缓存实现过程解析

    常见的分布式缓存解决方案有Ehcache、Redis、Memcached等。今天我们将使用Redis来实现分布式缓存。 Redis的配置 首先,我们需要在application.yml中配置Redis的信息,如下所示: ``` spring: redis: database: ...

    缓存 ehcache-1.3.0.rar

    - **分布式缓存**: Ehcache 支持集群部署,可以实现跨节点的数据共享,提高高可用性和可伸缩性。 - **缓存加载策略**: 提供了自动加载机制,当缓存中找不到所需数据时,可以从数据库或其他源加载。 6. **缓存的...

Global site tag (gtag.js) - Google Analytics