接到配合架构部要求配合测试需求,对EhCache 进行测试,在此之前,未接触过ehcache缓存,之前知道一些缓存,但是还真没了解过内存缓存。于是百度,看书,查资料,先恶补一下ehcache的一些知识,然后整理如下:

EhCache 是一个分布式缓存,分布式缓存系统简介:

Ehcache是一个纯java的进程内缓存框架,也就是说Ehcache是一个进程中的缓存系统。

Ehcache的主要特性有:

  1. 快速、精干,简单
  2. 多种缓存策略
  3. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
  4. 缓存数据会在虚拟机重启的过程中写入磁盘
  5. 可以通过RMI、可插入API等方式进行分布式缓存
  6. 具有缓存和缓存管理器的侦听借口
  7. 支持多缓存管理器实例,以及一个实例的多个缓存区域
  8. 提供Hibernate 的缓存实现。

注意:由于Ehcache是进程中的缓存系统,一旦将应用部署到集群环境中, 每一个节点维护各自的缓存数据,当某个节点对缓存数据进行更新, 这些更新的数据无法再其他节点中共享, 不仅会降低节点运行的效率, 而且会导致数据不同步的情况发生。 例如某个网站采用A、B 两个节点作为集群部署, 当A节点的缓存更新后, 而B节点缓存尚未更新就可能出现用户在浏览页面的时候,一会是更新后的数据, 一会是尚未更新的数据。

所以就需要用到EhCache的集群解决方案

EhCache  1.7 版本开始,支持五种集群方案,分别是:

• Terracotta

RMI

• JMS

• JGroups

• EhCache Server

其中的三种最为常用集群方式,分别是 RMI、JGroups 以及 EhCache Server 。本文主要介绍RMI的原理及测试方法,

RMI方式缓存集群/配置分布式缓存

RMI是java的一种远程方法调用技术,是一种点对点的基于java对象的通讯方法。Ehcache从1.2版本开始支持RMI方式的缓存集群。在集群环境中Ehcache所有缓存对象的键和值都必须是可序列化的,也就是说必须实现java.io.Serializable 接口,这点在其他集群方式下也是需要遵守的。

下面是RMI集群模式的结构图:

采用RMI集群模式时,集群中的每个节点都是对等关系,并不存在主节点或者从节点的概念,因此节点间必须有一个机制能够互相认识对方,必须知道其他节点的信息,包括主机ip,端口号等。Ehcache提供两种节点的发现方式:手工配置和自动发现。手工配置方式要求在每个节点中配置其他所有的节点连接信息,一旦集群中的节点发生变化是,需要对缓存进行重新配置。

由于RMI 是java中内置支持的技术, 因此使用RMI集群模式时, 无需引入其他的jar包,Ehcache 本身就带有支持RMI集群的功能, 使用RMI集群模式需要在ehcache.xml配置文件中定义cacheManagerPeerProviderFactory 节点。

分布式同步缓存要让这边的cache知道对方的cache,叫做Peer Discovery(成员发现) EHCache实现成员发现的方式有两种:

手动查找配置方法:

A、 在ehcache.xml中配置PeerDiscovery成员发现对象

Server1配置,配置本地hostName、port是400001,分别监听192.168.8.32:400002的mobileCache和192.168.5.231:400003 的mobileCache。注意这里的mobileCache是缓存的名称,分别对应着server2、server3的cache的配置。

<?xml version="1.0" encoding="gbk"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"><diskStore path="java.io.tmpdir"/><!-- 集群多台服务器中的缓存,这里是要同步一些服务器的缓存server1 hostName:192.168.8.9 port:400001 cacheName:mobileCacheserver2 hostName:192.168.8.32 port:400002 cacheName:mobileCacheserver3 hostName:192.168.8.231 port:400003 cacheName:mobileCache注意:每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置--><!-- server1 的cacheManagerPeerProviderFactory配置 --><cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="hostName=localhost,port=400001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.32:400002/mobileCache|//192.168.5.231:400003/mobileCache"/>
</ehcache>

同样在你的另外2台服务器上增加配置

Server2,配置本地host,port为400002,分别同步192.168.8.9:400001的mobileCache和192.168.5.231:400003的mobileCache

<!-- server2 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="hostName=localhost,port=400002,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.9:400001/mobileCache|//192.168.5.231:400003/mobileCache"
/>

Server3,配置本地host,port为400003,分别同步192.168.8.9:400001的mobileCache缓存和192.168.8.32:400002的mobileCache缓存

<!-- server3 的cacheManagerPeerProviderFactory配置 -->
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="hostName=localhost,port=400003,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.9:400001/mobileCache|//192.168.8.32:400002/mobileCache"
/>

这样就在三台不同的服务器上配置了手动查找cache的PeerProvider成员发现的配置了。 值得注意的是你在配置rmiUrls的时候要特别注意url不能重复出现,并且端口、地址都是对的。

如果指定,hostname将使用InetAddress.getLocalHost().getHostAddress()来得到。

注意:不要将localhost配置为本地地址127.0.0.1,因为它在网络中不可见将会导致不能从远程服务器接收信息从而不能复制。在同一台机器上有多个CacheManager的时候,你应该只用localhost来配置。

B、 下面配置缓存和缓存同步监听,需要在每台服务器中的ehcache.xml文件中增加cache配置和cacheEventListenerFactory、cacheLoaderFactory的配置<defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/>
<!-- 配置自定义缓存maxElementsInMemory:缓存中允许创建的最大对象数eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。timeToIdleSeconds:缓存数据空闲的最大时间,也就是说如果有一个缓存有多久没有被访问就会被销毁,如果该值是 0 就意味着元素可以停顿无穷长的时间。timeToLiveSeconds:缓存数据存活的时间,缓存对象最大的的存活时间,超过这个时间就会被销毁,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。overflowToDisk:内存不足时,是否启用磁盘缓存。memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。每一个小时更新一次缓存(1小时过期)
-->
<cache name="mobileCache"maxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="1800"timeToLiveSeconds="3600"memoryStoreEvictionPolicy="LFU"><!-- RMI缓存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory这个工厂支持以下属性:replicatePuts=true | false – 当一个新元素增加到缓存中的时候是否要复制到其他的peers。默认是true。replicateUpdates=true | false – 当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。replicateRemovals= true | false – 当元素移除的时候是否进行复制。默认是true。replicateAsynchronously=true | false – 复制方式是异步的指定为true时,还是同步的,指定为false时。默认是true。replicatePutsViaCopy=true | false – 当一个新增元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。replicateUpdatesViaCopy=true | false – 当一个元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。asynchronousReplicationIntervalMillis=1000--><!-- 监听RMI同步缓存对象配置 注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,和expire --><cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true "/><!-- 用于在初始化缓存,以及自动设置 --><bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/>
</cache>

View Code

下面给出server1的完整的ehcache.xml的配置:

