redis超时原因排查

孤街浪徒 提交于 2019-11-27 11:03:56

1.低效操作产生的延迟。单命令操作一半很快不会造成这样,SORT,LREM, SUNION,keys ,* 等操作都会影响响应时间。

 

使用进程监控程序(top, htop, prstat, 等...)来快速查看Redis进程的CPU使用率。如果traffic不高而CPU占用很高,八成说明有慢操作。(top -p pid)

 

slowlog 查询引发延迟的慢命令:(默认超过10毫秒就算慢命令) 只针对慢命令进行统计

 

slowly get 10 查看前十条慢命令

 

config get slowlog-log-slower-than  设置慢命令时间(默认10000us) 10ms

 

2.客户端连接数量,默认为10000 ,超过5000就会影响性能

 

3.客户端连接数的限制

 

4.加强内存管理

 

5.命令处理总数的影响:total_commands_processed

 

6.延迟命令查询:

 

文中出现的延迟(latency)均指从客户端发出一条命令到客户端接受到该命令的反馈所用的最长响应时间

 

redis-cli --latency -h host -p port 

 

7.网络和通信引起的延迟

 

当用户连接到Redis通过TCP/IP连接或Unix域连接,千兆网络的典型延迟大概200us,而Unix域socket可能低到30us。这完全基于你的网络和系统硬件。在通信本身之上,系统增加了更多的延迟(线程调度,CPU缓存,NUMA替换等等)。系统引起的延迟在虚拟机环境远远高于在物理机器环境。

 

8.redis使用优化

 

客户机和服务器之间的交互也必然消耗系统相关的延迟,因此在使用redis操作时可以通过捆绑多个命令在一起的方式减少客户端和服务端的交互次数。聚合命令象MSET/MGET也可以用作这个目的。

 

9.不要经常的去进行连接与断开的操作,尤其是基于web的应用。

 

尽可能的延长与服务器连接的时间

 

10.swap到硬盘操作造成的延迟 /proc/pid

 

因为smaps文件包括有redis进程的多个不同的的内存映射区域的使用情况(进程的内存布局远不是线性排列那么简单)。

 

cat smaps | egrep '^(Swap|Size)' (grep -e ‘’ -e ‘’)

 

11.AOF 和硬盘I/O操作延迟

 

主redis不建议使用相关的持久化操作,

 

从redis建议打开aof操作

 

因为主从同步是将🐷的内存线dump出来后传给从,从进行内存中load。以后每次同步就是定期进行dump核load?

 

通过设置AOF相关的appendfsync项,可以使用三种不同的方式来执行文件同步(也可以在运行时使用CONFIG SET 命令来修改这个配置)。

 

- appendfsync 的值设置为no,redis不执行fsync。这种情况下造成延迟的唯一原因就是写操作。这种延迟没有办法可以解决,因为redis接收到数据的速度是不可控的,不过这种情况也不常见,除非有其他的进程占用I/O使得硬盘速度突然下降。

 

- appendfsync 的值设置为everysec,每秒都会执行fsync。fsync 由一个单独线程执行,如果需要写操作的时候有fsync正在执行redis就会用一个buffer来延迟写入2秒(因为在Linux如果一个fsync 正在运行那么对该文件的写操作就会被堵塞)。如果fsync 耗时过长(译者注:超过了2秒),即使fsync 还在进行redis也会执行写操作,这就会造成延迟。

 

- appendfsync 的值设置为always ,fsync 会在每次写操作返回成功代码之前执行(事实上redis会积累多个命令在一次fsync 过程中执行)。这种模式下的性能表现是非常差劲的,所以最好使用一个快速的磁盘和文件系统以加快fsync 的执行。

 

大多数redis用户都会把这个值设成 no 或者 everysec。要减少延迟,最好避免在同一个机器上有其他耗费I/O的程序。用SSD也有益于降低延迟,不过即使不使用SSD,如果能有冗余的硬盘专用于AOF也会减少寻址时间,从而降低延迟。

 

如果你想诊断AOF相关的延迟原因可以使用strace 命令:

 

sudo strace -p $(pidof redis-server) -T -e trace=fdatasync

 

12.数据过期造成的延迟

 

redis有两种方式来去除过期的key:

 

- lazy 方式,在key被请求的时候才检查是否过期。 to be already expired.

 

