为了演示缓存穿透,这里设置的redis是单机单实例。
布隆过滤器能够迅速判断一个元素是否存在于集合里。
布隆过滤器缺点:
1.会有1%的误判率,误判概率越低,数组所占用的空间越长。
2.布隆过滤器的数据只能添加,不能移除,主要是由于多个数据可能存在于同一个位置,比如subCat:2、subCat:3。
3.维护起来比较麻烦,代码复杂。
1.什么是缓存雪崩?
当在同一时刻缓存里有大量的key过期时间结束,此时有大量过期的key请求,这时就会有大量的请求落到数据库,数据库承载不了这么大的数据访问,就会宕机。
2.雪崩预防
对于雪崩来说,我们不可能完全解决,只能对它预防,缓解雪崩的现象
预防方法如下:
(1)永不过期
(2)过期时间错开
比如热点数据可以把过期时间设置久一点,或者永不过期;其他不长访问的数据的过期时间设置短一点;在设置过期时间时,比如设置1小时过期,精确到毫秒就是1*60*60*1000,那么就可以在1分钟之内(60*1000)取随机数,每次在1小时的基础上加或减随机数。
(3)多缓存结合(多级缓存)
Memcache中的key过期时间设置的比redis的过期时间长,这样的话,redis中的key过期了就会去查Memcache
(4)采购第三方Redis
第三方服务还是很牛的,不用自己维护,减少运维成本。
阿里云Redis
HA:就相当于哨兵形式,SlaveN:有很多slave节点,都是哨兵模式
穿透是单个的key不存在于redis,雪崩是指大面积的key失效;两者都是由于超高流量的并发打在数据库上,造成数据库不可用。
每次get查询,其实就是建立一个连接,等get之后,再关闭连接。(socket通信),这样是会有IO损耗的,我们实现mget,这样对于批量查询,只建立一次连接。
/** * 批量查询,对应mget * @param keys * @return */ public List<String> mget(List<String> keys) { return redisTemplate.opsForValue().multiGet(keys); }
除了用mget批量查询,还可以用管道。
就如keepalive对nginx的作用:建立一次连接,pipeline对redis的作用也是建立一次连接,可以在管道内部进行很多类型的操作,如get,mget,range,set,mset等
/** * 批量查询,管道pipeline * @param keys * @return */ public List<Object> batchGet(List<String> keys) { // nginx -> keepalive // redis -> pipeline List<Object> result = redisTemplate.executePipelined(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { StringRedisConnection src = (StringRedisConnection)connection; for (String k : keys) { src.get(k); } return null; } }); return result; }
为什么实现了mget方法,还要实现pipeline方法批量查询?
因为pipeline支持更多类型的操作,set,get,mget,mset,range等,不仅仅支持String类型,其他类型也支持。