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

iBATIS缓存

阅读更多

 

一.缓存介绍

1.1缓存对象

理论上,Web分层设计的各个层都可以有缓存,Web中的任何对象都可以缓存。

Http请求结果的缓存

浏览器缓存、代理缓存、服务器端方向代理缓存、使用Filter实现对请求结果页面的缓存

Java对象的缓存

缓存数据库查询结果对象

1.2缓存介质[保存在哪里]

从硬件介质上来将无非就是两种,内存和硬盘(对应应用层的程序来讲不用考虑寄存器等问题).但是往往我们不会从硬件上来划分,一般的划分方法是从技术上划分,可以分成几种,内存,硬盘文件.数据库.

1.2.1内存

将缓存放在内存中是最快的选择,任何程序直接操作内存都比操作硬盘要快的多,但是如果你的数据要考虑到break down的问题,因为放在内存中的数据我们称之为没有持久话的数据,如果硬盘上没有备份,机器down机之后,很难或者无法恢复.

1.2.2硬盘

一般来说,很多缓存框架会结合使用内存和硬盘,比如给内存分配的空间有满了之后,会让用户选择把需要退出内存空间的数据持久化到硬盘.当然也选择直接把数据放一份到硬盘(内存中一份,硬盘中一份,down机也不怕).也有其他的缓存是直接把数据放到硬盘上.

1.2.3数据库

说到数据库,可能有的人会想,之前不是讲到要减少数据库查询的次数,减少数据库计算的压力吗,现在怎么又用数据库作为缓存的介质了呢.这是因为数据库又很多种类型,比如berkleydb,这种db不支持sql语句,没有sql引擎,只是keyvalue的存储结构,所以速度非常的快,在当代一般的pc,每秒中十几w次查询都是没有问题的.

1.3命中率

命中率是指请求缓存次数和缓存返回正确结果次数的比例.比例越高,就证明缓存的使用率越高.

命中率问题是缓存中的一个非常重要的问题,我们都希望自己缓存的命中率能达到100%,但是往往事与愿违,而且缓存命中率是衡量缓存有效性的重要指标.

1.4最大保存元素数量

缓存中可以存放得最大元素得数量,一旦缓存中元素数量超过这个值,那么将会起用缓存清空策略,根据不同的场景合理的设置最大元素值往往可以一定程度上提高缓存的命中率.从而更有效的时候缓存.

1.5缓存更新策略

1.5.1 FIFO[first in first out]

最先进入缓存得数据在缓存空间不够情况下(超出最大元素限制时)会被首先清理出去

1.5.2 LFU[Less Frequently Used]

一直以来最少被使用的元素会被被清理掉。这就要求缓存的元素有一个hit 属性,在缓存空间不够得情况下,hit 值最小的将会被清出缓存。

1.5.3 LRU[Least Recently Used]

最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

1.6本地缓存VS远程缓存

Local Cache:本地缓存

Remote Cache:远程缓存

Local Cache最大的优点是应用和Cache的时候是在同一个进程内部,请求缓存非常快速,完全不需要网络开销等.所以单应用,不需要集群或者集群情况下cache node不需要相互通知的情况下使用local cache比较合适.

但是Local cache是有一定的缺点的,一般这种缓存框架都是local cache.也就是跟着应用程序走的,多个应用程序无法直接共享缓存,应用集群的情况下这个问题更加明显,当然也有的缓存组件提供了集群节点相互通知缓存更新的功能,但是由于这个是广播,或者是环路更新,在缓存更新频繁的情况下会导致网络io开销非常大,严重的时候会影响应用的正常运行.而且如果缓存中数据量较大得情况下使用local cache意味着每个应用都有一份这么大得缓存,着绝对是对内存的浪费.

所以这个情况下,往往我们会选择remote cache,.这样集群或者分布式的情况下各个应用都可以共享memcached中的数据,这些应用都通过socket和基于tcp/ip协议上层的memcached协议直接连接到memcached,有一个app更新了memcached中的值,所有的应用都能拿到最新的值.虽然这个时候多了很多了网络上的开销,但是往往这种方案要比localcache广播或环路更新cache节点要普遍的多,而且性能也比后者高.由于数据只需要保存一份,所以也提高了内存的使用率.

二.iBATIS高速缓存介绍

2.1 iBATIS高速缓存的关注点

 iBATIS高速缓存只关注如何在持久层对查询结果进行缓存。

2.2 iBATIS对高速缓存管理的帮助