<?xml version="1.0" encoding="gbk"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"><diskStore path="java.io.tmpdir"/><!-- 集群多台服务器中的缓存,这里是要同步一些服务器的缓存server1 hostName:192.168.8.9 port:400001 cacheName:mobileCacheserver2 hostName:192.168.8.32 port:400002 cacheName:mobileCacheserver3 hostName:192.168.8.231 port:400003 cacheName:mobileCache注意每台要同步缓存的服务器的RMI通信socket端口都不一样,在配置的时候注意设置--><!-- server1 的cacheManagerPeerProviderFactory配置 --><cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="hostName=localhost,port=400001,socketTimeoutMillis=2000,peerDiscovery=manual,rmiUrls=//192.168.8.32:400002/mobileCache|//192.168.5.231:400003/mobileCache"/><defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30" overflowToDisk="false"/><!-- 配置自定义缓存maxElementsInMemory:缓存中允许创建的最大对象数eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。timeToIdleSeconds:缓存数据空闲的最大时间,也就是说如果有一个缓存有多久没有被访问就会被销毁,如果该值是 0 就意味着元素可以停顿无穷长的时间。timeToLiveSeconds:缓存数据存活的时间,缓存对象最大的的存活时间,超过这个时间就会被销毁,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。overflowToDisk:内存不足时,是否启用磁盘缓存。memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。每一个小时更新一次缓存(1小时过期) --><cache name="mobileCache"maxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="1800"timeToLiveSeconds="3600"memoryStoreEvictionPolicy="LFU"><!-- RMI缓存分布同步查找 class使用net.sf.ehcache.distribution.RMICacheReplicatorFactory这个工厂支持以下属性:replicatePuts=true | false – 当一个新元素增加到缓存中的时候是否要复制到其他的peers。默认是true。replicateUpdates=true | false – 当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。replicateRemovals= true | false – 当元素移除的时候是否进行复制。默认是true。replicateAsynchronously=true | false – 复制方式是异步的指定为true时,还是同步的,指定为false时。默认是true。replicatePutsViaCopy=true | false – 当一个新增元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。replicateUpdatesViaCopy=true | false – 当一个元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。asynchronousReplicationIntervalMillis=1000--><!-- 监听RMI同步缓存对象配置 注册相应的的缓存监听类,用于处理缓存事件,如put,remove,update,和expire --><cacheEventListenerFactoryclass="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true "/><!-- 用于在初始化缓存,以及自动设置 --><bootstrapCacheLoaderFactory class="net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory"/></cache>
</ehcache>

View Code

Ehcache测试方法

本次测试服务由架构部提供的两个Ehcacahe服务端。一个做put操作,一个做同步操作。

jdk版本: jdk1.7.0_79

tomcat版本: Tomcat/7.0.57

修改echcahe.xml,参照上面的配置方式配置测试服务器ip地址

Put端xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"monitoring="autodetect" dynamicConfig="true"><cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="hostName = 10.27.82.170,port = 50001,socketTimeoutMillis=10000" /><cacheManagerPeerProviderFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=manual, rmiUrls=//10.27.82.168:40001/clusterCache"/><cache name="clusterCache" maxEntriesLocalHeap="999999999" eternal="false"timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false"><cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </cache>
</ehcache> 

同步端xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"monitoring="autodetect" dynamicConfig="true" ><cacheManagerPeerListenerFactoryclass="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="hostName=172.19.136.197, port=40001, socketTimeoutMillis=2000" /><cache name="clusterCache" maxEntriesLocalHeap="10" eternal="false"timeToIdleSeconds="1800" timeToLiveSeconds="1800" overflowToDisk="false"><cacheEventListenerFactory class="com.suning.servlet.MyCacheEventListenerFactory"/>  <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> <bootstrapCacheLoaderFactoryclass="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"properties="bootstrapAsynchronously=false, maximumChunkSizeBytes=5000000"/></cache>
</ehcache> 

注:本次测试是采用手动配置同步信息方式,需要配置服务器端的ip+端口

修改成功后,将工程导出成war包,然后分别部署到两台测试服务器上,部署成功后,打开tomcat后台日志。

浏览器访问路径:

put数据url:

http://ip:8080/EhCacheTest1/

同步访问路径:

http://ip:8080/EhCacheTest2/monitor.htm

测试结果如下:

Put端日志打印:

同步端后台日志打印如下:

开启put端后,往put端中塞数据,然后往同步端进行同步,观察耗时,差值,以及系统资源消耗,带宽流程等,后续补充,基本大概的思路流程是这样

转载于:https://www.cnblogs.com/apnsa/p/5178227.html

