Java技术:剖析缓存击穿的处理方式

缓存Cache这个词,相信作为一个软件开发人员,是常常提到的一个词,并且也是在项目里面经常使用的一个词;这个东西很重要的,我们也很有必要了解这个内容;首先请同学们,先思考:

我们系统里面为什么需要缓存?

从下面没有缓存的情况和有缓存的情况进行对比大家就应该清楚了,我们为什么需要缓存;

下图是没有缓存情况,用户user1 和 user2 在访问应用程序,每次来访问数据,都要查询数据库,而经常操作数据库,就会存在性能的读写瓶颈;所有需要缓存来解决;

Java技术:剖析缓存击穿的处理方式

缓存是什么?

缓存相当于容器,能够把数据存储到一块空间,这个空间通常指的是内存;

现在如果系统里面存在缓存的情况,是怎样的处理的?

同样是user1和user2来访问,第一次用户user1来访问的时候,发现没有数据,就直接从数据库db里面加载数据,然后加载完之后,会把数据放入一份到缓存里面,这个缓存底层通常是通过map来存放,第二次user2来访问的,就先从缓存里面搜索,如果有数据,直接返回数据,如果没有就查询数据库,查询的数据放入缓存里面;如果这样处理的话,下次如果还有其他人来访问,相同的数据 直接从缓存里面搜索,不会每次都从数据查询,极大的提高用户的响应速度 和 减轻的数据库的压力,如下图所示:

Java技术:剖析缓存击穿的处理方式

但是就上面的缓存方案也是存在问题的,那究竟存在什么问题呢? --- 缓存击穿问题

什么是缓存击穿?

比如说如果有些人来访问,比如黑客,他想攻击你的系统的时候,他故意在同一时间内,给你制造很多不存在的值,如果在访问这些不存在的值的时候,发现缓存里面没有,那会把这些请求都会转发到数据库,那这样数据库压力就会变大,完全有可能承受不住导致数据库系统的崩溃;这样就是缓存击穿;

怎么解决缓存击穿呢?

方案一:可以把不存在的key也设置缓存,并设置过期时间;

解决思路,尽量的把请求拦截到,不让它去访问数据库,那我们怎么去拦截呢,比如说,当拿一个不存在key访问程序的时候,如果查询数据库,不存在对应的值,那我们也会给不存在的这个key 存入到缓存里面,并且可以设置缓存失效时间;比如说可以把对应的key设置为null值存入到缓存里面,如果下次有相同的key来访问的时候,在缓存失效之前,都是直接从缓存里面取;这样就会把不必要的请求拦截下来;

如果假如后面业务需求的增加,这key在数据库里面已存在,那么缓存失效之后,就可以利用这key,去加载数据;

方案二:使用redis或者zookeep提供的互斥锁也可以解决缓存击穿

这种方案是通过异步方式 去获取缓存过程中,其他key 处于等待现象,必须等待第一个构建完缓存之后,释放锁,其他人才能通过该key才能访问数据;如下图所示

Java技术:剖析缓存击穿的处理方式

第一个key1 在查询db,获取数据 到放入缓存过程中,都有把锁 先锁住,其他人就必须等待,等待这个人把缓存设置成功,才去释放锁,那其他人就直接从缓存里面取数据;不会造成数据库的读写性能的缺陷;

Java技术:剖析缓存击穿的处理方式


分享到:


相關文章: