大key
- string 类型的 value 超过 1MB
- 复合类型(列表、哈希、集合、有序集合等)的 value 包含的元素超过 5000 个(对于复合类型的 value 来说,不一定包含的元素越多,占用的内存就越多)。
大 key 造成的阻塞问题如下:
- 客户端超时阻塞:由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
- 引发网络阻塞:每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
- 阻塞工作线程:如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
集群扩容
Redis 集群可以进行节点的动态扩容缩容,这一过程目前还处于半自动状态,需要人工介入。
扩缩容时,需要进行数据迁移。为了保证迁移的一致性,迁移所有操作都是同步操作。
执行迁移时,两端的 Redis 均会进入时长不等的阻塞状态,对于小 Key,时间可以忽略不计,对于大 Key ,严重时会触发集群内的故障转移,造成不必要的切换。
Swap(内存交换)
内存不足把一部分硬盘空间虚拟成内存使用。
内存与硬盘的读写速度差几个数量级, Redis 性能急剧下降。
识别 Redis 发生 Swap 的检查方法如下:
1、查询 Redis 进程号
redis-cli -p 6383 info server | grep process_id
process_id: 4476
2、根据进程号查询内存交换信息
cat /proc/4476/smaps | grep Swap
Swap: 0kB
Swap: 0kB
Swap: 4kB
Swap: 0kB
Swap: 0kB
.....
如果交换量都是 0KB 或者个别的是 4KB,则正常。
预防内存交换的方法:
- 保证机器充足的可用内存
- 确保所有 Redis 实例设置最大可用内存(maxmemory),防止极端情况 Redis 内存不可控的增长
- 降低系统使用 swap 优先级,如
echo 10 > /proc/sys/vm/swappiness
CPU竞争
Redis 是典型的 CPU 密集型应用,不建议和其他多核 CPU 密集型服务部署在一起。当其他进程过度消耗 CPU 时,将严重影响 Redis 的吞吐量。
可以通过redis-cli --stat
获取当前 Redis 使用情况。通过top
命令获取进程对 CPU 的利用率等信息 通过info commandstats
统计信息分析出命令不合理开销时间,查看是否是因为高算法复杂度或者过度的内存优化问题。
网络问题
连接拒绝、网络延迟,网卡软中断等网络问题也可能会导致 Redis 阻塞。