Redis
缓存是解决分布式系统时效问题的一枚银弹,可惜这世上根本就没有什么真正的银弹,任何一种中间件的引入都会带来系统复杂性,这不它就带来了,雪崩、穿透和击穿.
雪崩
- redis无,数据库有
“当雪崩发生的时候,没有一片雪花是无辜的”,这句话很贴切。在双十一这天,马云让玄武做个淘宝首页,玄武写了个小程序把数据都放到redis中缓存,设置2小时过期; 过了2个小时激烈的购买以后,热度不减,但是redis中的数据,短期内都失效了。 用户的请求,向一片片雪花一样,直接打在了数据库上,打的数据库 喘不过气,虽然一片雪花力量有限,无奈抵不过人多,数据库就这样挂了。 这种大量的redis缓存短期内同时失效而导致的数据请求打到数据库的问题,就是雪崩
解决办法:经过一份分析以后,玄武痛定思痛, 在设置 首页数据进redis的时候,对不同商品设置了 随机过期时间,这样,雪花一片一片打到数据库上来,数据库消灭它们,像玩似的。 还有,设置永不过期的缓存、定时更新过期数据 等方法
穿透
- redis无、数据库无
隔壁老王,看着马云的淘宝生意这么好,心里起了坏主意,他想把系统搞坏,苦思冥想,终得一法 他写了个爬虫软件,开启了n个线程,疯狂的查询一件不存在的商品(id<0的数据),玄武的redis中没查到这件商品,直接到数据库中查询,也有这件商品。然后这个讨厌的查询疯狂的请求,数据库应接不暇,卒;
这种大量查询原本就不存在的数据问题导致的数据看压力问题,称为缓存穿透
解决办法:玄武苦思冥想后,想到 可以用一把分布式锁,当redis中查询不到的时候,先去获取一把对这件商品的查询锁,这样就控制了 只会有一个线程在查询 某件商品。 隔了两天以后,玄武又想到,这种方法可以防止不停地查询某件不存在的商品,可如果那个坏蛋用很多不同假商品来查,咋办?于是进行了升级,使用布隆过滤器,先判断数据是否存在,不存在就直接返回,存在的话,再去数据库中查询。 另外:还可 每次查出 空值,也缓存到redis中
击穿
- redis无、数据库有
双十二来了,马爸爸像搞个营销,拍卖自己午餐机会,玄武 把马爸爸的的午餐活动上架,缓存到了redis中,设置了4小时过期,可万万没想到,拍卖太火了,4小时过去了,依然么有结束。 刷的一下,所有的请求 同时抵达了数据库,这个查询,就像一把利剑,直接击穿了数据库
这种由于某个热键在缓存中突然失效,导致大量请求直接打到数据库上的问题,就是数据库击穿
解决办法:可以用一把分布式锁,当redis中查询不到的时候,先去获取一把对这件商品的查询锁,这样就控制了 只会有一个线程在查询 某件商品。当查询到数据以后,再放到redis中去。其他线程获取到锁以后,再去redis中查询,即可查到数据。