jcs开源缓存框架介绍

来源:互联网 发布:独战乾坤进阶数据大全 编辑:程序博客网 时间:2024/06/05 18:53

这篇文章写的通俗易懂,转自http://blog.csdn.net/zyujie/article/details/7369463,以作学习。

JCS是Jakarta的项目Turbine的子项目。它是一个复合式的缓冲工具。可以将对象缓冲到内存、硬盘。具有缓冲对象时间过期设定。还可以通过JCS构建具有缓冲的分布式构架,以实现高性能的应用。对于一些需要频繁访问而每访问一次都非常消耗资源的对象,可以临时存放在缓冲区中,这样可以提高服务的性能。而JCS正是一个很好的缓冲工具。缓冲工具对于读操作远远多于写操作的应用性能提高非常显著。

JCS除了简单的将对象缓冲在内存中以外,还具有几个特性,以适应企业级缓冲系统的需要。这些特性包括时间过期、索引式硬盘缓冲、并行式的分布缓冲等。

内存缓冲

JCS现在支持两种内存缓冲算法LRU和MRU。通常都是使用LRU算法。

org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache

使用内存缓冲区需要定义缓冲区大小,当超过缓冲区限制时,会将缓冲内容抛弃掉。如果有配硬盘缓冲,则将挤出来的缓冲内容写入硬盘缓冲区。

时间过期

JCS对于缓冲的对象,可以设定缓冲过期时间,一个对象在缓冲区中停留的时间超过这个时间,就会被认为是“不新鲜”而被放弃。

索引式硬盘缓冲

  一方面,为了避免缓冲区过大,撑爆虚拟机的内存,另一方面又希望能够缓冲更多的对象,JCS可以将超出缓冲区大小的对象缓存到硬盘上。配置上也比较方便,只需要指定缓冲临时文件的存放目录位置。硬盘缓冲将缓冲对象的内容写到文件上,但是将访问索引保存在内存中,因此也能够达到尽可能高的访问效率。

并行式的分布缓冲(Lateral)

  通常,将对象缓冲在内存中,一方面提高了应用的性能,而另一方面却使得应用不可以分布式发布。因为假设一个应用配置在两台服务器上并行运行,而两台服务器单独缓冲,则很容易导致两个缓冲区内容出现版本上的不一致而出错。一个机器上修改了数据,这个动作会影响到本地内存缓冲区和数据库服务器,但是却不会通知到另一台服务器,导致另一台上缓冲的数据实际上已经无效了。

  并行式的分布缓冲就是解决这个问题。可以通过配置,将几台服务器配成一个缓冲组,组内每台服务器上有数据更新,会横向将更新的内容通过TCP/IP协议传输到其他服务器的缓冲层,这样就可以保证不会出现上述情况。这个的缺点是如果组内的并行的服务器数量增大后,组内的数据传输量将会迅速上升。这种方案适合并行服务器的数量比较少的情况。

Client/Server式的缓冲(Remote)

  客户/服务端式的缓冲集群。这种方式支持一个主服务器和最高达到256个客户端。客户端的缓冲层会尝试连接主服务器,如果连接成功,就会在主服务器上注册。每个客户端有数据更新,就会通知到主服务器,主服务器会将更新通知到除消息来源的客户端以外的所有的客户端。

  每个客户端可以配置超过一个服务器,第一个服务器是主服务器,如果与第一个服务器连接失败,客户端会尝试与备用的服务器连接,如果连接成功,就会通过备用服务器与其他客户端对话,同时会定期继续尝试与主服务器取得连接。如果备用服务器也连接失败,就会按照配置顺序尝试与下一个备用服务器连接。

  这种方式下,更新通知是一种轻量级的,一个机器上的数据更新,不会把整个数据传输出去,而只是通知一个ID,当远程的其他机器收到更新通知后,就会把对应ID的缓冲对象从本地的内存缓冲区中移除,以保证不会在缓冲区内出现错误数据。

  这种构造需要分别配置客户端和服务器,配置比较麻烦。

 

配置方法

  JCS的好处之一,就是应用在开发的时候,可以不用去构思底层的缓冲配置构架。同一个应用,只需要修改配置,就可以改变缓冲构架,不需要修改应用的源代码。配置方法也比较简单,就是修改配置文件cache.ccf。这个文件放置在WEB-INF/classes目录下。配置格式类似log4j的配置文件格式。下面介绍一下使用各种缓冲结构的配置方法。

