文章目录
- 导读
- 为什么redis会开小差?
- 1.连接数过多
- 2.bigkey
- 3.慢命令操作
- 4.内存策略不合理
- 5.外部数据双写一致性
- 6.保护机制未开启
- 7. 数据集中过期
- 8. CPU饱和
- 9. 持久化阻塞
- 10. 网络问题
- 结论
导读
提起分布式缓存,想必大多数同学脑海中都会浮出redis这个名字来……但是,对于它,你真的玩转了吗?为什么你的redis会慢,会卡顿,会崩溃?现在带你一探究竟。
为什么redis会开小差?
本文主要简要介绍redis使用过程中可能遇到的一些意外情况,只讲原因,并不过多分析细节,对于细节问题,读者可自行查询相关资料。
1.连接数过多
- 限制了redis最大连接数(maxclients),高并发场景下,达到该值,那么新的请求无法获取连接执行读写操作
- 没有限制,那么连接数在达到5000以上时(2g4c),可能影响到性能,在更高请求或更低配置机器情况下,数据会更低
针对这种情况,建议开启限制最大连接数,同时预估客户端数量,控制好连接参数;同时需要确认请求操作后所使用的连接是否被释放的问题。
2.bigkey
如果一个key的value过大,则被称为大key。主要包括:
- 单个简单的key存储的value很大
- hash, set,zset,list 中存储过多的元素(以万为单位)
若单key过大,读写频繁,那么数据读写中的序列化、网络传输等本身就是瓶颈点。
3.慢命令操作
- 危险命令:keys。执行全量扫描,在数据量大的场景下,将引起整个redis阻塞
- O(N)命令:hgetall、lrange、smembers、zrange、sinter、hkeys、hvals等,慎用。如需要使用,提前预估数据,一般认为应该控制在元素量控制在5K以内,如果的确过大,则需要根据实际机器配置评估验证。
- monitor命令:主要用于debug使用,生产环境长时间开启对性能有较大影响
4.内存策略不合理
在redis.conf中有一行配置,关于内存淘汰策略的说明
maxmemory-policy volatile-lru
当redis占用达到指定的maxmemory值时,会触发redis部分key的移除以释放内存。
- 如果选择不当的策略,可能会造成部分key被除后读不到引发意外。
- 如果选择策略noeviction,不会释放内存,但是对于写操作会提示错误。
- 如果读写并发高,可能出现频繁的内存释放,导致系统卡顿。
遇到报错或者获取key内容丢失,未必是redis故障,因为也这是一种自我保护机制。
5.外部数据双写一致性
在分布式的环境下,数据库和缓存双写,存在一致性问题,如果要求强一致性,那么redis会受到db的影响造成瓶颈。此时一般建议走最终一致,通过异步(如消息队列)方式来实现。需要站在架构设计的角度来对待redis的使用。
6.保护机制未开启
redis有一种保护机制,默认情况下是开启的。但有些时候为了图方便,没有开启该机制,同时将redis暴露于公网,此时容易受到外部攻击,导致redis甚至操作系统不可用。在生产环境还是要有提高安全的意识。
7. 数据集中过期
Redis的主动过期的定时任务,也是在Redis主线程中执行的,如果出现了需要大量删除过期key的情况,那么主线程会出现阻塞(最大25s)。而且这个访问延迟的情况,不会记录在慢日志里。
解决方案是,在集中过期时增加一个随机时间,把这些需要过期的key的时间打散即可。
8. CPU饱和
对于这种情况,首先判断当前Redis的并发量是否达到极限,建议使用统计命令redis-cli-h{ip}-p{port}–stat获取当前 Redis使用情况。对于并发量达到极限这种情况,我们需要做集群化水平扩展来分摊OPS压力。如果没有低并发就接近CPU饱和是很不正常的,有可能使用了高算法复杂度的命令。还有一种情况是过度的内存优化,需要我们根据infocommandstats统计信息分析出命令不合理开销时间(比如上万个元素却采用ziplist编码,虽然hash结构内存占用会变小,但是操作变得更慢且更消耗CPU)
9. 持久化阻塞
持久化引起主线程阻塞的操作主要有:fork阻塞、AOF刷盘阻塞、 HugePage写操作阻塞。
HugePage写操作阻塞:子进程在执行重写期间利用Linux写时复制技术降低内存开销,因此只有写操作时Redis才复制要修改的内存页。对于开启Transparent HugePages的 操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。例如简单的incr命 令也会出现在慢查询中。
10. 网络问题
可能有这三种情况:网络闪断、Redis连接拒绝、连接溢出。
Redis连接拒绝。Redis通过maxclients参数控制客户端最大 连接数,默认10000。
连接溢出。这是指操作系统或者Redis客户端在连接时的问题。这个问题的原因比较多,比如进程限制、 backlog队列溢出。
如何快速定位慢的原因?
常用工具,redis内部命令如info、slowget慢查询,内存分析排查可参考redis-rdb-tool等。当然,完善的监控系统能让我们更快,更准地解决,这里建议telegraf+influxdb+grafana组合实现图形化监控预警。
结论
对于使用不当引起的风险操作,需要对症下药。2.对于海量数据、高并发这种的确因为正常需求引起的资源不足问题的场景,就需要考虑扩容的方式来解决。3.做好准备工作、善用工具、建立监控预警机制,将使你对redis的维护工作事半功倍。