Redis堵塞原因以及问题排查

尽管咱们在日常作业中经常运用Redis作为数据库的缓存,以大大减轻数据库压力并提升用户体会,但Redis也或许呈现堵塞状况,导致整个体系变慢,进而影响用户体会。

因而,在面临Redis堵塞的状况下,咱们能够从以下七个方面进行全面的剖析,以承认形成Redis堵塞的详细原因。

【Redis故障排查】「连接失败问题排查和解决」带你深入分析一下Redis阻塞原因以及问题排查方案指南

慢查询

因为Redis是单线程的,所以假如呈现很多的慢查询,或许会导致redis-server堵塞,能够经过slowlog get n 获取慢日志查看详细状况,如下所示。

> slowlog get 3
34
1688630099
14659
LPOP
Automatic:Plan:wait:RestoreList
192.168.0.168:17777
33
1688608199
12247
LPOP
Automatic:Plan:process:RestoreList
192.168.0.168:61399
32
1688562824
15059
LPOP
Automatic:Plan:process:RestoreList
192.168.0.168:56006

查看慢查询装备

在Redis中,慢查询日志是用来记载履行时刻超越阈值的指令的。能够经过装备慢查询相关的参数来操控记载的条件和日志的保存方位。

能够运用CONFIG GET slowlog-*指令来查看现有的Redis装备。这个指令用于获取Redis慢查询日志的相关装备。

CONFIG GET slowlog-*
slowlog-log-slower-than
10000
slowlog-max-len
128

运用CONFIG GET slowlog-*指令能够获取与慢查询日志有关的装备项及其对应的值。该指令会返回一个列表,列表中包含了以slowlog-*最初的装备项的称号和对应的值。

参数介绍剖析

  • slowlog-log-slower-than是Redis的一个装备项,用于设置慢查询日志的阈值。它表明履行时刻超越该阈值的指令会被记载到慢查询日志中。在您供给的示例中,slowlog-log-slower-than被装备为10000,单位是微秒(s),即10毫秒。

这意味着当一个指令的履行时刻超越10毫秒时,它将被Redis记载到慢查询日志中。

  • slowlog-max-len是Redis的另一个装备项,表明慢查询日志的最大长度。它决议了慢查询日志中能够保存的记载数量。在您供给的示例中,slowlog-max-len被装备为128,即最多保存128条慢查询日志记载。

当慢查询日志中的记载到达最大长度后,新的慢查询会替换掉最旧的记载。

经过装备这些参数,您能够依据实际需求,灵敏地设置Redis的慢查询日志的阈值和最大长度。这样能够协助您及时发现影响功能的慢查询操作,并对其进行优化。

留意,履行CONFIG GET slowlog-*指令需求具有访问Redis装备的权限。假如您没有对应的权限,将无法履行该指令。

bigkey大目标

大目标(bigkey)或许导致以下问题:

【Redis故障排查】「连接失败问题排查和解决」带你深入分析一下Redis阻塞原因以及问题排查方案指南

  • 内存空间不均衡在Redis Cluster中,大目标会导致节点的内存运用不均衡。一些节点或许会存储更多的大目标,而另一些节点或许只保存较小的键值对,从而导致内存分配不平衡。

  • 超时堵塞因为Redis是单线程的,处理大目标会占用更多的处理时刻,或许导致其他操作的堵塞。假如一个大目标的存取操作耗时较长,那么有或许会形成其他恳求的推迟或堵塞

  • 网络堵塞获取大目标时会产生很多网络流量,尤其在分布式环境中。假如每次获取大目标的操作都会触及传输很多数据,或许会导致网络拥塞或推迟

功能问题影响

假如一个大目标几乎不会被访问到,那么对功能的影响相对较小,主要存在内存空间不均衡的问题。可是,假如一个大目标是一个热点key(频繁访问),它将对体系的功能产生严峻的影响。

拆分键值

需求依据实际状况来评价和办理大目标,假如一个大目标经常被访问,或许需求将其分解成多个小的键值对,或许运用其他数据结构来存储和处理该目标,以减轻Redis的负担。

