java中的缓存.pdf





《java中的缓存.pdf》由会员分享,可在线阅读,更多相关《java中的缓存.pdf(13页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、JAVA 缓存1Hibernate的缓存机制介绍缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。缓存的介质一般是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。Hibernate 的缓存包括Session的缓存和 SessionFactory的缓存,其中SessionFactory 的缓存又可以分
2、为两类:内置缓存和外置缓存。Session 的缓存是内置的,不能被卸载,也被称为Hibernate 的第一级缓存。SessionFactory的内置缓存和Session的缓存在实现方式上比较相似,前者是 SessionFactory对象的一些集合属性包含的数据,后者是指Session 的一些集合属性包含的数据。SessionFactory 的内置缓存中存放了映射元数据和预定义SQL 语句,映射元数据是映射文件中数据的拷贝,而预定义SQL 语句是在 Hibernate 初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQ
3、L 语句,因此 SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory 的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory 的外置缓存也被称为Hibernate 的第二级缓存。Hibernate 的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝,那么它们之间的区别是什么呢?为了理解二者的区别,需要深入理解持久化层的缓存的两个特性:缓存的范围和缓存的并发访问策略。持久化层的缓存的范围缓存的范围决定了缓存的生命周期以及可
4、以被谁访问。缓存的范围分为三类。1 事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。在此范围下,缓存的介质是内存。事务可以是数据库事务或者应用事务,每个事务都有独自的缓存,缓存内的数据通常采用相互关联的的对象形式。2 进程范围:缓存被进程内的所有事务共享。这些事务有可能是并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。进程范围的缓存可能会存放大量的数据,所以存放的介质可以是内存或硬盘。缓存内的数据既可以是相互关联的对象形式也可以是对象的松散数据形式。松散的对象数
5、据形式有点类似于对象的序列化数据,但是对象分解为松散的算法比对象序列化的算法要求更快。3 集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性,缓存中的数据通常采用对象的松散数据形式。对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查到相应的数据,还可以到进程范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查询。事务范围的缓存是持久化层的第一级缓存,通常它
6、是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。持久化层的缓存的并发访问策略当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。读写型:提供了Read Committed 事务隔离级别。仅仅在非集群的环境中适用。对于经常
7、被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。非严格读写型:不保证缓存与数据库中数据的一致性。如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。什么样的数据适合存放到第二级缓存中?1、很少被修改的数据2、不是很重要的数据,允许出现偶尔并发的数据3、不会被并发访问的数据4、参考数据不适
8、合存放到第二级缓存的数据?1、经常被修改的数据2、财务数据,绝对不允许出现并发3、与其他应用共享的数据。Hibernate 的二级缓存如前所述,Hibernate 提供了两级缓存,第一级是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必需的,不允许而且事实上也无法比卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。第二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory 对象的生命周期和应用程序的整个过程对应,因此第二级缓存是进程范围或者集
9、群范围的缓存。这个缓存中存放的对象的松散数据。第二级对象有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate 集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。Hibernate 的二级缓存策略的一般过程如下:1)条件查询的时候,总是发出一条select*from table_name where.(选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。2)把获得的所有数据对象根据ID 放入到第二级缓存中。3)当 Hibernate 根据 ID 访问数据对象的时候,首
10、先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID 放入到缓存。4)删除、更新、增加数据的时候,同时更新缓存。Hibernate 的二级缓存策略,是针对于 ID 查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query 缓存。Hibernate 的 Query 缓存策略的过程如下:1)Hibernate 首先根据这些信息组成一个Query Key,Query Key 包括条件查询的请求一般信息:SQL,SQL 需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。
11、2)Hibernate 根据这个 Query Key 到 Query 缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key 放入到 Query 缓存中。3)Query Key 中的 SQL 涉及到一些表名,如果这些表的任何数据发生修改、删2java 中的缓存技术该如何实现看一粒沙中的世界,一朵野花中的天堂。把无限握于掌中,把永恒握于瞬间。威廉?布莱克开始讨论缓存之前,让我们先来讨论讨论另外一个问题:理论和实践.从ahuaxuan接触的程序员来看,有的程序员偏实践,有的程序员偏理论,但是这都是不好的行为,理论和实践同
12、样重要,我们在做很多核心的算法的时候,没有理论根本无从下手,而在我们多年的实践中,不总结理论就不能加深自己的理解.所以理论和实践同等重要.缓存是当今各种软件或者硬件系统中不可缺少的技术之一,所以对每个程序员来说都显得异常重要,对 ahuaxuan 来说亦是如此.如果说用 dfa 实现文字过滤是从理论到实践,那么本文便是从实践中总结出得理论.在讨论缓存功能之前,我们首先来了解一下缓存这个东西本身.ahuaxuan 根据自己的经验把缓存问题细分为4 类小问题.1 缓存为什么要存在?2 缓存可以存在于什么地方?3 缓存有哪些属性?4 缓存介质?搞清楚这 4 个问题,那么我们就可以随意的通过应用的场景
13、来判断使用何种缓存了.下面 ahuaxuan 和大家一一分析这4 个问题.1.缓存为什么要存在?一般情况下,一个网站,或者一个应用,它的一般形式是,浏览器请求应用服务器,应用服务器做一堆计算后再请求数据库,数据库收到请求后再作一堆计算后把数据返回给应用服务器,应用服务器再作一堆计算后把数据返回给浏览器.这个是一个标准流程.但是随着互连网的普及,上网的人越来越多,网上的信息量也越来越多,在这两个越来越多的情况下,我们的应用需要支撑的并发量就越来越多.然后我们的应用服务器和数据库服务器所做的计算也越来越多,但是往往我们的应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的(谁叫俺们的硬盘转
14、速有限呢).如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计算量,缩短请求流程(减少网络 io 或者硬盘 io),这时候缓存就可以大展手脚了.缓存的基本原理就是打破上图中所描绘的标准流程,在这个标准流程中,任何一个环节都可以被切断.请求可以从缓存里取到数据直接返回.这样不但节省了时间,提高了响应速度,而且也节省了硬件资源.可以让我们有限的硬件资源来服务更多的用户.2 缓存可以存在于什么地方?Java 代码1.数据库分过层的 app-浏览器和 app 之间-浏览器-数据库 分过层的 app-浏览器和 app 之间-浏览器-在上图中,我们可以看到一次请求的一般流程,下面我们重新绘制这张
15、图,让我们的结构稍微复杂一点点.(将 app 分层)数据库 分过层的 app-浏览器和 app 之间-浏览器-理论上来将,请求的任何一个环节都是缓存可以作用的地方.第一个环节,浏览器,如果数据存在浏览器上,那么对用户来说速度是最快的,因为这个时候根本无需网络请求.第二个环节,浏览器和 app 之间,如果缓存加在这个地方,那么缓存对app 来说是透明的.而且这个缓存中存放的是完整的页面.第三个节点,app 中本身就有几个层次,那么缓存也可以放在不同的层次上,这一部分是情况或者场景比较复杂的部分.选择缓存时需要谨慎.第四个环节,数据库中也可以有缓存,比如说 mysql 的 querycache.那
16、么也就是说在整个请求流程的任何一点,我们都可以加缓存.但是是所有的数据都可以放进缓存的吗.当然不是,需要放进缓存的数据总是有一些特征的,要清楚的判断数据是否可以被缓存,可以被怎样缓存就必须要从数据的变化特征下手.数据有哪些变化特征?最简单的就是两种,变和不变.我们都知道,不会变化的数据不需要每次都进行计算.问题是难道所有的数据理论上来讲都会变化,变化是世界永恒的主题.也就是说我们把数据分为变和不变两种是不对的,那么就让我们再加一个条件:时间.那么我们就可以把数据特征总结为一段时间内变或者不变.那么根据这个数据特征,我们就可以在合适的位置和合适的缓存类型中缓存该数据.3 缓存有哪些属性从面向对象
17、的角度来看,缓存就是一个对象,那么是对象,必然有属性.那么下面我们来探讨一下缓存有哪些属性.以下列举我们常用到的3 个属性.(1)命中率命中率是指请求缓存次数和缓存返回正确结果次数的比例.比例越高,就证明缓存的使用率越高.命中率问题是缓存中的一个非常重要的问题,我们都希望自己缓存的命中率能达到 100%,但是往往事与愿违,而且缓存命中率是衡量缓存有效性的重要指标.(2)最大元素缓存中可以存放得最大元素得数量,一旦缓存中元素数量超过这个值,那么将会起用缓存清空策略,根据不同的场景合理的设置最大元素值往往可以一定程度上提高缓存的命中率.从而更有效的时候缓存.(3)清空策略1 FIFO,first
18、in first out,最先进入缓存得数据在缓存空间不够情况下(超出最大元素限制时)会被首先清理出去2 LFU,Less Frequently Used,一直以来最少被使用的元素会被被清理掉。这就要求缓存的元素有一个hit 属性,在缓存空间不够得情况下,hit 值最小的将会被清出缓存。2 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。4 缓存介质从硬件介质上来将无非就是两种,内存和硬盘(对应应用层的程序来讲不用考虑寄存器等问题).但是往往我
19、们不会从硬件上来划分,一般的划分方法是从技术上划分,可以分成几种,内存,硬盘文件.数据库.(1)内存.将缓存放在内存中是最快的选择,任何程序直接操作内存都比操作硬盘要快的多,但是如果你的数据要考虑到break down 的问题,因为放在内存中的数据我们称之为没有持久话的数据,如果硬盘上没有备份,机器 down机之后,很难或者无法恢复.(2)硬盘.一般来说,很多缓存框架会结合使用内存和硬盘,比如给内存分配的空间有满了之后,会让用户选择把需要退出内存空间的数据持久化到硬盘.当然也选择直接把数据放一份到硬盘(内存中一份,硬盘中一份,down 机也不怕).也有其他的缓存是直接把数据放到硬盘上.(3)数
20、据库.说到数据库,可能有的人会想,之前不是讲到要减少数据库查询的次数,减少数据库计算的压力吗,现在怎么又用数据库作为缓存的介质了呢.这是因为数据库又很多种类型,比如 berkleydb,这种 db不支持 sql 语句,没有 sql 引擎,只是 key 和 value 的存储结构,所以速度非常的快,在当代一般的 pc 上,每秒中十几 w次查询都是没有问题的(当然这个是根据业务特征来决定的,如果您访问的数据在分布上是均匀的,那 ahuaxuan可不能保证这个速度了).除了缓存介质之外,ahuaxuan 根据缓存和应用的耦合程度将其划分为local cache 和 remote cache.Loca
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 中的 缓存

限制150内