缓存穿透
很多项目在使用Redis或其他缓存框架的时候,都是先查询缓存,查询不的话再查询数据库,查到之后再放到内存中;如果一个key值本身就不存在,那么每一次都会查询数据库,也就是常说的【缓存穿透】。
应对方法:
-
如果在Redis中查询不到,并且查询数据库也没有结果,那么就将这个key写入到Redis中,value=空,并设置一个超时过期时间,例如五分钟,那么五分钟以内的对这个可以的所有查询就可以拦截下来,如果数据库有key对应的数据了,那么五分钟后Redis中的缓存过期,会访问数据库并加载缓存;但是如果被恶意攻击,每次请求的key都不相同且不存在,那么依然会穿透到数据库;
-
布隆过滤器:将可能存在的数据Hash到一个足够大的bitmap上,它可以告诉你 “某个key一定不存在或者可能存在”,一个一定不存在的数据会被bitmap拦截。
缓存雪崩
很多时候,Redis中的缓存是要设置过期时间的,假如Redis中的数据,过期时间都设置成一样的,那么到了时间之后,全部缓存过期失效,下一秒所有的请求都会访问数据库,那么数据库可能因为访问量多大导致“崩溃”,这就是缓存雪崩。
应对方法:
-
最暴力的解决办法,缓存不设置自动过期时间,只要缓存不崩,数据库就不会崩。
-
另外一个办法,就是让缓存过期时间不那么一致,比如一批缓存数据24小时后过期,那么就在这个基础上,每条缓存的过期时间前后随机1-6000秒(1-10分钟)。
缓存并发
大多数时候,我们的程序访问Redis都不可能是单线程,那么当多个Client并发对Redis进行set key操作的时候,可能会产生一些问题;其实Redis本身是单线程的,这种时候会按照先后顺序进行操作;或者把操作放在队列中,按顺序执行;
但比如这种情况:
-
token过期,有两个线程都去重新获取token;
-
线程1获取token1;
-
线程2获取到token2,此时token1过期;
-
线程1把token1放到Redis,再拿着token1去调用服务,发现过期了,继续去请求token3,此时token2过期;
-
线程2把token2放到Redis,再拿着token2去调用服务,发现过期了,继续去请求token4,此时token3过期;
-
... ...
这就需要我们在更新缓存的时候,做一些控制了。
我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。
海量数据下如何正确访问Redis服务才不会挂掉?
Redis是啥?
在Java高级里经常见,但是我才学到框架,所请问以Redis是啥,干啥用的?
想要了解Redis,先从Redis是什么?为何要用Redis?有哪些特性,以及其集群架构来几个方面来了解。
Redis 简介
Redis 是一个开源(BSD 许可)的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
为什么要用 Redis
在高并发场景下,如果需要经常连接结果变动频繁的数据库,会导致数据库读取及存取的速度变慢,数据库压力极大。因此我们需要通过缓存来减少数据库的压力,使得大量的访问进来能够命中缓存,只有少量的需要到数据库层。由于缓存基于内存,可支持的并发量远远大于基于硬盘的数据库。所以对于高并发设计,缓存的设计是必不可少的一环。而 Redis 作为比较热门的内存存储系统之一,由于其对数据持久化的支持,种类丰富的数据结构,使其定位更倾向于内存数据库,适用于对读写效率要求都很高、数据处理业务复杂和对安全性要求较高的系统。
Redis 特征
- 单线程,利用 redis 队列技术将访问变为串行访问,消除了传统数据库串行控制的开销。
Redis 的线程模型:
- Redis 支持数据的持久化,包括 RDB 的全量持久化,或者 AOF 的增量持久化,从而使得
Redis 挂了,数据是有机会恢复的。也可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
- 分布式架构,读写分离。
- 支持的数据结构丰富。Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list、
set、zset、hash 等数据结构的存储。
- Redis 支持数据的备份,提供成熟的主备同步,故障切换的功能,从而保证了高可用。
Redis Cluster 架构
Redis 搭建方式有很多种,本章主要介绍 Redis Cluster 集群构建方式:Redis 3.0 之后版本支持 Redis Cluster 集群,Redis Cluster 采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。Redis Cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的 SORT 就可以由从服务器来承担。Redis 的主从同步是异步进行的,这意味着主从同步不会影响主逻辑,也不会降低 redis 的处理性能。主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能。在主从架构中,从服务器通常被设置为只读模式,这样可以避免从服务器的数据被误修改。