内存缓冲

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #WEB-INF/classes/cache.ccf(以下内容不要换行)  
  2.   
  3. jcs.default=  
  4.   
  5. jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes  
  6.   
  7. jcs.default.cacheattributes.MaxObjects=1000  
  8.   
  9. jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache  
  上面配置了默认缓冲属性。一个应用中,由于对象类型的不同,可能会使用多个缓冲区,每个缓冲区都会有一个名字,如果在配置文件中没有指明特定的缓冲区的属性,所有的缓冲区都会根据默认属性来构建。上面的内容,指明缓冲区的大小为存放1000个对象,内存缓冲器使用LRUMemoryCache对象。可选的还有MRUMemoryCache,应该可以自定义新的内存缓冲区。1000个缓冲对象这个容量,是指每个缓冲区都缓冲1000个,而不是指所有缓冲区总容量。以上配置,就可以让应用运行起来。

时间过期

  如果需要引入时间过期机制,则需要加上

  jcs.default.cacheattributes.cacheattributes.UseMemoryShrinker=true

  jcs.default.cacheattributes.cacheattributes.MaxMemoryIdleTimeSeconds=3600

  jcs.default.cacheattributes.cacheattributes.ShrinkerIntervalSeconds=60

  这里指明对象超过3600秒则过期,每隔60秒检查一次。

索引式硬盘缓冲

  索引式硬盘缓冲是辅助缓冲的一种,使用时需要做以下事情

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #定义一个硬盘缓冲区产生器(Factory),取名为DC  
  2.   
  3. jcs.auxiliary.DC=org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory  
  4.   
  5. jcs.auxiliary.DC.attributes=org.apache.stratum.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes  
  6.   
  7. jcs.auxiliary.DC.attributes.DiskPath=g:/dev/jakarta-turbine-stratum/raf  
  8.   
  9. #这里其实就是指明了缓冲文件存放到那里去。  
  10.   
  11. #然后,做以下修改  
  12.   
  13. jcs.default=DC  
  14.   
  15. #这样,所有未特别指定属性的缓冲区都会自己使用一个硬盘缓冲区,缓冲文件会以缓冲区的名字来命名。存放在指定的目录下。  
  16.   
  17. #横向式的并行缓冲  
  18.   
  19. #并行式的配置如下  
  20.   
  21. jcs.auxiliary.LTCP=org.apache.jcs.auxiliary.lateral.LateralCacheFactory  
  22.   
  23. jcs.auxiliary.LTCP.attributes=org.apache.jcs.auxiliary.lateral.LateralCacheAttributes  
  24.   
  25. jcs.auxiliary.LTCP.attributes.TransmissionTypeName=TCP  
  26.   
  27. jcs.auxiliary.LTCP.attributes.TcpServers=192.168.10.129:1121,192.168.10.222:1121  
  28.   
  29. jcs.auxiliary.LTCP.attributes.TcpListenerPort=1121  
  30.   
  31. jcs.auxiliary.LTCP.attributes.PutOnlyMode=false   
  这里的配置是在41,129,221三台机器上实现并行缓冲的。

  大家都在1121端口上监听,同时与另外两台机器连接。如果连接失败,就会等待一个时间后再连接一次,直到连接成功为止。三台机器中任意一台的缓冲区发生更新,比如put和remove动作,就会把更新传递给另外两台。

单独指明某个缓冲区的属性

  如果,针对某个缓冲区,比如叫做TestCache1,需要单独配置属性,可以如下配置。

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. jcs.region.testCache1=DC,LTCP  
  2.   
  3. jcs.region.testCache1.cacheattributes=org.apache.stratum.jcs.engine.CompositeCacheAttributes  
  4.   
  5. jcs.region.testCache1.cacheattributes.MaxObjects=1000  
  6.   
  7. jcs.region.testCache1.cacheattributes.MemoryCacheName=org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache  
  8.   
  9. jcs.region.testCache1.cacheattributes.UseMemoryShrinker=true  
  10.   
  11. jcs.region.testCache1.cacheattributes.MaxMemoryIdleTimeSeconds=3600  
  12.   
  13. jcs.region.testCache1.cacheattributes.ShrinkerIntervalSeconds=60  
  14.   
  15. system.GroupIdCache  
  16.   
  17. #这个概念我也不是很清楚。不过JCS文档中指出配置以下内容会比较好。  
  18.   
  19. jcs.system.groupIdCache=DC  
  20.   
  21. jcs.system.groupIdCache.cacheattributes=org.apache.stratum.jcs.engine.CompositeCacheAttributes  
  22.   
  23. jcs.system.groupIdCache.cacheattributes.MaxObjects=10000  
  24.   
  25. jcs.system.groupIdCache.cacheattributes.MemoryCacheName=org.apache.stratum.jcs.engine.memory.lru.LRUMemoryCache  
  26.   
  27. #这可能是JCS自己的组管理体系上的缓冲区。   

