这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天
这篇文章主要是收集了笔者在学习今天的课程,在学习了一些秒杀系统设计与实现课程后并进行实践操作后,总结了一些注意点。
秒杀系统设计注意点5
使用缓存带来的相关问题
缓存击穿
上次我们介绍了缓存击穿的第一种解决方法:互斥锁。所以,此处主要讲述缓存击穿的另外一种解决方法:逻辑过期。
逻辑过期
我们都知道,缓存击穿的产生原因,是因为某个或某些key对应缓存忽然失效,导致大量用户的请求无法集中缓存,而直接去查询数据库,而此时大量的请求就会使得后台压力巨大。
因此,我们想解决问题,只需要让这些缓存不失效不就行了!但是,实现缓存技术,通常是由内存级别的非关系数据库,比如redis,所以我们绝对不能直接令缓存的TTL变为无穷大,使得缓存在物理意义上永不过期,因为这样会让后台存储空间爆炸!
那么,既然我们不能让设置缓存在非关系数据库中,的过期时间是非常久的,那么,我们就让它的“逻辑过期”时间是非常久的就行了。即,我们不再把TTL设置到非关系数据库中,而是把这个缓存的TTL,作为这个缓存的数据信息的一部分,一起存入到非关系数据库中!
那么,为什么这样就可以达到解决缓存击穿的效果呢?这是因为,当我们把TTL设置到非关系数据库中时,非关系数据库会自己检测过期时间,当过期时间一到就直接删除缓存,这样就会产生“击穿”的效果;而当我们采取另外的做法时,数据库就不会自己删除缓存了。而当等到下一次的用户查询,取出缓存后发现此时数据过期时,就会先返回过期数据,然后申请一个互斥锁,来通过类似之前互斥锁的做法,去查询数据库,并将新的信息插入redis等非关系数据库中。
很容易看出来,逻辑过期的特点有:
- 发现数据过期的那次查询,得到的是过期的数据,即“脏数据”。这实际上就是一个缺点。
- 还是要用互斥锁。所以更通俗地解释逻辑过期做法,实际上是“人为设置过期时间+互斥锁”。