Hibernate缓存机制对Hibernate的性能发挥一直处于一个极其重要的作用,它是持久层性能提升的关键。
Hibernate缓存介于Hibernate应用和数据库之间,缓存中存放了数据库数据的拷贝。其作用是减少访问数据库的频率,从而提高应用的运行性能。
Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称为“缓存命中”),则直接把命中的数据作为结果加以使用,避免了建立数据库查询的性能损耗。
Hibernate提供了两级缓存:一级缓存(Session级缓存)
二级缓存(SessionFactory级别的全局缓存)
缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围可以分为三类:
- 事务范围 缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。缓存的介质是内存。事务可以是数据库事务或者应用事务,每个事务都有独自的缓存,缓存内的数据通常采用相互关联的对象形式。一级缓存就属于事务范围。
- 进程范围 缓存被进程范围内的所有事务共享。 这些事务有可能并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。它的物理介质可以是内存或硬盘。
- 集群范围 在集群环境中,缓存被一个机器或多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性,缓存中的数据通常采用对象的松散数据形式。
这里提下松散数据,它的存放如图:
-
这种分布是不紧凑的,牺牲了很多空间,但可以最快速的找到数据。而list这种排列紧凑的数据集合一般用于批处理。
-
当然还有兼顾空间和速度的数据结构,那就是树结构,在查找时不需要所有数据都进行遍历,时间复杂度一般是O(logn),而且空间是紧凑的,采用的是链表结构,而不是紧凑的数组。所以在时间和空间上都不比前两者,但用途却十分广大,我们所用的数据库的索引基本上都是用的树。这样既保证了占用空间小,查询的速度也不慢。
-
缓存也有其策略,最常见的是按时间缓存,在单位时间内该数据有效,每当访问该数据时都要判断缓存的数据是否过期,再决定Get还是Remove。除了时间策略,还有使用热度策略,由于内存有限,所以我们的缓存也不是无限申请的,是时候限制长度了。限制了长度就意味着有人能进来就得有人要出去。这就是Remove策略。我们可以对所有的缓存打上标记,来标记他的热度,每次添加缓存的时候把热度最低的缓存剔除掉(假如已经达到限制的话)。每次获取缓存的时候给该缓存热度+1。
当一个人找不到出路的时候,最好的办法就是将当前能做好的事情做到极致,做到无人能及。