击穿
大家都知道,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生了缓存,将一些热点数据放在内存中,随用随取,降低连接到数据库的请求链接,避免数据库挂掉。需要注意的是, 无论是击穿还是后面谈到的穿透与雪崩,都是在高并发前提下 ,当缓存中某一个热点key失效,
为什么会有击穿发生呢?
有两个主要原因:
Key过期
Key被页面置换淘汰
对于第一个原因是因为在Redis中,Key有过期时间,如果某一个时刻(假如商城做活动,零点开始)key失效,那么零点之后对某一个商品查询请求将全都压到数据库上,导致数据库崩。
对于第二个原因,因为内存是有限的,要时时刻刻缓存新的数据,淘汰旧的数据,所以在一定的页面置换策略(常见页面置换算法图解)中,淘汰数据,如果某些商品做活动之前无人问津,势必会被淘汰。
应对击穿的处理思路
正常的处理请求如图:
由于key过期在所难免,高流量来到Redis时,根据Redis的单线程特性,可以认为任务是在队列里依次执行的,当请求到达Redis发现Key过期时,进行一个操作: 设置锁
这个流程大概如下:
- 请求到达Redis,发现Redis Key过期,查看有没有锁,没有锁的话回到队列后面排队
- 设置锁,注意,这儿应该是setnx(),而不是set()