Ehcache分布式缓存及测试方法相关推荐

  1. EhCache 分布式缓存/缓存集群

    开发环境: System:Windows JavaEE Server:tomcat5.0.2.8.tomcat6 JavaSDK: jdk6+ IDE:eclipse.MyEclipse 6.6 开发 ...

  2. EhCache 分布式缓存/缓存集群之Terracotta

    介绍 分布式缓存使您可以利用水平扩展的其他好处,而不会损失本地堆上层提供的低延迟. 热点数据在本地缓存,热点数据在更快的层中 由一个应用程序实例缓存的数据可用于所有群集成员. 群集中有完整数据. 可以 ...

  3. Java 开源分布式缓存框架Ehcache

    Ehcache 是一个Java实现的开源分布式缓存框架,EhCache 可以有效地减轻数据库的负载,可以让数据保存在不同服务器的内存中,在需要数据的时候可以快速存取.同时EhCache 扩展非常简单, ...

  4. java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)...

    一.缓存 当系统的并发量上来了,如果我们频繁地去访问数据库,那么会使数据库的压力不断增大,在高峰时甚至可以出现数据库崩溃的现象.所以一般我们会使用缓存来解决这个数据库并发访问问题,用户访问进来,会先从 ...

  5. EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是hibernate中默认的CacheProvider Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通

    EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是hibernate中默认的CacheProvider Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存, ...

  6. Terracotta为Ehcache实现应用支持分布式缓存和应用session共享

    目录 Terracotta产品介绍 Terracotta服务器的一些关键功能包括: TC Server 4.3.x入门 下载并安装 1-下载Terracotta服务器. 2-更新类路径 3-配置Ehc ...

  7. 分布式缓存的选择及问题

    现如今,缓存系统的应用非常广泛,能够用来提高并发数.数据吞吐量,提高快速响应能力.那么当数据量达到一定程度,单机环境可能就显得有些力不从心了,就需要一个分布式缓存系统.分布式缓存能够处理大量的动态数据 ...

  8. 大厂都拿捏的缓存方案,平台级分布式缓存,什么业务才合适?

    所有程序猿都对那缓存并不陌生,好似那风一样的女子只为你独自而舞.只见那回眸一笑百媚生,让你甚是吝惜,惹人怜爱. 但随着项目规模不断增大变强,光是单个缓存就难以招架,优而显得力不从心. 这时伴随着多级缓 ...

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

    2019独角兽企业重金招聘Python工程师标准>>> 在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没 ...

最新文章

  1. 中国AI开发者真实现状:写代码这条路,会走多久?
  2. docker 容器无法使用中文 解决方案
  3. 2020年人工智能领域突破性工作
  4. 交换机端口灯闪烁频率一样_思创易控cetron-新品S2024GE 24口全千兆非网管交换机即将上市!...
  5. 服务器搭建php mysql5_Windows下php5+apache+mysql5 手工搭建笔记
  6. 干货!操作系统基础知识汇总!转给要面试的同学吧
  7. tomcat7 加载el表达式 报错 使用tomcat8得以解决
  8. 【CS231n_2017】2-Image Classification
  9. 大数据分析平台的作用有什么
  10. 浅析StackTrace
  11. 计算机组成原理(第3版)思考题与习题答案----唐朔风 编著
  12. 【Linux应用】SAN(存储区域网络)技术
  13. 无线数字信息传送服务器,无线数字远程监控管理及网站实时推广项目方案.doc...
  14. bat批处理实现win和linux间上传下载
  15. 今有物不知其数三三数之JAVA_今有物不知其数.三三数之剩二.五五数之剩三.七七数之剩二.问物几何? 题目和参考答案——青夏教育精英家教网——...
  16. em表示什么长度单位_CSS的长度单位(em)与em标签
  17. 为什么逍遥子说,双11已成全球的社会大协同?
  18. 苹果电脑各型号支持的macOS版本列表
  19. java获取东八区时间
  20. 我的世界pe服务器坐标怎么显示,我的世界手机版坐标怎么看 PE版没有MOD怎么查看坐标...

热门文章

  1. 关于Arcgis工作空间的记忆点
  2. mysql sql 备份数据_mysql怎么进行数据库备份和还原,以及自动备份
  3. java controller json_Controller 获取 JSON
  4. go json部分解析_Go语言爱好者周刊:第 60 期 — 今天这题你做对了吗?
  5. 星露谷物语json_《星露谷物语》1.5版本更新细节公开 已上线PC
  6. groovy 访问java,Groovy如何能够访问Java类的私有方法?
  7. Beyond Compare 4
  8. oracle查看表中记录数,Oracle 查询某一用户下所有表的记录数
  9. VDO-SLAM论文阅读
  10. 包子和饺子之扫地机器人_扫地机器人:行业发展放缓,市场暗藏潜力