`
helloman0907
  • 浏览: 29883 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

EhCache 分布式缓存对象的同步

 
阅读更多
分类: 架构&性能 2012-09-03 22:27 1908人阅读 评论(8) 收藏 举报

为了提升目前开发产品的性能,项目组内考虑将一些常用的数据放入缓存,并且今后要将系统分布式部署,以达到负载均衡的目的,因此缓存同步问题就不得不需要考虑,该项目中主要用EhCache产品,EhCache的优势和劣势这里就不做介绍,网上可以搜索,单从这次项目出发,说说他在项目中的应用,HibernateSpring都集成了EhCache,如果您的项目中用到这两个框架,那将会大大降低开发复杂度,如果没有使用此类框架,Ehcache还提供在项目中独立使用。

先大概了解一下EhCache的原理吧,见下图:

主要为三层,最上层的是CacheManager,它是操作Ehcache的入口。我们可以通过CacheManager.getInstance()(还有别的方法,可查看API)获得一个单例的CacheManger;每个CacheManager都管理着多个Cache;而每个Cache都以Hash的方式,关联着多个 ElementElement则是我们用于存放要缓存对象的地方。

先从EhCache在项目中独立使用的Demo说起:

开发环境:Eclipse4.0(不受限制)、JDK1.5

引用Jar包:ehcache-core-2.5.2.jar

                   junit-3.8.1.jar

                  slf4j-api-1.6.1.jar

                  slf4j-jdk14-1.6.1.jar

新建一个Java Project,引入以上jar包,创建一个测试类TestPutElement,代码如下:

  1. package ehcache;  
  2.   
  3. import java.net.URL;  
  4. import test.User;  
  5.   
  6. import junit.framework.TestCase;  
  7. import net.sf.ehcache.Cache;  
  8. import net.sf.ehcache.CacheManager;  
  9. import net.sf.ehcache.Element;  
  10.   
  11. public class TestPutElement extends TestCase {  
  12.       
  13.     public void testPut() throws Exception {  
  14.           
  15.         URL url = TestPutCache.class.getClassLoader().getResource(  
  16.                 "conf/ehcache.xml");  
  17.         CacheManager manager = new CacheManager(url);  
  18.           
  19.         Cache cache = manager.getCache("metaCache");  
  20.   
  21.         User user = new User();  
  22.         user.setName("张三");  
  23.         Element element = new Element("key",user);  
  24.         cache.put(element);  
  25.   
  26.         manager.shutdown();  
  27.         System.out.println("已放入缓存!");  
  28.     }  
  29. }  
package ehcache;

import java.net.URL;
import test.User;

import junit.framework.TestCase;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class TestPutElement extends TestCase {
	
	public void testPut() throws Exception {
		
		URL url = TestPutCache.class.getClassLoader().getResource(
				"conf/ehcache.xml");
		CacheManager manager = new CacheManager(url);
		
		Cache cache = manager.getCache("metaCache");

		User user = new User();
		user.setName("张三");
		Element element = new Element("key",user);
		cache.put(element);

		manager.shutdown();
		System.out.println("已放入缓存!");
	}
}

创建一个POJO对象User,一定要经过序列化,并保证序列化UID的存在:

  1. import java.io.Serializable;  
  2.   
  3. public class User implements Serializable {  
  4.   
  5.     private static final long serialVersionUID = -4402392412217726278L;  
  6.     private String name;  
  7.   
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.   
  12.     public void setName(String name) {  
  13.         this.name = name;  
  14.     }  
  15. }  
import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = -4402392412217726278L;
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

在ClassPath目录下加入ehcache.xml文件,这也可以在Ehcachejar包中找到,有两个注意事项,不要删除defaultcache,如果是两台不同的电脑,那么把cacheManagerPeerProviderFactory中的第二个localhost换成另一台机器IP即可,端口号是可以自定义的,不过要注意不要和系统使用的端口冲突,不然会报错;

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:noNamespaceSchemaLocation="ehcache.xsd"  
  5.          updateCheck="true" monitoring="autodetect"  
  6.          dynamicConfig="true">  
  7.   
  8.     <diskStore path="java.io.tmpdir" />  
  9.   
  10.     <!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->  
  11.     <cacheManagerPeerProviderFactory  
  12.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  13.         properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />  
  14.   
  15.     <!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->  
  16.     <cacheManagerPeerListenerFactory  
  17.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  18.         properties="port=40004,socketTimeoutMillis=120000" />  
  19.   
  20.     <!-- 默认缓存 -->  
  21.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  22.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  23.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  24.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  25.         memoryStoreEvictionPolicy="LRU">  
  26.     </defaultCache>  
  27.   
  28.     <!-- 缓存 -->  
  29.     <cache name="metaCache"   
  30.         maxElementsInMemory="1000"   
  31.         eternal="false"  
  32.         timeToIdleSeconds="2000"   
  33.         timeToLiveSeconds="1000"   
  34.         overflowToDisk="false">  
  35.         <cacheEventListenerFactory  
  36.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  37.         <!-- <bootstrapCacheLoaderFactory  
  38.             class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"  
  39.             properties="bootstrapAsynchronously=false" /> -->  
  40.     </cache>  
  41. </ehcache>  
<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true" monitoring="autodetect"
         dynamicConfig="true">

 	<diskStore path="java.io.tmpdir" />

	<!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->
	<cacheManagerPeerProviderFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
		properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />

	<!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->
	<cacheManagerPeerListenerFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
		properties="port=40004,socketTimeoutMillis=120000" />

	<!-- 默认缓存 -->
	<defaultCache maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
		diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
		diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
	</defaultCache>

	<!-- 缓存 -->
	<cache name="metaCache" 
		maxElementsInMemory="1000" 
		eternal="false"
		timeToIdleSeconds="2000" 
		timeToLiveSeconds="1000" 
		overflowToDisk="false">
		<cacheEventListenerFactory
			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
		<!-- <bootstrapCacheLoaderFactory
			class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
			properties="bootstrapAsynchronously=false" /> -->
	</cache>
</ehcache>

到此为止,放入缓存,也就是发送端配置好了,下面开始创建另个Java Project(),User类不变,必须要注意的是序列化UID和上一个Java Project要一致,否则会报ClassNotFound的错误,下面是测试类:

  1. package ehcache;  
  2.   
  3. import java.net.URL;  
  4.   
  5. import test.User;  
  6. import junit.framework.TestCase;  
  7. import net.sf.ehcache.Cache;  
  8. import net.sf.ehcache.CacheManager;  
  9. import net.sf.ehcache.Element;  
  10.   
  11. public class TestGetCache extends TestCase {  
  12.       
  13.     public void testGet() throws Exception {  
  14.         URL url = TestGetCache.class.getClassLoader().getResource(  
  15.                 "conf/ehcache.xml");  
  16.         CacheManager manager = new CacheManager(url);  
  17.           
  18.         Cache cache = manager.getCache("metaCache");  
  19.           
  20.         while (true) {  
  21.             System.out.println("搜索中...");  
  22.             System.out.println("当前资源数:" + cache.getSize());  
  23.             Element element = cache.get("key");  
  24.             if (element != null) {  
  25.                 User user = (User)element.getValue();  
  26.                 System.out.println(user.getName());  
  27.                 break;  
  28.             }  
  29.             Thread.sleep(1000);  
  30.         }  
  31.     }  
  32. }  
package ehcache;

import java.net.URL;

import test.User;
import junit.framework.TestCase;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class TestGetCache extends TestCase {
	
	public void testGet() throws Exception {
		URL url = TestGetCache.class.getClassLoader().getResource(
				"conf/ehcache.xml");
		CacheManager manager = new CacheManager(url);
		
		Cache cache = manager.getCache("metaCache");
		
		while (true) {
			System.out.println("搜索中...");
			System.out.println("当前资源数:" + cache.getSize());
			Element element = cache.get("key");
			if (element != null) {
				User user = (User)element.getValue();
				System.out.println(user.getName());
				break;
			}
			Thread.sleep(1000);
		}
	}
}
ehcache.xml配置文件如下:
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:noNamespaceSchemaLocation="ehcache.xsd"  
  5.          updateCheck="true" monitoring="autodetect"  
  6.          dynamicConfig="true">  
  7.   
  8.     <diskStore path="java.io.tmpdir" />  
  9.   
  10.     <!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->  
  11.     <cacheManagerPeerProviderFactory  
  12.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  13.         properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />  
  14.   
  15.     <!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->  
  16.     <cacheManagerPeerListenerFactory  
  17.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  18.         properties="port=40004,socketTimeoutMillis=120000" />  
  19.   
  20.     <!-- 默认缓存 -->  
  21.     <defaultCache maxElementsInMemory="10000" eternal="false"  
  22.         timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"  
  23.         diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"  
  24.         diskPersistent="false" diskExpiryThreadIntervalSeconds="120"  
  25.         memoryStoreEvictionPolicy="LRU">  
  26.     </defaultCache>  
  27.   
  28.     <!-- 缓存 -->  
  29.     <cache name="metaCache"   
  30.         maxElementsInMemory="1000"   
  31.         eternal="false"  
  32.         timeToIdleSeconds="2000"   
  33.         timeToLiveSeconds="1000"   
  34.         overflowToDisk="false">  
  35.         <cacheEventListenerFactory  
  36.             class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />  
  37. <!--         <bootstrapCacheLoaderFactory  
  38.             class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"  
  39.             properties="bootstrapAsynchronously=true" /> -->  
  40.     </cache>  
  41. </ehcache>  
<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true" monitoring="autodetect"
         dynamicConfig="true">

 	<diskStore path="java.io.tmpdir" />

	<!-- 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->
	<cacheManagerPeerProviderFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
		properties="peerDiscovery=manual,rmiUrls=//localhost:40004/metaCache|//localhost:60000/metaCache" />

	<!-- 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->
	<cacheManagerPeerListenerFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
		properties="port=40004,socketTimeoutMillis=120000" />

	<!-- 默认缓存 -->
	<defaultCache maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
		diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
		diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
	</defaultCache>

	<!-- 缓存 -->
	<cache name="metaCache" 
		maxElementsInMemory="1000" 
		eternal="false"
		timeToIdleSeconds="2000" 
		timeToLiveSeconds="1000" 
		overflowToDisk="false">
		<cacheEventListenerFactory
			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
<!--  		<bootstrapCacheLoaderFactory
			class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
			properties="bootstrapAsynchronously=true" /> -->
	</cache>
</ehcache>
下面就可以测试了,首先运行后一个java Project项目,然后运行前一个java Project,运行结果为:1,张三。

 

分享到:
评论

相关推荐

    ehcache分布式缓存实例

    通过RMI实现的Ehcache分布式缓存,可以有效地提高多节点环境下的数据处理速度,同时降低数据库的压力。然而,RMI也有其局限性,如性能瓶颈、网络延迟等问题。在大型分布式系统中,可能会选择更先进的通信协议,如...

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

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

    ehcache项目缓存技术

    3. **分布式缓存**:Ehcache支持分布式部署,通过 Terracotta Server 集群,可以在多台服务器间共享和同步缓存,提供高可用性和负载均衡。 4. **缓存策略**:除了LRU和LFU,Ehcache还提供了TTL(Time To Live)和...

    Ehcache 整合Spring 使用页面、对象缓存

    此外,它还支持分布式缓存,使其成为大型企业级应用的理想选择,特别是当配合Spring和Hibernate这样的框架时。 Spring 对 Ehcache 的集成非常便捷,允许开发者轻松地在Spring应用中使用缓存功能。整合Ehcache的主要...

    EHCache缓存技术介绍

    分布式缓存适用于读取操作频繁且对并发性能要求高的场景,但在读写操作均衡或数据库被多应用共享时,使用分布式缓存可能会带来数据同步的复杂性和性能下降的风险。 在选择缓存策略时,应根据业务需求和系统性能瓶颈...

    Ehcache缓存

    Ehcache是一种广泛使用的开源Java分布式缓存系统,它为高性能应用程序提供了内存存储和缓存解决方案。在Java世界中,尤其是在持久化框架如Hibernate的使用中,Ehcache扮演了至关重要的角色。由于数据库查询通常会...

    ehcache 缓存

    **四、Ehcache分布式缓存** 1. **Terracotta服务器**: Ehcache通过集成Terracotta服务器,可以实现跨JVM的分布式缓存,提高多节点间的缓存共享和一致性。 2. **复制策略**: 分布式缓存中,当在一个节点上添加、...

    Java流行ehcache缓存

    - **Ehcache层次结构**:Ehcache通常包含三级缓存:内存、硬盘和分布式缓存。内存缓存响应速度最快,但容量有限;硬盘缓存用于扩展内存,当内存满时使用;分布式缓存则允许在多台机器间共享数据,适用于大型分布式...

    大型分布式系统中的缓存架构

    Ehcache是一款流行的Java缓存解决方案,提供从进程内缓存到分布式缓存的扩展能力。其特性包括自动过期策略和多种缓存策略,支持TB级缓存。 **Guava Cache** Guava Cache是Google的开源Java库Guava的一部分,提供了...

    Spring+EhCache缓存实例

    在多节点环境下,可以使用EhCache的分布式缓存功能,通过RMI、JGroups或Terracotta等方式实现数据同步。配置分布式缓存需要在`ehcache.xml`中指定相关的网络配置。 **7. 性能优化与监控** EhCache提供了丰富的统计...

    缓存框架-Ehcache学习笔记

    Ehcache 提供了本地内存缓存、磁盘存储以及分布式缓存的能力,使得应用程序能够快速访问频繁使用的数据,从而提高整体性能和响应速度。 ### 1. Ehcache 基本概念 - **Cache**: 缓存是存储数据的临时区域,用于快速...

    ehcache 缓存技术

    2. **缓存层次:**EHCache有三个主要的缓存层次,分别是`MemoryStore`(内存缓存)、`DiskStore`(磁盘缓存)和`Terracotta Distributed Cache`(分布式缓存)。 3. **元素(Element):**缓存中的最小单位,包含一...

    Spring Boot 2.x基础教程:使用EhCache缓存集群.docx

    首先,确保缓存对象是可序列化的。在上述例子中,`User`实体需要实现`Serializable`接口,以便在进程间传递时能够正确地进行序列化和反序列化。如果不这样做,当数据在集群中传输时,可能会引发序列化相关的异常。 ...

    ehcache2.6.5.rar

    在版本2.6.5中,Ehcache提供了一套完整的缓存解决方案,包括本地缓存、分布式缓存和 Terracotta 集群支持。 Ehcache 2.6.5的关键特性包括: 1. **内存管理**:Ehcache 使用LRU(Least Recently Used)策略来管理...

    Hibernate + EhCache 实现数据缓存的处理

    - 对于多服务器部署的应用,可以使用EhCache的分布式缓存功能,确保数据的一致性,提高系统的可扩展性。 通过以上步骤,我们可以有效地整合Hibernate和EhCache,实现高效的数据缓存处理,提升应用程序的性能和用户...

    基于Java的ehcache(Java缓存框架 EhCache).zip

    EhCache是一个高性能、易用且广泛应用于Java环境中的分布式缓存框架,它极大地提高了应用程序的性能和响应速度。在Java开发中,特别是在处理大数据量或频繁读取的数据时,缓存技术是不可或缺的一部分。EhCache作为...

    高并发缓存器(基于ehcache)

    Ehcache支持本地缓存、分布式缓存和 terracotta 集群模式,广泛应用于Java Web应用和企业级系统中。其主要特性包括: 1. **内存和磁盘存储**:Ehcache允许将数据存储在内存中,当内存不足时,可以自动将部分数据...

    ehCache 使用例子

    6. **分布式缓存**:当需要在多个节点间共享缓存时,ehCache提供了分布式缓存支持。这涉及到两种主要的通信机制: - **RMI(Remote Method Invocation)**:通过Java的远程方法调用来实现节点间的通信。 - **...

    mybatis-ehcache

    7. **分布式缓存**:如果应用是分布式部署,Ehcache可以通过Terracotta服务器实现跨节点的缓存同步,提供分布式缓存功能。 8. **监控与优化**:Ehcache提供了一套监控工具,可以帮助开发者了解缓存的使用情况,进行...

    ehcache的Jar包

    3. **分布式缓存**:EhCache提供了分布式缓存能力,允许在多台服务器之间共享缓存,这对于构建可扩展的、高可用性的系统至关重要。 4. **缓存预热**:可以通过预加载机制,在应用程序启动时将常用数据加载到缓存中...

Global site tag (gtag.js) - Google Analytics