Client/Server式的缓冲(Remote)

  这种构架需要单独配置客户端和服务端,如果要研究,可以查看 http://jakarta.apache.org/turbine/jcs/RemoteAuxCache.html

 

 

这里给出一个之前系统配置的例子:cache.cff配置

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. # DEFAULT CACHE REGION  
  2.   
  3. # sets the default aux value for any non configured caches  
  4. jcs.default=DC  
  5. jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes  
  6. jcs.default.cacheattributes.MaxObjects=1  
  7. jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache  
  8. jcs.default.elementattributes.IsEternal=true  
  9. jcs.default.elementattributes.MaxLifeSeconds=360000  
  10. jcs.default.elementattributes.IdleTime=1800  
  11. jcs.default.elementattributes.IsSpool=true  
  12. jcs.default.elementattributes.IsRemote=true  
  13. jcs.default.elementattributes.IsLateral=true  
  14.   
  15. # CACHE REGIONS AVAILABLE  
  16.   
  17. # AUXILIARY CACHES AVAILABLE  
  18.   
  19. # Primary Disk Cache -- faster than the rest because of memory key storage  
  20. jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory  
  21. jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes  
  22. jcs.auxiliary.DC.attributes.DiskPath=./kpicache  
  23. jcs.auxiliary.DC.attributes.MaxPurgatorySize=100000000  
  24. jcs.auxiliary.DC.attributes.MaxKeySize=10000000  
  25. jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000  
  26. jcs.auxiliary.DC.attributes.MaxRecycleBinSize=7500  

一些方法的操作:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.zyujie.util;  
  2.   
  3. import org.apache.jcs.JCS;  
  4.   
  5. public class JCSManagerDTO {  
  6.     private static JCSManagerDTO instance;  
  7.     private static int checkedOut = 0;  
  8.     public static JCS ObjCache;  
  9.   
  10.     private JCSManagerDTO() {  
  11.         try {  
  12.             ObjCache = JCS.getInstance("ObjCache");  
  13.         } catch (Exception e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.   
  18.     public static JCSManagerDTO getInstance() {  
  19.         synchronized (JCSManagerDTO.class) {  
  20.             if (instance == null) {  
  21.                 instance = new JCSManagerDTO();  
  22.             }  
  23.   
  24.         }  
  25.         synchronized (instance) {  
  26.             instance.checkedOut++;  
  27.         }  
  28.         return instance;  
  29.     }  
  30.   
  31.     public Object getObj(Object key) {  
  32.         Object obj = null;  
  33.         obj = (Object) ObjCache.get(key);  
  34.         return obj;  
  35.     }  
  36.   
  37.     public void storeObject(Object key, Object obj) {  
  38.         try {  
  39.             if (!key.equals("")) {  
  40.                 // ObjCache.remove(key);  
  41.             }  
  42.             ObjCache.put(key, obj);  
  43.   
  44.         } catch (Exception e) {  
  45.         }  
  46.     }  
  47.   
  48.     public void clearObject(Object key) {  
  49.         try {  
  50.             ObjCache.remove(key);  
  51.         } catch (Exception e) {  
  52.         }  
  53.     }  
  54.   
  55.     public void clear() {  
  56.         try {  
  57.             ObjCache.clear();  
  58.         } catch (Exception e) {  
  59.         }  
  60.     }  
  61.   
  62.     public void clearMatchObject(String key) {  
  63.   
  64.         // CacheAccess access1=CacheAccess.getAccess("DC");  
  65.         // java.util.Map map=access1.get.getMatchingCacheElements(key);  
  66.     }  
  67.   
  68.     public static void main(String[] args) {  
  69.         JCSManagerDTO dto = JCSManagerDTO.getInstance();  
  70.         dto.storeObject("test1""111");  
  71.         dto.storeObject("test2""222");  
  72.         dto.storeObject("test3""333");  
  73.         dto.storeObject("test4""444");  
  74.   
  75.         System.out.println("test1 is  " + dto.getObj("test1"));  
  76.         System.out.println("test2 is  " + dto.getObj("test2"));  
  77.         System.out.println("test3 is  " + dto.getObj("test3"));  
  78.         System.out.println("test4 is  " + dto.getObj("test4"));  
  79.     }  
  80.   
  81. }  
 

依赖jar包

jcs-1.3.jar

commons-lang-2.3.jar

commons-collections-2.1.1.jar

concurrent-1.3.4.jar

0 0