集群分片

相同,能够考虑运用Redis的分片、集群等功能来均衡内存运用,并添加体系的扩展性和容错性。

能够经过redis-cli -h {ip} -p {port} bigkeys发现大目标。


swap热交流

前提介绍

首要,Redis在版别3.0之后,从内部代码中删除了对交流空间(swap space)的支撑和依靠。因而,Redis 3.0及更高版别不再运用交流空间进行内存交流。

在早期版别的Redis中,假如Redis实例的内存超越可用最大内存约束,操作体系会运用交流空间进行内存交流。但是,这种行为被发现会导致严峻的功能下降,而且将Redis带入不安稳的状况,因而在Redis 3.0中现已放弃了对交流空间的依靠。

辨认Redis进程号

redis-cli info server | grep process_id

依据进程号查询内存交流信息

cat /proc/{process_id}/smaps | grep Swap

假如交流量都是0kb或许单个的4kb都是正常现象

官方主张

Redis官方主张用户合理装备最大可用内存,并保证Redis实例具有满足的可用内存来包容数据和处理操作,以防止内存交流问题。这样做能够提高Redis的功能和安稳性,保证杰出的的用户体会。

咱们能够运用目标”used_memory”来了解Redis当时运用的内存状况。经过监测used_memory的值,能够承认Redis是否接近或超越了最大可用内存的阈值,从而及时做出相应的调整。

为了防止内存交流问题,需求合理装备Redis的内存约束,并保证Redis实例有满足的可用内存来包容数据和处理操作。这能够经过监控内存运用状况、调整Redis的缓存策略、设置合理的最大内存约束等手法来完成。

分布式Redis集群

为了提高功能和防止内存交流问题,主张独自布置Redis实例或运用分布式Redis集群,而且装备满足的内存,以便满意实际需求和预防潜在的功能问题。


Fork子进程

当Redis履行耐久化操作(RDB生成或AOF重写)时,会运用fork体系调用创建一个子进程来完结作业。在履行fork操作时,子进程会复制父进程的内存空间,包含所有数据集的内存表,这会导致fork操作的耗时与内存量(数据集)相关。

依据经验,每GB内存的fork操作耗时大约在20毫秒左右。因而,为了防止长时刻的堵塞,需求严格操控每个Redis实例可运用的最大内存在10GB以内,以削减fork操作的履行时刻。

查看对应INFO STATS指令剖析

能够经过运用Redis的INFO STATS指令来获取lastest_fork_usec目标,它表明Redis最近一次fork操作的耗时。经过监控这个目标,能够了解每次fork操作的耗时状况,并依据需求采取恰当的措施,如下降fork操作的频率或调整内存装备,以削减堵塞状况的产生。

 INFO STATS
# Stats
total_connections_received:513883995
total_commands_processed:4448904052
instantaneous_ops_per_sec:43
total_net_input_bytes:524046943608
total_net_output_bytes:562840058709
instantaneous_input_kbps:2.20
instantaneous_output_kbps:0.24
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:7725231
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:1361084505
keyspace_misses:311319261
pubsub_channels:28
pubsub_patterns:6
latest_fork_usec:15086
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

总归,了解fork操作对功能的影响以及操控内存运用是重要的,以保证Redis实例的安稳性和杰出的功能。


AOF刷盘堵塞

当Redis敞开AOF(Append-Only File)耐久化的一起,文件刷盘操作通常每秒履行一次。可是,当硬盘压力过大时,履行fsync操作需求等候写入完结,这或许会导致推迟。

INFO PERSISTENCE

要查看Redis日志或运用INFO PERSISTENCE指令能够获取到aof_delayed_fsync目标,它表明推迟履行的fsync操作的次数。

> INFO PERSISTENCE
# Persistence
loading:0
rdb_changes_since_last_save:1062773605
rdb_bgsave_in_progress:0
rdb_last_save_time:1672120744
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:0
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:5
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:4104192
aof_current_size:669972573
aof_base_size:366781665
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0