iBATIS带来的好处就是通过配置文件来管理高速缓存,帮助避免因手工管理高速缓存结果及其依赖性而造成的大量繁琐的工作。

2.3 iBATIS高速缓存和传统O/RM高速缓存的区别

iBATIS的思想是建立SQL语句到对象的映射,而不是建立数据库表到对象的映射。传统O/RM工具主要关注数据库表到对象的映射。

传统的O/RM高速缓存会为其管理的每个对象维护一个OID[object identification,对象标识],就像数据库需要管理其表中的每条记录的唯一性一样。这意味着,如果两个不同的结果都返回同一个对象,那么该对象将只被高速缓存一次

iBATIS不这样,关注的是SQL语句的执行结果,我们不会根据对象的唯一性来高速缓存它们iBATIS高速缓存的所有结果,而不考虑所标识的对象是否存在于高速缓存中。

<!--[if !supportLists]-->三.<!--[endif]-->配置iBATIS缓存

3.1 cacheModel标签

cacheModel标签用来配置iBATIS的高速缓存,cacheModel标签的属性包括四个

3.1.1 cacheModel标签的属性

<!--[if !supportLists]-->l  <!--[endif]-->id[必需]

该值用来指定一个唯一的ID,便于为需要使用此高速缓存模型所配置的高速缓存的查询已映射语句使用。

<!--[if !supportLists]-->l  <!--[endif]-->type[必需]

此属性用于指定高速缓存所配置的高速缓存的类型。其有效值包括MEMORY LRU FIFO OSCACHE,该属性也可取值为某个自定义CacheController实现的全限定名。

<!--[if !supportLists]-->l  <!--[endif]-->readOnly[可选]

取值为true时表示高速缓存将仅仅用作只读缓存,从只读高速缓存中读出的对象的特性值不允许修改。

<!--[if !supportLists]-->l  <!--[endif]-->serialize[可选]

该属性用于指定在读取高度缓存内容时是否要进行深复制

readOnlyserialize属性经常联合起来使用。

3.1.2 联合使用readOnlyserialize属性

readOnly

seralize

结果

 

true

false

可以最快地检索出已高速缓存对象。返回已高速缓存对象的一个共享实例,若使用不当可能会导致问题

false

true

能快速检索出已高速缓存对象。返回已高速缓存对象的一个深副本

false

false

警告

对于此组合,高速缓存仅仅同调用线程的会话的生命周期相关,且不能被其他线程所使用

true

true

这种组合同readOnly=false&serialize=true的组合作用一致,否则它在语意上无任何意义

【表1】联合使用readOnlyserialize属性

【备注】默认组合是readOnly=true&serialize=false

3.2 iBATIS高速缓存模型的类型

3.2.1 MEMORY

MEMORY高速缓存是一种基于引用的高速缓存(参考java.lang.ref)。高速缓存中的每个对象都被赋予一个引用类型,此引用类型为垃圾收集器提供了线索,指导它如何处理相应的对象。

MEMORY高速缓存模型对于那些更关注内存的管理策略而不是对象的访问策略的应用程序而言是完美的。有了STRONGSOFTWEAK这三种引用类型,就可以确定哪些结果应该比其他结果保留更长的时间。

 

 

WEAK

    WEAK应用类型将很快地废弃已高速缓存的对象。这种引用类型不会阻止对象被垃圾收集器收集。它仅仅提供一种方式来访问高速缓存的对象,该对象在垃圾回收器的第一遍收集就会被移除。这是MEMORY的默认的引用类型,如果保存在高速缓存中的所有对象都会以非常一致的方式被访问,那么使用这种类型就非常合适。由于高速缓存对象被废弃的速度比较快,可以确保你的高速缓存不会超过内存限制。然而,使用这种引用类型时,数据库访问的频率会很高。

SOFT

    SOFT引用类型也适合于那些将满足内存约束看的很重要,必要时就会放弃高速缓存对象的情况。这种引用类型在满足内存约束的情况下,将尽可能地保存已高速缓存对象。此时,垃圾收集器始终不会收集对象,除非确定需要更多的内存。SOFT引用也确保不会超过内存限制,并且和WEAK类型相比,其数据库访问频率会低一些。

STRONG

    STRONG引用类型不管内存约束,其中的已高速缓存对象永远不会被废弃,除非到达了指定的清除时间间隔。STRONG类型的高速缓存应该用于存放那些静态的小对象,并且对这些小对象的访问应该有一定规律。这个引用类型可以通过减少数据库访问频率提高性能,但当高速缓存中的数据越来越多时存在内存耗尽的风险。

