-
自身因素
- api或数据结构使用不合理:例如对一个上万元素的hash结构执行hgetall操作,数据量造成堵塞。
- 慢查询
- 大对象
a. 数据库清零过后执行redis-cli --bigkeys命令的执行结果,系统没有查询到大的对象
127.0.0.1:6379> flushall OK 127.0.0.1:6379> [root@localhost etc]# redis-cli --bigkeys # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). -------- summary ------- Sampled 0 keys in the keyspace! Total key length in bytes is 0 (avg len 0.00) 0 strings with 0 bytes (00.00% of keys, avg size 0.00) 0 lists with 0 items (00.00% of keys, avg size 0.00) 0 sets with 0 members (00.00% of keys, avg size 0.00) 0 hashs with 0 fields (00.00% of keys, avg size 0.00) 0 zsets with 0 members (00.00% of keys, avg size 0.00) [root@localhost etc]#
写入数据,执行大对象查询命令,发现String类型name为当前最大对象,确定了大对象,这样我们可以对它进行调整或缩减,分成多个小对象
[root@localhost etc]# redis-cli 127.0.0.1:6379> set name itxds OK 127.0.0.1:6379> exit [root@localhost etc]# redis-cli --bigkeys # Scanning the entire keyspace to find biggest keys as well as # average sizes per key type. You can use -i 0.1 to sleep 0.1 sec # per 100 SCAN commands (not usually needed). [00.00%] Biggest string found so far 'name' with 5 bytes -------- summary ------- Sampled 1 keys in the keyspace! Total key length in bytes is 4 (avg len 4.00) Biggest string found 'name' has 5 bytes 1 strings with 5 bytes (100.00% of keys, avg size 5.00) 0 lists with 0 items (00.00% of keys, avg size 0.00) 0 sets with 0 members (00.00% of keys, avg size 0.00) 0 hashs with 0 fields (00.00% of keys, avg size 0.00) 0 zsets with 0 members (00.00% of keys, avg size 0.00)
b.生产环境查看key对应value序列化后的长度
生产环境执行debug object key 查看key对应value序列化后的长度,或strlen key查看key的字节数
c.info commandstats 命令分析命令不合理的开销时间,返回最近执行命令的调用次数,耗时信息
CPU饱和:redis单线程只能用一个CPU,饱和将无法处理更多命令 可以执行命令redis-cli -h{ip} -p{port} --stat 获取当前redis使用情况
[root@localhost etc]# redis-cli --stat ------- data ------ --------------------- load -------------------- - child - keys mem clients blocked requests connections 1 808.23K 1 0 140 (+0) 10 1 808.23K 1 0 141 (+1) 10 1 808.23K 1 0 142 (+1) 10 1 808.23K 1 0 143 (+1) 10 1 808.23K 1 0 144 (+1) 10
2.持久化造成阻塞
a.fork阻塞:fork操作做法神挂在RDB和AOF重写,redis主线程调用fork操作产生共享内存的子进程,柚子进程完成持久化操作,如果fork操作本身耗时过长,将导致主进程阻塞,可以执行info stats命令获取到latest_fork_usec指标,表示最近一次fork操作的耗时,若操作1s则需优化。
b.aof刷盘阻塞:当开启aof持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对aof文件做fsync操作,硬盘压力过大时,fsync操作需要等待,直到写入完成如果主线程发现距离上一次的fsync成功超过2秒,为了数据安全性它会阻塞直到后台线程执行fsync操作完成,这种阻塞行为主要是硬盘压力引起,可查看Redis日志识别出这种情况,当发生这种阻塞行为时。
b.aof刷盘阻塞: 当开启aof持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对aof文件做fsync操作,硬盘压力过大时,fsync操作需要等待,直到写入完成如果主线程发现距离上一次的fsync成功超过2秒,为了数据安全性它会阻塞直到后台线程执行fsync操作完成,这种阻塞行为主要是硬盘压力引起,可查看Redis日志识别出这种情况,当发生这种阻塞行为时,会打印如下日志:
亦可查看info persistence统计中的aof_delayed_fsync指标,每次发生aof刷盘阻塞主线程时会累加。
c.HugePage写操作阻塞(求大佬指教): 子进程在执行重写期间利用Linux写时复制技术降低内存开销,因此只有写操作时Redis才复制要修改的内存页,对于开启Transparent HugePages的操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512倍,会拖慢写操作的执行时间,导致大量写操作慢查询。
3.外因素
A.CPU竞争
a.进程竞争:当redis与其他cpu密集型服务部署在一起时可能发生
b.绑定cpu:由于redis单线程架构,为充分利用多核cpu,一台机器部署多个redis并将redis进程绑定到cpu(可降低cpu上下文切换开销),当redis父进程fork操作创建子进程进行rdb/aof重写(很耗cpu) 时,父子进程共享同一cpu,将影响redis的稳定性
B.内存交换:指操作系统把redis使用的部分内存换出到硬盘,导致交换后redis性能急剧下降(内存与硬盘处理速度不在一个数量级),可如下查看内存交换信息获取redis进程号→cat /proc/进程号/smaps | grep Swap
C.网络问题:
1)连接拒绝:
a).网络闪段:网络割接或者带宽耗尽
b).连接拒绝:超过客户端最大连接数
c).连接溢出:指操作系统或redis客户端在连接时的问题,2种原因:
原因1:进程限制 操作系统会对进程使用的资源做限制,其中之一便是对可打开最大文件数进行控制,ulimit –n可查看,超过则发送too many open files错误
原因2:backlog队列溢出 系统对于特定端口的tcp连接使用backlog队列保存,redis默认长度为511,通过tcp-backlog参数设置,高并发场景下可增大该值,但必须大于操作系统允许值才生效,系统默认backlog为128,使用echo511>/proc/sys/net/core/somaxconn命令进行修改,可通过netstat -s命令获取因队列溢出造成的连接拒绝统计
2)网络延迟: 可使用redis提供的测试工具进行测试,在redis-cli -h {ip} -p {port}命令后加入参数进行测试:
--latency:持续进行延迟测试,分别统计:最小值、最大值、平均值、采样次数
--latency-history:统计结果同—latency,但默认每15秒完成一行统计,可通过-i参数控制采样时间
--latency-dist:使用统计图的形式展示延迟统计,每1秒采样一次
3)网卡软中断(求大佬指教):
网卡软中断是指由于单个网卡队列只能使用一个CPU,高并发下网卡数据交互都集中在同一个CPU,导致无法充分利用多核CPU的情况,网卡软中断瓶颈一般出现在网络高流量吞吐的场景
摘自大佬:https://www.cnblogs.com/linguoguo/p/12046548.html
C.网络问题:
1)连接拒绝:
a).网络闪段:网络割接或者带宽耗尽
b).连接拒绝:超过客户端最大连接数
c).连接溢出:指操作系统或redis客户端在连接时的问题,2种原因:
原因1:进程限制 操作系统会对进程使用的资源做限制,其中之一便是对可打开最大文件数进行控制,ulimit –n可查看,超过则发送too many open files错误
原因2:backlog队列溢出 系统对于特定端口的tcp连接使用backlog队列保存,redis默认长度为511,通过tcp-backlog参数设置,高并发场景下可增大该值,但必须大于操作系统允许值才生效,系统默认backlog为128,使用echo511>/proc/sys/net/core/somaxconn命令进行修改,可通过netstat -s命令获取因队列溢出造成的连接拒绝统计
2)网络延迟: 可使用redis提供的测试工具进行测试,在redis-cli -h {ip} -p {port}命令后加入参数进行测试:
--latency:持续进行延迟测试,分别统计:最小值、最大值、平均值、采样次数
--latency-history:统计结果同—latency,但默认每15秒完成一行统计,可通过-i参数控制采样时间
--latency-dist:使用统计图的形式展示延迟统计,每1秒采样一次
3)网卡软中断(求大佬指教):
网卡软中断是指由于单个网卡队列只能使用一个CPU,高并发下网卡数据交互都集中在同一个CPU,导致无法充分利用多核CPU的情况,网卡软中断瓶颈一般出现在网络高流量吞吐的场景
摘自大佬:https://www.cnblogs.com/linguoguo/p/12046548.html
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Redis阻塞原因 - Python技术站