Redis的输入/输出缓冲区也或许导致堵塞

当Redis无法及时处理写入数据或无法将数据及时发送到磁盘,输入/输出缓冲区或许会添加,并导致堵塞。为了防止这种状况,能够依据实际状况调整Redis的相关装备参数,如client-output-buffer-limitaof-rewrite-incremental-fsync等,以操控输入/输出缓冲区的巨细和行为。

综上所述,理解和监控aof_delayed_fsync目标以及适时调整Redis的相关装备参数,能够协助应对或许导致堵塞的硬盘压力和输入/输出缓冲区的问题。

输入缓冲区

要查看输入缓冲区的总容量(qbuf)和剩下容量(qbuf-free),你能够运用Redis的INFO MEMORY指令。

在Redis客户端中,履行以下过程:

  1. 运用INFO MEMORY指令获取内存运用状况的相关信息。

    INFO MEMORY
    
  2. 在指令输出中,你会看到关于内存运用的详细信息,包含输入缓冲区的总容量和剩下容量。

   # Memory
   used_memory: 123456
   used_memory_human: 120.57K
   used_memory_rss: 456789
   used_memory_rss_human: 445.68K
   used_memory_peak: 789012
   used_memory_peak_human: 770.67K
  • 参数介绍
    • used_memory字段表明Redis运用的总内存。
    • used_memory_human字段表明Redis运用的总内存的人类可读方式。
    • used_memory_rss字段表明Redis的物理内存占用。
    • used_memory_rss_human字段表明Redis的物理内存占用的人类可读方式。
    • used_memory_peak字段表明Redis运用的内存峰值。
    • used_memory_peak_human字段表明Redis运用的内存峰值的人类可读方式。 留意:qbufqbuf-free字段在这个输出中或许不显式地列出,可是你能够依据上面提到的字段来揣度Redis的输入缓冲区容量。假如used_memory_peak字段和used_memory_peak_human字段的值为0,那么阐明没有分配查询缓冲区,每次只能处理一个指令。

redis为每个客户端分配了输入缓冲区,会将客户端发送指令暂时保存,然后取出来履行。

  • qbuf 表明总容量(0 表明没有分配查询缓冲区)
  • qbuf-free 表明剩下容量(0 表明没有剩下空间);

巨细不能超越 1G,当巨细超越1G时会将客户端自动封闭,输入缓冲区不受 maxmemory 约束

Blocked_Clients

当很多的 key 进入输入缓冲区且无法被消费时,即可形成 redis 堵塞;经过 client list 指令可定位产生堵塞的客户端;经过 info clients 指令的 blocked_clients 参数能够查看到当时堵塞的指令。

输出缓冲区

redis-server端完成的一个读取缓冲区,redis-server 在接收到客户端的恳求后,把获取成果写入到 client buffer 中,而不是直接发送给客户端。从而能够持续处理客户端的其他恳求,这样异步处理方式使 redis-server 不会因为网络原因堵塞其他恳求的处理。


网络问题

衔接回绝

当呈现网络闪断或Redis衔接回绝时,你能够运用以下方法来处理问题:

网络闪断:

  1. 查看网络衔接是否正常。保证网络衔接安稳,没有断开或中断。
  2. 查看网络带宽是否耗尽。假如网络带宽到达极限,或许会导致闪断。你能够联系网络办理员或供给商以处理带宽问题。

Redis衔接回绝:

  1. 承认maxclients设置。在Redis装备文件(redis.conf)中,找到maxclients设置项,保证其值满足大以包容你的并发衔接数。你能够经过修正装备文件来添加maxclients的值。
  2. 查看已建立的衔接数。运用Redis的INFO STATS指令能够获取有关衔接的计算信息。关注rejected_connections字段的值,假如该值添加,阐明现已到达了maxclients的约束。你能够经过添加maxclients或优化现有衔接以削减衔接数来处理此问题。

衔接溢出

进程约束

进程可翻开的最大文件数操控(ulimit -n)是约束体系中一起存在的文件描绘符数量的设置。关于Redis来说,高并发状况下需求处理很多的衔接,因而需求增大该值。