【表2MEMORY高速缓存reference-type属性取值及对应含义

3.2.2 LRU

LRU类型的高速缓存模型使用最近最少使用策略来管理高速缓存。该高速缓存的内部机制会在后台记录哪些对象最近最少使用,一旦超过高速缓存大小限制就会废弃它们。大小限制规定了高速缓存中可以存放的对象数目。应避免将那些占用较大内存的对象放置在此类高速缓存中,否则内存会很快耗尽。

LRU高速缓存非常设用于那些需要根据某些特定对象的访问频率来管理的高速缓存的情况。通常这种高速缓存策略试用于那些需要高速缓存用于分页结果或关键词搜索结果的对象应用程序中。

3.2.3 FIFO

FIFO高速缓存模型采用先进先出的管理策略,是一种基于时间的策略,使用于放置那些初放入时使用频率高、随时间流逝访问频率就会降低的对象。如:报表、报告股票价格。

3.2.4 OSCACHE

使用OSCache,意味着需要OSCache组件的支持,需要将相应的jar包和配置文件引入进来。

3.2.5自定义高速缓存模型

只需要实现com.ibatis.sqlmap.engine.cache.CacheController接口即可,配置时设定type为全限类名或其别名即可。

3.3 高速缓存的清除

使用flushOnExecuteflushInterval标签可以定义清空缓存触发条件

标签名称

 

<flushOnExecute>

定义查询已映射语句,其执行将引起相关高速缓存的清除

<flushInterval>

定义一个时间间隔,高速缓存将以此间隔定期清除

【表3<flushOnExecute><flushInterval>标签

 

属性

 

hours(可选)

每次清除高速缓存前应该经过的小时数

minutes(可选)

每次清除高速缓存前应该经过的分钟数

seconds(可选)

每次清除高速缓存前应该经过的秒数

milliseconds(可选)

每次清除高速缓存前应该经过的毫秒数

【表4<flushInterval>标签属性 

3.4 设置高速缓存模式实现的特性

由于高速缓存模型只是一些可以插入到iBATIS框架的组件,它甚至允许用户自己定制,因此必须有一种方式能为这些组件提供任意的值。<property>标签就是用来完成此任务的。

属性

 

name(必需)

所设定的特性的名称

value(必需)

所设定的特性的值

【表5<property>标签的属性

 

3.5 常见问题

3.5.1如何选择iBATIS高速缓存模型类型

如何选择一个适合实际应用情况的高速缓存模型类型是一个很负责的问题,需要考虑诸多因素。

 

需要考虑的因素:

1.当前应用程序是否是数据库的唯一操作入口

2.读写属性

3.缓存时间间隔

4.失效控制

5.最大保存对象数目

 

举例:

<!--[if !supportLists]-->1.<!--[endif]-->只读的长效数据

购物车中的物品类别--LRU

缓存只读的长效数据可以明显地提升访问效率,如果使用LRU高速缓存模型,记得不要将其size属性值设置过大,否则就变成了STRONG类型的MEMORY高速缓存。

<!--[if !supportLists]-->2.<!--[endif]-->可读写数据

根据对象的更新频率选择是否需要对其进行缓存

<!--[if !supportLists]-->3.<!--[endif]-->旧的静态数据

每小时内顾客购买的最多5件产品--FIFO

需要多找一些例子,让大家进行讨论和选择;另外需要在实际应用中找到验证所选择的缓存模型类型是否是最佳方案的方式。

 

场景

适合缓存模型类型

 

翻页

LRU

......

 

 

 

 

 

 

【表6iBATIS高速缓存模型类型选择讨论示例表格

3.5.2如何手工强制清除iBATIS高速缓存中保存的对象

SqlMapClient接口提供了相关的方法:

public void flushDataCache()

public void flushDataCache(String cacheId)

分别用来清空所有缓存内容及指定ID的缓存内容,先获取到SqlMapClient接口具体实现的实例,然后就可以进行相关操作。

3.5.3 OSCACHE基本使用及配置项说明

http://mov-webhobo.iteye.com/admin/blogs/1672234

 

<!--[if !supportLists]-->四.<!--[endif]-->参考资料

iBATIS实战》 9章,使用高速缓存提升性能

 

论缓存之第一<>

http://www.javaeye.com/topic/345693

 

论缓存之第二<近与快>

http://www.javaeye.com/topic/348671

 

iBATIS中的强制刷新缓存

http://blogger.org.cn/blog/more.asp?id=32349&name=lhwork

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics