主题
《面渣逆袭》Redis 篇 · 第 5/8 章。原版 PDF(下载 / 打印)
34.Redis报内存不足怎么处理?
Redis 内存不足有这么几种处理方式:
修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存也可以通过命令setmaxmemory 动态设置内存上限修改内存淘汰策略,及时释放内存空间使用 Redis 集群模式,进行横向扩容。
35.Redis的过期数据回收策略有哪些?
Redis 主要有2 种过期数据回收策略:

惰性删除
惰性删除指的是当我们查询k ey 的时候才对k ey 进行检测,如果已经达到过期时间,则删除。显然,他有一个缺点就是如果这些过期的k ey 没有被访问,那么他就一直无法被删除,而且一直占用内存。
定期删除
定期删除指的是Redis 每隔一段时间对数据库做一次检查,删除里面的过期k ey 。由于不可能对所有k ey去做轮询来删除,所以Redis 会每次随机取一些k ey 去做检查和删除。
36.Redis有哪些内存溢出控制/内存淘汰策略?
Redis 所用内存达到maxmemory 上限时会触发相应的溢出控制策略,Redis 支持六种策略:

- noeviction :默认策略,不会删除任何数据,拒绝所有写入操作并返 回客户端错误信息,此 时
Redis 只响应读操作。
2.volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直 到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction 策略。
allkeys-lru :根据LRU 算法删除键,不管数据有没有设置超时属性, 直到腾出足够空间为止。
allkeys-random :随机删除所有键,直到腾出足够空间为止。
5.volatile-random:随机删除过期键,直到腾出足够空间为止。
6.volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果 没有,回退到noeviction策略。
37.Redis阻塞?怎么解决?
Redis 发生阻塞,可以从以下几个方面排查:

API 或数据结构使用不合理
通常Redis 执行命令速度非常快,但是不合理地使用命令,可能会导致执行速度很慢,导致阻塞,对于高并发的场景,应该尽量避免在大对象上执行算法复杂 度超过O (n )的命令。
对慢查询的处理分为两步:
发现慢查询: slowlogget{n} 命令可以获取最近 的n 条慢查询命令;
发现慢查询后,可以从两个方向去优化慢查询:
修改为低算法复杂度的命令,如hgetall 改为hmget 等,禁用keys 、sort 等命 令
调整大对象:缩减大对象数据或把大对象拆分为多个小对象,防止一次命令操作过多的数
据。
CPU 饱和的问题
单线程的Redis 处理命令时只能使用一个CPU 。而CPU 饱和是指Redis 单核CPU 使用率跑到接近100% 。
针对这种情况,处理步骤一般如下:
- 判断当前Redis 并发量是否已经达到极限,可以使用统计命令redis-cli-h{ip}-p{port}--stat
获取当前 Redis 使用情况
- 如果Redis 的请求几万+ ,那么大概就是Redis 的OPS 已经到了极限,应该做集群化水品扩展
来分摊OPS 压力
- 如果只有几百几千,那么就得排查命令和内存的使用
持久化相关的阻塞
对于开启了持久化功能的Redis 节点,需要排查是否是持久化导致的阻塞。
- fork 阻塞
fork 操作发生在RDB 和AOF 重写时,Redis 主线程调用fork 操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork 操作本身耗时过长,必然会导致主线程的阻塞。
- AOF 刷盘阻塞
当我们开启AOF 持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对AOF 文件做fsync 操作。当硬盘压力过大时,fsync 操作需要等 待,直到写入完成。如果主线程发现距离上一次的fsync 成功超过2 秒,为了 数据安全性它会阻塞直到后台线程执行fsync 操作完成。
- HugePage 写操作阻塞
对于开启Tr ansparentHugePages 的 操作系统,每次写命令引起的复制内存页单位由4 K 变为2 MB ,放大了5 12 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。
38.大key问题了解吗?
Redis 使用过程中,有时候会出现大k ey 的情况, 比如:
单个简单的k ey 存储的value 很大,size 超过1 0KB
hash , set ,zset ,list 中存储过多的元素(以万为单位)
大k ey 会造成什么问题呢?
客户端耗时增加,甚至超时对大k ey 进行IO操作时,会严重占用带宽和CPU造成Redis 集群中数据倾斜主动删除、被动删等,可能会导致阻塞
如何找到大k ey?
bigkeys 命令:使用bigkeys 命令以遍历的方式分析Redis 实例中的所有K ey ,并返回整体统计信息与每个数据类型中To p1 的大K ey
redis-rdb-tools :redis-rdb-tools 是由Python 写的用来分析Redis 的r db 快照文件用的工具,它可以把r db 快照文件生成json 文件或者生成报表用来分析Redis 的使用详情。
如何处理大k ey?

删除大k ey
当Redis 版本大于4 .0 时,可使用UNLINK 命令安全地删除大K ey ,该命令能够以非阻塞的方式,逐步地清理传入的K ey 。
当Redis 版本小于4 .0 时,避免使用阻塞式命令KEYS ,而是建议通过SCAN 命令执行增量迭代扫描k ey ,然后判断进行删除。
压缩和拆分k ey
当vaule 是string 时,比较难拆分,则使用序列化、压缩算法将k ey 的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
当value 是string ,压缩之后仍然是大k ey ,则需要进行拆分,一个大k ey 分为不同的部分,记录每个部分的k ey ,使用multiget 等操作实现事务读取。
当value 是list/set 等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。
39.Redis常见性能问题和解决方案?
- Master 最好不要做任何持久化工作,包括内存快照和 AOF 日志文件,特别是不要启用内存快照
做持久化。
如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。
尽量避免在压力较大的主库上增加从库。
Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存
资源,导致服务 load 过高,出现短暂服务暂停现象。
- 为了 Master 的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关为:
Master< – Slave1< – Slave2< – Slave3 …,这样的结构也方便解决单点故障问题,实现 Slave 对
Master 的替换,也即,如果 Master 挂了,可以立马启用 Slave1 做 Master ,其他不变。