为什么要设置缓存:
有海量并发的业务场景需要,大量的请求涌入关系型数据库,基于磁盘的IO读取效率低下,常用的mysql数据库不易进行扩展维护,容易造成数据库崩溃,从而相关业务崩溃,系统崩溃。
因此我们需要去减少IO的读取次数,增强数据库的可拓展性和可维护性,Nosql数据库就可以更好的完成集群的拓展。通过多级缓存的设计,减少直接访问数据库的次数,减少IO操作,提升系统的健壮性。
redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。
在此,将讨论常用于数据缓存的redis的业务场景,面临的问题,及解决方案。
缓存雪崩
概念: 指大量Key 同时失效,业务的访问直接涌向数据库,大量的访问造成数据库的崩溃,从而业务崩溃,系统崩溃。
解决方案:
1 给不同的Key 设置不同的TTL时间,避免大量的key 同时失效,尽量减少大量请求同时涌入数据库,面对热点数据,也可以将剩余时间设为-1,即永久保存。
2 对集群做水平的拓展,Redis数据库相比于Mysql极易于进行集群的水平拓展,将数据分开存储,或备份存储在不同的集群服务上,可以避免服务器崩溃而造成缓存失败,请求涌入数据库。
3 设置多级缓存,更多的缓存逻辑去拦截请求直接进入数据库,减少IO 的读取次数。
4 给缓存业务添加降级限流策略
缓存击穿
缓存击穿问题,也被称为热点key问题,是指缓存中没有但数据库中有的数据(一般是缓存时间到期),此时由于并发用户过多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
所以解决该问题的逻辑就是
1 在第一次访问到缓存中该key失效时,阻断后续对该key的访问,减少热点key失效而造成的大量请求直接涌入数据库
2 将该热点Key永久保存于缓存之中,但是设置逻辑过期来保证数据的有效性与真实性。
阻断后续请求的解决方案: 互斥锁
解决方案二:逻辑过期
即永久的保存该数据,但设置一些逻辑,经过一段时间去对数据进行校准和更新,通过异步的方式去更新数据,可以很好的解决缓存击穿的问题,唯一的不足时,在逻辑过期更新的时间段内,这些少量用户请求到的数据为脏数据。
缓存穿透:
解决方案一:
缓存空对象的方式,即第一次访问该key时从redis中没有查到该数据,再去数据库中访问也没有查找到该数据,这是就通过业务逻辑,去在redis中给该key存储一个空对象,后续每次请求该数据,直接从redis中返回该空对象,避免对数据库的持续访问造崩溃。
解决方案二:
布隆过滤器:本质上是一个超大的二维数组,通过哈希思想去对数据进行判断,认为存在该Key的值,则放行该请求继续访问缓存与数据库,认为没有则则返回该访问请求。但是因为哈希思想的原因,就会不可避免的存在 哈希冲突,造成错误的放行。