增大Redis衔接

主张增大ulimit -n的值来满意Redis的衔接需求。你能够经过修正体系的装备文件来设置该值。例如,在Linux体系中,能够修改/etc/security/limits.conf文件或/etc/sysctl.conf文件,并添加如下装备来增大该值:

# /etc/security/limits.conf
*    soft    nofile    65535
*    hard    nofile    65535

# /etc/sysctl.conf
fs.file-max = 65535

然后重启体系或运用sysctl -p指令加载装备。这样能够增大体系对翻开文件数量的约束,为Redis供给满足的文件描绘符。

backlog行列溢出

backlog行列溢出是指因为体系关于特定端口的TCP衔接运用的backlog行列溢出,导致衔接无法进入行列,形成衔接丢失。

你能够经过定时履行netstat -s | grep overflowed指令来计算backlog行列溢出状况。假如溢出的数量较多,能够考虑添加backlog行列的巨细。

参数来增大backlog行列

在Redis中,默许backlog行列巨细为511,而体系默许的backlog行列巨细为128。你能够经过修正Redis的装备文件(redis.conf)中的tcp-backlog参数来增大backlog行列的巨细。例如,将其设置为1024:

tcp-backlog 1024

网络推迟

网络推迟是指数据在网络中的传输所需求的时刻。若要优化网络推迟,你能够考虑以下几个方面:

  1. 保证网络衔接的安稳性。查看网络设备和链路,保证没有断开、抖动或毛病。能够联系网络办理员或服务供给商来处理网络问题。

  2. 优化Redis的网络装备。能够调整Redis的timeout参数,添加客户端与Redis服务器之间的超时时刻,以习惯网络推迟的状况。默许超时时刻为0,即永不超时。你能够依据实际状况适度添加这个时刻。

  3. 运用合适的网络协议及相关优化技能。挑选较低的网络协议推迟、运用TCP/IP的Nagle算法或敞开TCP_NODELAY选项来削减推迟等方式,都能够协助优化网络推迟。

敞开TCP_NODELAY

TCP_NODELAY是一个TCP套接字选项,用于操控是否启用Nagle算法。Nagle算法经过将数据缓存一小段时刻,合并多个小数据包一起发送,以削减网络传输中的报文数量,提升网络吞吐量和功率。可是这种优化策略会添加网络传输的推迟,特别是关于需求实时呼应的使用来说,Nagle算法或许会导致推迟较高的现象。

当启用TCP_NODELAY选项时,套接字禁用了Nagle算法,数据会当即发送,而且不会缓冲等候合并。这能够下降推迟,但会添加网络传输的负载。

在Redis中,默许状况下TCP_NODELAY是被禁用的,这意味着Nagle算法是启用的,适用于大部分状况。但是,假如你的使用对实时性要求较高,能够考虑启用TCP_NODELAY来削减推迟。

能够经过Redis的装备文件(redis.conf)中的tcp-keepalive参数来启用TCP_NODELAY。将其设置为1以启用该选项:

tcp-keepalive 1

需求留意的是,启用TCP_NODELAY或许会添加网络带宽的负载,特别是在高并发环境中运用时,或许会影响功能。因而,在启用该选项之前,应该仔细评价你的使用的实际需求,并进行相应的功能测验。

彩蛋介绍

在这里,我向咱们推荐一本关于JVM优化和调优的实战系列书本,《深入浅出Java虚拟机 — JVM原理与实战》。这本书是最新出书的,内容涵盖了与咱们当时作业和开发实例密切相关的技能和实战事例。经过学习这本书,咱们能够深入了解Java虚拟机的原理,并经过实践把握优化和调优的技巧。我诚挚地推荐这本书给咱们,信任它将为咱们的作业和技能发展带来巨大的收益。期望咱们能够抽出时刻多多学习一下这本宝贵的资料

【Redis故障排查】「连接失败问题排查和解决」带你深入分析一下Redis阻塞原因以及问题排查方案指南
【当当-点击链接】【京东-点击链接】