`
crazyox
  • 浏览: 182834 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

各种cache技术基本特性

阅读更多

摘自: http://hi.baidu.com/xproduct/blog/item/28297009f7016ccd3bc76

首先,介绍一下我(作者)自己使用Cache的背景,以便读者更清楚地了解我下面要讲述哪些内容。
我主要是一个Cache实现者,而不是使用者。为了给一些ORM(比如JPA实现)提供Cache支持,我需要包装其它的Open Source Cache,并考察它们的特性。
我对这些Open Source Cache的一些工作原理,了解得比较多。具体配置和使用细节,了解的比较少。
本文主要讲述的也是Cache的特性和工作原理,而不是一个安装、配置、使用的入门手册。
本文简述Cache的一般特性,详述Cache的高级特性,比如,分布式Cache,关联对象的Cache,POJO Cache等。
阅读本文需要具备基本的Cluster知识,ORM知识,数据库事务知识。本文不解释这些基本概念。

-------------------------------------------------------
Cache Features
首先,我们来浏览一下常见的Cache。
这个链接给出了常用的Java Open Source Cache。
http://java-source.net/open-source/cache-solutions

memcached,JBoss Cache,SwarmCache,OSCache,JCS,EHCache等开源项目的出镜率和关注率比较高。
memcached和其他几个不同,后面会详述。
JBoss Cache的特点是,功能大而全,可算是Cache集大成者,几乎什么都支持。
其余的几个都很轻量。SwarmCache,OSCache,JCS支持Cluster。EHCache不支持Cluster。

下面列出Cache的基本特性。
1. 时间记录
数据进入Cache的时间。

2. timeout过期时间
Cache里面的数据多久过期

3. Eviction Policy 清除策略
Cache满了之后,根据什么策略,应该清除哪些数据。
比如,最不经常被访问的数据,最久没有访问到的数据。

4. 命中率
Cache的数据被选中的比率

5. 分级Cache
有些Cache有分级的概念。比如,几乎所有的Cache都支持Region分区的概念。可以指定某一类的数据存放在特定的Region里面。JBoss Cache可以支持更多的级别。

6. 分布式Cache
分布在不同计算机上的Cache

7. 锁,事务,数据同步
一些Cache提供了完善的锁,事务支持。

以上特性,大部分Cache都有相应的API支持。这些API很直观,也很简单,本文不打算展开讲述。
本文下面主要介绍,memcached和JBoss Cache这两个具有代表意义的Cache的高级特性,包括分布式Cache的支持。

-------------------------------------------------------

memcached
http://www.danga.com/memcached/

memcached是一个Client Server结构的远程Cache实现。
Server是用C写的,提供了多种语言的客户端API,包括Java, C#, Ruby, Python, PHP, Perl, C等多种语言。
memcached主要使用在Shared Nothing Architecture中。应用程序通过客户端API,从memcached server存取数据。
典型的应用,比如,用memcached作为数据库缓存。
也常有这样的用法,用memcached存放HTTP Session的数据。具体做法是包装Session Interface,截获setAttribute(), getAttribute()方法。

MemcachedSessionWrapper {
Object getAttribute( key ){
return memcachedClient.get (session.getId() + key);
}
void setAttribute( key, value ){
memcachedClient.setObject(session.getId() + key, value);
}
}

不同计算机上的应用程序通过一个IP地址来访问memcahced Server。
同一个key对应的数据,只存在于一台memcached server的一份内存中。
memcached server也可以部署在多台计算机上。Memcached通过key的hashcode来判断从哪台memcached server上存取数据数据。我们可以看到,同一个key对应的数据,还是只存在于一台memcached server的一份内存中。
所以,memcached不存在数据同步的问题。这个特性很关键,我们后面讲到Cluster Cache的时候,就会涉及到数据同步的问题。
memcached由于是远程Cache,要求放到Cache的Key和Value都是Serializable。
远程Cache,最令人担心的网络通信开销。据有经验的人说,memcached网络通信开销很小。
memcached的API设计也是远程通信友好的,提供了getMulti()等高粒度的调用方法,能够批量获取数据,从而减少网络通信次数。

-------------------------------------------------------

JBoss Cache
http://www.jboss.org/products/jbosscache

有一个商业Cluster Cache,叫做tangosol。
JBoss Cache是我唯一知道的能够和tangosol媲美的开源Cache。

Cluster Cache的数据同步,需要网络通信,这就要求放到Cache的数据是Serializable。
JBoss Cache提出了POJO Cache的概念,意思是数据不是Serializable,一样能够在Cluster中同步。
JBoss POJO Cache通过AOP机制,支持对象同步,支持对象属性的同步,支持关联对象的Cache,支持继承,集合,Query,并支持不同级别的事务,俨然一个小型内存数据库级别的数据存储系统。
下面进行解释。
最令人迷惑不解的是这个POJO的Cluster同步如何实现。
JBoss POJO Cache采用AOP来照管了POJO的通信和传播工作。天下没有免费的午餐,POJO不支持序列化,框架本身就要做这个工作——Marshal and Unmarshal,比如通过把Java对象翻译成XML,传播出去,对方收到XML,再翻译成Java对象。
上面说了,JBoss POJO Cache很像一个小型存储容器,JBoss POJO Cache的对象管理也非常类似Hibernate,JDO,JPA等ORM工具,同样有Detach和Attach的概念。
Attach就是put,把对象放入到Cache中。Detach就是remove,把对象从Cache中删除。为啥要多起个名?
原因是,put的时候,放进去的是个干干净净的POJO,出来的时候,就是Enhanced Object,里面夹杂了很多Interceptor代码,监听对象的方法。
你操作这个对象的时候,JBoss AOP框架就获得了相应的通知,能够做出相应的反应,比如数据同步等。
JBoss POJO Cache支持对集合类型的AOP。同样需要把集合Attach(Put)进Cache,然后get出来,然后对集合进行操作,就可以被JBoss AOP截获了。

JBoss POJO Cache的基础是JBoss Tree Cache。这个Tree Cache类似于一个XML DOM树形数据结构。
JBoss Cache采用Full Qualified Name作为Cache Key,类似于XPath。比如,a/b/c/d。
当你删除a/b的时候,a/b/c,a/b/c/d等所有属于a/b的Key和对应数据,都被删除。
JBoss Cache的findObjects方法能够找出一串对象。比如,findObjects根据a/b/c/d能够找出a,b,c,d等4个对象,放在一个Map中返回。
具体用法要参见API详细说明,因为JBoss POJO Cache提供了很多行为模式。
这 种分级的Cache功能很有用,实现起来也不难。只是,我觉得,还是不够强大。既然支持了类似于XPath的Key,不如索性支持XPath的条件查询。 比如,a[name=”n”]/b/c。当然,实现这种功能的代价非常大,需要遍历整个Cache Tree,正如XPath需要遍历整个DOM节点一样。

最后,JBoss Cache和tangosol一样,都支持了一个我认为如同鸡肋一般的功能,锁机制和事务支持。这个事务支持的意思是,Cache本身实现了类似于数据库的4种事务隔离级别。
在我看来,这种支持无疑是为了赚取眼球。Cache不当做Cache来用,搞些歪门邪道,大而不当。想当作数据库来用,那还不如把主要功夫花在上述提到的那种精确批量查询功能上。

-------------------------------------------------------
Cluster同步

Cluster 之间的Cache同步有多种实现方法。比如,JMS,RMI,Client Server Socket等方法,用的最多的,支持最广的方法是JGroups开源项目实现的Multicast。配置Cluster Cache,通常就相当于配置JGroups,需要阅读JGroups配置文档。
Cache的操作通常有4个,get,put,remove,clear。
对 于Cluster Cache来说,读操作(get)肯定是Local方法,只需要从本台计算机内存中获取数据。Remove/clear两个写操作,肯定是Remote方 法,需要和Cluster其他计算机进行同步。Put这个写方法,可以是Local,也可以是Remote的。
Remote Put方法的场景是这样,一台计算机把数据放到Cache里面,这个数据就会被传播到Cluster其他计算机上。这个做法的好处是Cluster各台计算机的Cache数据可以及时得到补充,坏处是传播的数据量比较大,这个代价比较大
Local Put方法的场景是这样,一台计算机把数据放到Cache里面,这个数据不会被传播到Cluster其他计算机上。这个做法的好处是不需要传播数据,坏处 是Cluster各台计算机的Cache数据不能及时得到补充,这个不是很明显的问题,从Cache中得不到数据,从数据库获取数据是很正常的现象。
Local Put比起Remote Put的优势很明显,所以,通常的Cluster Cache都采用Local Put的策略。各Cache一般都提供了Local Put的配置选项,如果你没有看到这个支持,那么请换一个Cache。Very Happy

-------------------------------------------------------

Center vs Cluster
Memcached可以看作是Center Cache。
Center Cache和Cluster Cache的特性比较如下:
Center Cache没有同步问题,所以,remove/clear的时候,比较有优势,不需要把通知发送到好几个计算机上。
但是,Center Cache的所有操作,get/put/remove/clear都是Remote操作。而Cluster Cache的get/put都是Local操作,所以,Cluster Cache在get/put操作上具有优势。

Local get/put在关联对象的组装和分拆方面,优势比较明显。
关联对象的分拆是这个意思。
比如,有一个Topic对象,下面有几个Post对象,每个Post对象都有一个User对象。
Topic对象存放到Cache中的时候,下面的关联对象都要拆开来,分成各自的Entity Region来存放。
Topic Region -> Topic ID -> Topic Object
Post Region -> Post ID -> Post Object
User Region -> User ID -> User Object
这个时候,put的动作可能发生多次。Remote Put的开销就比较大。
Get的过程类似,也需要get多次,才能拼装成一个完整的Topic对象。


-------------------------------------------------------

过期数据
Cache可以用在任何地方,比如,页面缓存。但Cache的最常用场景是用在ORM中,比如,Hibernate,JDO,JPA中。
ORM Cache的使用方法有个原则——不要把没有Commit的修改数据放入到缓存中。这是为了防止Read Dirty。
数据库事务分为两种,一种是读事务,不修改数据,一种是写事务,修改数据。
写事务的操作流程如下:
db.commt();
cache.remove(key); // 这一步操作,清除了Cache数据,也记录了一个时间removeTime。

读事务的操作流程如下:
readTime = current time;
data = cache.get(key);
if(data is null){
data = db.load(key);
cache.put(key, data, readTime); // 这里要readTime传进去
}

这里需要注意的是put的时候,需要readTime这个参数。
这个readTime要和上一次的removeTime进行比较。
如果readTime > removeTime,这个put才能成功,数据才能够进入缓存。
这是为了保证不把过期数据放入到Cache中,及时反映数据库的变化。

另外,需要注意的是,cache.remove(key); 这个事件需要传播到Cluster其他计算机,通知它们清理缓存。
为什么需要这个通知?
一定要注意,这不是为了避免并发修改冲突。并发修改冲突的避免需要引入乐观锁版本控制机制。
有可能存在这样的误解,认为有了乐观锁版本控制机制,就不需要Cache.remove通知了。这是不对的。
Cache.remove通知的主要目的是,保证缓存能够及时清理过期数据,反映数据的变化,保证大部分时间内,应用程序显示给用户的不是过期数据。
另外,db.commt(); cache.remove(key); 这两步调用之间,有很小的可能发生另外的事务。这段极小的时间内,可能无法保证Read Committed,可能出现很短期的过期数据。
为什么说很短期,因为紧接着的Cache.remove就会清理过期数据。
如果偏执到这种程度,这么短期的几乎不可能发生的小概率事件,都不能容忍,那么可以,db.commt()之前,给Cache加一个悲观锁,不让别的事务,把数据Put进入Cache,就可以防止这个小概率、微影响的事件。
JBoss Cache和Tangosol就提供了这类鸡肋一般的悲观锁机制。典型的开发资源配置不当,有用的需要的不做,没用的功能使劲做。
ORM Query Cache
ORM Cache一般分为两种。一种是ID Cache(ORM文档中称为二级Cache),用来存放Entity ID对应的Entity对象;一种是Query Cache,用来存放一条查询语句对应的查询结果集。
ID Cache非常直观,如同上述讲述的,一般是一个Entity Class对应一个Region,Entity存放到对应的Region里面。
Query Cache比较复杂,而且潜在作用很大,值得仔细讲解。
现有的ORM对Query Cache的支持并不是很理想。
比如,Hibernate把整个结果集直接放在Query Cache中。这样,有任何风吹草动,发生了任何数据库的写操作,Query Cache都需要清空。
有 一种比较好的做法,把ID List存放在Query Cache中,每次获取的时候,先获取ID List,然后根据ID List获取Entity List。Query Cache根据Query涉及到的Table Name来进行清理,一旦发生对这些Table Name的修改操作,就可以根据不同情况,清理Query Cache。
比如,select t2.* from t1, t2 where t1.id = t2.foreign_id and t1.name = ‘a’
那么insert into t1, delete from t1, insert into t2, delete from t2都会清除这条Query Cache。
同样的 update t1 set 这样的语句也会清除这条Query Cache。
Hibernate为什么不这么做,因为Query Cache的情况比较复杂。也许选择的结果集并不是只有一个Entity类型,也许只是几个字段。
这个地方,如果细分,还是有很多功夫可以做的。而且也很值得花功夫做,因为Query Cache对于性能的提高,有很大作用。

-------------------------------------------------------

ORM Query Cache
Cache可以用在任何地方,比如,页面缓存。但Cache的最常用场景是用在ORM中,比如,Hibernate,JDO,JPA中。
ORM Cache一般分为两种。一种是ID Cache(ORM文档中称为二级Cache),用来存放Entity ID对应的Entity对象;一种是Query Cache,用来存放一条查询语句对应的查询结果集。
ID Cache非常直观,如同上述讲述的,一般是一个Entity Class对应一个Region,Entity存放到对应的Region里面。
Query Cache比较复杂,而且潜在作用很大,值得仔细讲解。
现有的ORM对Query Cache的支持并不是很理想。
比如,Hibernate把整个结果集直接放在Query Cache中。这样,有任何风吹草动,发生了任何数据库的写操作,Query Cache都需要清空。
有 一种比较好的做法,把ID List存放在Query Cache中,每次获取的时候,先获取ID List,然后根据ID List获取Entity List。Query Cache根据Query涉及到的Table Name来进行清理,一旦发生对这些Table Name的修改操作,就可以根据不同情况,清理Query Cache。
比如,select t2.* from t1, t2 where t1.id = t2.foreign_id and t1.name = ‘a’
那么insert into t1, delete from t1, insert into t2, delete from t2都会清除这条Query Cache。
同样的 update t1 set 这样的语句也会清除这条Query Cache。
Hibernate为什么不这么做,因为Query Cache的情况比较复杂。也许选择的结果集并不是只有一个Entity类型,也许只是几个字段。
这个地方,如果细分,还是有很多功夫可以做的。而且也很值得花功夫做,因为Query Cache对于性能的提高,有很大作用。

-----------------------------------------------------------

Query Key
Query Cache的性能需要考虑几个方面。比如,Query Key。Query Key一般由2个部分组成:Query String部分,SQL, HQL, EQL, or OQL;参数部分。
寻找Query Key的对应数据的时候,Query Key的比较有两个步骤,先hash,然后equals。所以,Query Key的hashcode和equals两个方法很重要。尤其是equals方法。
equals 方法需要比较很长的Query String。如果没有命中,Query String不相等,那么开销很小,因为通常来说,不相等的String长度都不同,或者前面的字符串都不相同。开销最大的是命中的时候,Query String相等,那么需要把String从头比到尾。
我们可以采取一些方法来提高String的比较速度。比如,大部分的情况属于静态查 询,我们可以采用Singleton String。相同reference的String之间的比较速度很快。对于ORM来说,最好直接使用最外面的HQL, EQL, OQL作为Query Key,而不是采用生成的SQL结果。因为生成的SQL结果每次都是一个新String,具有不同的reference,Cache命中的时候,需要比较 整个字符串。
动态拼装的Query String的性能提高比较难办。因为最终的结果,都是一个新String。我采用的一种方式是,动态拼装的结果是一个String[]。两个 String[]如果相等,那么里面的元素String的reference都是相等的,这是由JVM对一个Class内部的String常量进行优化的 结果。
比如,
String[] a = {
“select * from t where”
“a = 1”
“and b = 2”
};

String[] b = {
“select * from t where”
“a = 1”
“and b = 2”
};

那么a和b的比较只需要3次String reference的比较

分享到:
评论
3 楼 imjl 2007-10-09  
恩。。。我想看高级特性。
2 楼 Arden 2007-10-09  
ehcache是基于RMI的cluster的!
1 楼 ahuaxuan 2007-09-21  
引用
EHCache不支持Cluster

这个是不正确得,ehcache1.2之后就支持cluster了,


还有一点就是关于query cache描述也不是很正确,
1 query cache其实应该是一个很大得范畴,不应该只用在orm那一层,也不局限把sql语句作为key,orm里这样使用定义query cache只是情况之一。
2 查询结果集也可以被缓存。只有当经常使用同样的参数进行查询时,这才会有些用处。在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。需要将打印sql语句与最近的cache内容相比较,将不同之处修改到cache中,所以查询缓存通常会和二级缓存一起使用。而query cache虽然能提高性能,但是按照hibernate in action的话来说适用场景较少。

而如果我们放大query cache的概念,那么对于实时性要求不是很高的数据,它就能极大的提高性能,比如说主页,如果主页更新的时间为5分钟,那么query cache就能发挥其所长了。

相关推荐

    基于ARM处理器Cache特征的计时分析研究 (2015年)

    通过研究Cache基本结构、Cache计时攻击的基本原理和攻击模型,发现由于ARM处理器与x86处理器在Cache结构及特征等方面存在差异,导致原有基于x86平台的Cache计时攻击方法在ARM平台上具有不适用性。针对x86处理器与ARM...

    计算机系统结构.ppt

    第7章介绍存储层次,重点讲述cache的基本知识及提高cache性能的各种方法。第8章介绍总线、通道处理机和RAID。第9章介绍互连网络的特性参数、静/动态互连网络以及消息传递机制等。第10章介绍SMP、DSM、MPP等并行...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    关于java程序员发展需要学习的路线整理集合 技术 应用技术 计算机基础知识 cpu mem disk ... 线程,进程 第三方库 ... 语言特性 ... 技术攻关案例 ... 基本理论 ... 串行化技术 ... cache对其 ... cache ... 各种工具

    Visual C++音频视频处理技术及工程实践(分卷0)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++音频视频处理技术及工程实践(含源码2/2)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 ...

    Visual C++音频视频处理技术及工程实践地址

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 ...

    Visual C++音频视频处理技术及工程实践(分卷9)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++音频/视频处理技术及工程实践 (分卷1)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++ 音频/视频 处理技术及工程实践(分卷3)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++音频视频处理技术及工程实践(分卷7)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++音频视频处理技术及工程实践(分卷6)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    Visual C++音频/视频处理技术及工程实践(分卷2)

    13.4.4 使用Cache技术实现算法优化 507 13.4.5 使用乒乓式EDMA实现算法优化 508 13.5 DM642优化视频算法常见问题 513 13.6 本章小结 518 第14章 XviD CODEC实现MPEG-4编解码 519 14.1 MPEG-4编解码概述 520 14.1.1 ...

    微机原理及接口技术

    4.5 基本结构程序设计............................ 100 4.5.1 顺序程序设计......................... 101 4.5.2 分支程序设计......................... 102 4.5.3 循环程序设计......................... 105 ...

    服务器部件基础.pptx

    2023/6/4 Inspur group 2.2.3 CACHE技术简介 设置在CPU内部的存储区域,通常将系统最常用的指令放在CACHE中,减少重复调用指令的时间 一般CPU内部CACHE空间较少,根据使用频度可以设置多级,包括一级缓存(L1 Cache...

    微型计算机原理与接口技术(第三版)电子书及答案周荷琴

    6.7.2 高速缓冲存储器(cache) 165 6.7.3 虚拟存储器 167 本章小结 169 思考与练习题 170 第7章 输入/输出接口技术 172 7.1 概述 172 7.1.1 输入/输出接口电路要解决的问题 172 7.1.2 输入/输出接口的结构与功能 ...

    网络安全技术参数(1).docx

    网络安全技术参数(1)全文共10页,当前为第1页。...(5)、投标产品符合GA/T 698-2007信息安全技术 信息过滤产品安全功能要求(基本级)中相应的条款所述的有关要求,提供公安部信息过滤产品安全功能测

    UNIX 高级教程系统技术内幕

    11.4.1 基本特征 11.5 日志结构文件系统 11.6 4.4BSD 日志文件系统 11.6.1 写日志 11.6.2 数据检索 11.6.3 崩溃恢复 11.6.4 清除进程 11.6.5 分析 11.7 元数据日志 11.7.1 正常操作 11.7.2 日志的一致 11.7.3 崩溃...

    TCP-IP技术大全

    ARP和RARP 41 5.1 使用地址 41 5.1.1 子网寻址 41 5.1.2 IP地址 43 5.2 使用地址解析协议 44 5.2.1 ARP cache 45 5.2.2 代理ARP 47 5.2.3 反向地址解析协议 47 5.3 使用ARP命令 47 5.4 ...

    TCP/IP技术大全

    23.11 Windows 2000新特性 260 23.12 小结 261 第24章 在Novell NetWare中支持IP 262 24.1 Novell与TCP/IP 262 24.1.1 IP与NetWare 4 262 24.1.2 NetWare 5与Pure IP初始化 262 24.2 传统解决方案:NetWare 3.x到 ...

    JavaStudy:一角钱技术 All in One

    嗨你好,我是一角钱技术~ 大家可以去获取或者加我提意见(别忘记Star哟)。 原创文章每周最少两篇,公众号首发文章。博客会晚一两篇。 目录 注 : 没链接的是还没写 数据结构与算法 链表的基本实现和特性 栈、队列、...

Global site tag (gtag.js) - Google Analytics