数据库缓存简介
缓存应该都知道吧,就用MySQL和Redis举例,一般来说MSQL是用来做数据持久化的,在大多数实际情况下是对库中数据的进行读写操作,但是如果每次都去MySQL中读取,不用想,这肯定是非常恰资源的一个操作,所有就有了缓存这么个东西。
MySQL是自带缓存的一级缓存默认开启,二级需要手动开启,但是在访问量大的情况下,自带的缓存肯定是遭不住的,于是Redis就站出来了,Redis用C语言编写,基于内存,就非常的快(为了快,事务过程中即使有地方失败了都不会回滚,别问为什么,问就是快),可以把经常查询但又不经常改变的数据放在Redis中这样就不用每次读取数据都去MySQL,大大缓解了数据库的压力。
问题也随之而生
1.缓存穿透
当一个缓存中没有的数据被请求的时候,就会直接去数据库中查询,数据库中也没有该数据,此次就查询失败了,当这个不存在的数据被多次请求是,数据库的压力就会骤增,此时,这种情况叫做缓存穿透。
解决方案:
1.接口整个查询字段的校验,过滤一下非法请求。
2.记录下查询的key,在缓存中设置vlaue为null(记得设置一个有效时间,避免后面的数据写入出现问题)。
3.布隆过滤器(只能缓解,并且这玩意是有误判性的)
3.布谷鸟过滤器(原理和布隆过滤器差不多)
2.缓存击穿
当有一些数据在数据库是存在的,但是在缓存中不存在(一般是缓存的有效时间到期了),刚好这个时候有大量用户请求这个在缓存中失效的数据(缓存:md,早干什么去了,失效了才来),就会直接去数据库中获取,也会造成数据库的压力增大,甚至宕机
解决方案:
1.设置经常查询不经常改变的数据(热点数据)永不过期。
2.数据预热,把经常查询的数据事先添加进缓存中。
4.加互斥锁(一个数据只能被一条线程操作,性能问题可以看看这一篇(互斥锁对程序性能的影响.)。
3.缓存雪崩
缓存中大批量数据过期,这时等于缓存失效了,大批量的请求直接涌入数据库,你懂的。(缓存击穿指并发查同一条数据,而雪崩是大批量不同的数据都过期了,区别就是多和少)
解决方案:
1.设置经常查询不经常改变的数据(热点数据)永不过期。
2.缓存中数据的过期时间尽量分布均匀,不要太过一致防止大量数据同时过期。
3.如果有分布式部署就把热点数据均匀分布在不同的缓存数据库中(本质还是数据预热)。