框架集成式缓存

一   缓存简介

首先你要明白一点的是:我们应用程序中的数据要进行永久性存储,要么存于文件,要么存于数据库,
那么不管是文件还是数据库,其实都在磁盘上。问题来了,磁盘是低速存储设备,如果我们要从磁盘读取数据,
性能将会很差,当然这个很差是相对于内存来说,内存的读写性能通常是磁盘的10倍以上!
所以如果我们把应用程序和磁盘的数据交换变为和内存的数据交换,将大大提高应用程序的性能!
缓存:即让数据更接近于使用者;
工作机制是:先从缓存中(内存中)读取数据,如果没有再从慢速设备(磁盘)上读取实际数据(数据也会存入缓存);
缓存什么:那些经常读取且不经常修改的数据/那些昂贵(CPU/IO)的且对于相同的请求有相同的计算结果的数据。
例如:我们一个查询学生数据的web应用程序,我们先让它在内存中找,如果没有就去到磁盘上找。
还有如用过Maven的朋友都应该知道,我们找依赖的时候,先从本机仓库找,再从本地服务器仓库找,最后到远程仓库服务器找;
还有如京东的物流为什么那么快?
他们在各个地都有分仓库,如果该仓库有货物那么送货的速度是非常快的。
如果分库没有,那就只能让全国的集散中心发货,那就比较慢了!

缓存命中率

即从缓存中读取数据的次数 与 总读取次数的比率,命中率越高越好:
命中率 = 从缓存中读取次数 / (总读取次数[从缓存中读取次数 + 从慢速设备上读取的次数])
Miss率 = 没有从缓存中读取的次数 / (总读取次数[从缓存中读取次数 + 从慢速设备上读取的次数])
这是一个非常重要的监控指标,如果做缓存一定要健康这个指标来看缓存是否工作良好;


缓存策略
Eviction policy

移除策略,即如果缓存满了,从缓存中移除数据的策略;常见的有LFU、LRU、FIFO:
FIFO(First In First Out):先进先出算法,即先放入缓存的先被移除;
LRU(Least Recently Used):最久未使用算法,使用时间距离现在最久的那个被移除;
LFU(Least Frequently Used):最近最少使用算法,一定时间段内使用次数(频率)最少的那个被移除;
 
TTL(Time To Live )
存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)
 
TTI(Time To Idle)
空闲期,即一个数据多久没被访问将从缓存中移除的时间。
 
 
到此,基本了解了缓存的知识。
在Java中,我们一般对调用方法进行缓存控制,比如我调用"findUserById(Long id)",
那么我应该在调用这个方法之前先从缓存中查找有没有,如果没有再调用该方法如从数据库加载用户,
然后添加到缓存中,下次调用时将会从缓存中获取到数据。


二   java web程序中使用缓存

       java web程序中如果要使用缓存,一般有两种方案:1. 使用hibernate框架结合缓存插件(ehcache,oscache) 或使用mybatis自带的缓存机制;

2. 使用独立缓存程序(redis,memcached等)。本文使用第一种,独立缓存的使用请继续关注我的博文。

      这里我们使用mybatis自带的缓存机制来讲解该问题。关于mybatis缓存请参考我的博文【http://blog.csdn.net/wx5040257/article/details/78768244】

     假如有一个查询员工的web程序,如图所示:


如果没有利用缓存,那么反复点击首页,就会反复查询数据库,从日志输出中,我们可以看到每次都会输出sql语句


好,现在我们把缓存功能加上

首先在mybatis核心配置文件中加入如下代码开启缓存

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "mybatis-3-config.dtd">
<configuration>
     <settings>
        <!-- 是否开启全局缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 查询时,关闭关联对象即时加载以提高性能 -->
        <setting name="lazyLoadingEnabled" value="false"/>
        <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
        <setting name="multipleResultSetsEnabled" value="true"/>
        <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
	<typeAliases>
		<typeAlias type="com.obtk.entitys.StudentEntity" alias="StudentEntity"/>
		<typeAlias type="com.obtk.entitys.DeptEntity" alias="DeptEntity"/>
		<typeAlias type="com.obtk.entitys.UserEntity" alias="UserEntity"/>
		<typeAlias type="com.obtk.entitys.PageEntity" alias="PageEntity"/>
	</typeAliases>
</configuration>
注意settings部分!

然后在mapper文件中加入如下代码


接下来重新发布应用程序,继续多次点击首页,观察结果


有缓存命中率,说明缓存命中了,并没有看到sql语句,说明数据来自内存!


接下来删除一条数据


然后继续点击第一页,发现又有sql输出了,说明删除数据的时候缓存被刷新了(清除了)!


进行一下登录操作


没有登录sql,说明用户操作利用了缓存!

说明刷新缓存只刷新当前mapper文件的缓存数据,而不会影响其它mapper文件的缓存数据!

这里讲的就是集成式缓存,但这种缓存方案不适合大型应用,因为应用程序和缓存共用同一块内存,数据量大的话会导致内存不足!

请继续关注我的博文,后面将会讲解独立缓存的使用!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御前两把刀刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值