- active 方式,每0.1秒进行一次过期检查。

 

active过期模式是自适应的,每过100毫秒开始一次过期检查(每秒10次),每次作如下操作:

 

- 根据 REDIS_EXPIRELOOKUPS_PER_CRON 的值去除已经过期的key(是指如果过期的key数量超过了REDIS_EXPIRELOOKUPS_PER_CRON 的值才会启动过期操作,太少就不必了。这个值默认为10), evicting all the keys already expired.

 

- 假如超过25%(是指REDIS_EXPIRELOOKUPS_PER_CRON这个值的25%,这个值默认为10,译者注)的key已经过期,则重复一遍检查失效的过程。

 

REDIS_EXPIRELOOKUPS_PER_CRON 默认为10, 过期检查一秒会执行10次,通常在actively模式下1秒能处理100个key。在过期的key有一段时间没被访问的情况下这个清理速度已经足够了,所以 lazy模式基本上没什么用。1秒只过期100个key也不会对redis造成多大的影响。

 

总而言之: 要知道大量key同时过期会对系统延迟造成影响。

 

13.redis看门狗造成的延迟

 

CONFIG SET watchdog-period 200 记录延迟事件

 

redis 单实例最大并发据说可以达到写1w+/s,但是这是在本地操作redis,远程redis操作至少相差1/3的数据,因此线上业务现在最大也支持7k+每秒的读写操作以及。

 

那么如果并发上面没有问题,但是出现redis 的超时问题,就需要进行上面问题的排查啦。

 

reds的客户端连接数;top查看是否reds跑满了cpu;超时时间的设置(timeout/tcp-keepalive);网络延迟;数据量传输

 

测试qps/tps:

 

 /export/servers/redis-2.8.9/src/redis-benchmark -h 172.24.212.224 -p 6379 -c 50 -n 10000 -d 2

 

50个并发链接,10000个请求,每个请求2kb。算下来最终的QPS为59000/s

 

但是估计线上的redis真实的qps和tps是具体需要考虑到以下几个方面的:

 

1.估计生产的报文大小,使用-d模拟

 

2.使用redis-cli命令查看info total_commands_processed 信息.通过两次时间差进行计算QPS

 

注意:监控reis的每秒操作数

 

常用监控redis命令:

 

info commandstats 查看命令状态

 

persistence : RDB 和 AOF 的相关信息

 

stats : 一般统计信息

 

replication : 主/从复制信息

 

cpu : CPU 计算量统计信息

 

commandstats : Redis 命令统计信息

 

cluster : Redis 集群信息

 

keyspace : 数据库相关的统计信息

 

client list       列出当前连接的客户端

 

redis-cli info clients | grep connected_clients 查看客户端已连接个数

 

redis-cli info memory | egrep '(used_memory_human|used_memory_peak_human)'  查看当前使用内存量,和历史最高峰值

 

常用监控信息:

 

redis-cli -h 172.24.184.1 -p 6379 info stats | grep total_commands   查看启动到当前处理命令总数

 

redis-cli -h 172.24.184.1 -p 6379 info stats | grep instantaneous_ops_per_sec  每秒操作数

 

redis-cli -h 172.24.184.1 -p 6379 info stats |grep expired_keys                已过期的key数量

 

redis-cli -h 172.24.184.1 -p 6379 info stats |grep net_io_in_per_sec    每秒进出流量(70444byte)0.07M

 

redis-cli -h 172.24.184.1 -p 6379 info stats |grep net_io_out_per_sec

 

redis-cli -h 172.24.184.1 -p 6379 info memory | grep mem_fragmentation_ratio   内存碎片率(如果超大于1表示存在内存碎片/是used_memory_rss与used_memory的比值。小于1说明内存被交换到swap里面去了)

 

1.slowlog 查询引发延迟的慢命令:(默认超过10毫秒就算慢命令) 只针对慢命令进行统计

 

slowly get 10 查看前十条慢命令

 

config get slowlog-log-slower-than  设置慢命令时间(默认10000us) 10ms

 

2.客户端连接数量,默认为10000 ,超过5000就会影响性能

 

3.客户端连接数的限制

 

4.加强内存管理

 

5.命令处理总数的影响:total_commands_processed

 

6.延迟命令查询:

 

redis-cli --latency 

个人公众号,不定期更新技术文章:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!