APP下载

单位Redis反应迟缓

2020-12-31河南刘景云

网络安全和信息化 2020年3期
关键词:快照磁盘调用

■河南 刘景云

某单位的网站后台采用的是Redis数据库,为了便于管理Web应用的缓存信息,使用Python开发了对应的模块,来提供的不同的HTTP接口,可以用来执行数据查新、数据插入、数据测试等功能。

Redis是常用的键值存储系统,提供数据的高速处理功能。但在实际过程中,在查询和插入数据时,接口的响应时间却比较缓慢,这给网站的管理和维护带来了很大的问题。

故障分析

对于上述故障,首先考虑的是否在系统配置上存储问题,例如CPU资源占用率过高,内存消耗严重等,有可能造成Redis反应迟缓的问题。在后台服务器上执行“top”命令,在返回信息中的发现只有CPU 1的IOWait值较高,达到了89%,各进程的CPU占用率都不高,Python和Redis-Server进程的CPU使用率也不超过10%,存在很多的空闲内存,从“load average”栏数据来看那么,系统的负荷并不高。

那么是不是因为系统的I/O性能存在瓶颈呢?为了便于发现问题,在前台执行连续查询操作,不断的从特定的接口读取Redis缓存信息,之后在后台服务薇上执行“iostat-d-x 1”命令,对iostat的输出信息进行观察,发现磁盘每秒写入数据大约为7.9MB,“%util”的值为0,说明虽然存在一些I/O操作,但是没有比较严重的I/O瓶颈问题。根据以上分析,虽然发现CPU,内存和I/O都不存在明显的问题,

但是对于上述案例来说,在从接口中读取Redis数据时,涉及到的是只是数据的读取操作,并没有指定数据的频繁写入操作,根据上述iostat命令检测信息,却发现存在明显的写操作。

执行“pidstat-d 1”命令,显示所有进程I/O使用情况,发现PID为8701的进程在频繁的写入数据,与其对应的是“redis-server”进程,说明Redis服务确实在不停的向磁盘写入数据。

为了进一步进行观察,执行“strace-f-T-tt p 8701”命令,检测该进程的详细的I/O操作情况,其中的“-f”参数表示跟踪子进程和子线程信息,“-T”参数表示显示系统调用的时长,“tt”表示显示跟踪时间。

根据显示的系统调用信息,发现频繁出现诸如“epoll_pawit”“read”“write”“fdatasync”等系统调用行为,对于磁盘些操作来说,无疑是由于“write”“fdatasync”行为造成的。

执行“lsof-p 8701”命令,显示该进程调用的操作对象信息。可以看到,其操作的对象包括Pipe管道、Eventpoll文件描述符、名为“/data/appendonly”的文件(编号为7),以及“Protocol:TCP”端口(编号为8)。

故障排查

在这些对象中,只有涉及到到普通文件的操作,才会触发磁盘些操作,即上述“write”和“fdatasync”调用行为针对的就是名为/data/appendonly”的文件。这其实和Redis的数据持久化有着紧密的联系,因为它和Redis持久化中配置中的“appendonly”及“appendfync”项目有关。

在客户端上执行“rediscli config get 'append*'”命令,在返回信息中显示“appendfync”参数的值为“always”,“appendonly”参数的值为“yes”。Redis的持久化指的是将数据存储到断电后不会丢失的设备中。

Redis支持RDB和AOF两种持久化方式。前者是基于内存快照的持久化方式,后者可以将所有的操作命令记录下来形成日志文件,这样即使Redis出现异常情况,也可以利用日志进行数据的快速恢复。

在Redis配置文件中,将“appendonly”参数值设置为“yes”,表示启用AOF功能。将“appendfsync”参数值设置为“always”,表示将每一个命令都立即同步到aof日志。如果设置为“everysec”,表示每秒钟调用一次fsync操作,这样即使出现问题,也只是丢失1秒钟内的数据。如果设置为“no”,表示交由操作系统处理。

快照方式会按照指定的周期,生成数据的快照,并最终保存到磁盘文件中,为了避免阻塞主进程,Redis会利用Fork函数通过系统调用来创建一个子进程,用来负责保存快照,该方式具有速度快性能好的特点。但其缺点是,在处理较大的数据量时,该子进程会占用较大的内存,保存数据比较耗时。如果在指定的时间间隔内发生故障的话,就会丢失一定的数据。

AOF方式采用的是在文件尾部追加数据,因此Redis写入的的数据持久化显得更加安全。利用“appendfsync”参数参数,可以设置fsync策略,保证写入的数据都保存在磁盘中。根据上面检测的信息,说明“appendfsync”参数设置为“always”方式,说明在每次写入数据时,都会触发一次fsnc操作,所以造成了较大的磁盘I/O压力。

故障解决

为了验证这一想法,可以借助于Strace这款工具加以检测,Strace是一个集诊断、调试、统计与一体的工具,可以使用其对系统调用和信号传递进行跟踪分析。

例如,执行“strace-f-p 8701-T-tt-e fdatasync”命令,对fsync调用情况进行跟踪,根据返回信息,可以发现每隔几毫秒就会出现一个fdatasync调用信息,每次调用本身也会消耗一定的时间。根据上面的分析,可以看出之所以Redis出现反应迟缓的问题,和其配置方式存在很大的关系。

之所以在读取数据时,依然会出现写磁盘的操作,可以执行“strace-f-p 8701-T-tt”命令,会发现存在TCP Socket相关的数据读写操作,其中包含了“SADD”之类的指令,SADD指令的作用是将一个或多个成员元素加入到集合中。

执行“lsof-i”命令,查看所有进程的网络访问信息,在其中找到“redisserver”进程,对应的“FD”列中显示使用了“8u”,在“NAME”列中显示自身监听的端口(如“TCP 6379”),以及与其连接的端口(例如“TCP 59166”),而Python进程正好连接在后面的端口上。

也就说是,虽然通过对应接口执行了读操作,但是也涉及到了写操作,Redis会将相关的数据保存到“appendonly.aof”的持久化文件中。

经过上面一番分析,就已经找到了引发上述故障的原因,这其实是由于两方面的问题造成的,首先在Redis的配置信息中,“appendsync”参数设置为了“always”,造成Redis的所有写操作都会频繁的触发fdatasync调用,造成时间延迟的现象,将其设置为“everysec”表示每秒同步一次,就可以满足满足实际的需求。

在客户端执行“rediscli config set appendsync everysec”命令,即可更改该参数。其次在开发的Python查询接口模块中,对缓存的使用存在不完善的地方。例如,将Redis作为临时空间,来保存相关的数据,从而造成在查询时会调用Redis的SADD命令的情况。为此可以对程序进行优化,将这些查询数据保存到内存中即可。

完成了以上处理后,在客户端利用HTTP接口执行查询和写入等操作时,Redis的反应速度大大提高,迟缓的故障彻底消失。

猜你喜欢

快照磁盘调用
面向Linux 非逻辑卷块设备的快照系统①
EMC存储快照功能分析
它的好 它的坏 详解动态磁盘
核电项目物项调用管理的应用研究
创建虚拟机磁盘方式的选择
解决Windows磁盘签名冲突
系统虚拟化环境下客户机系统调用信息捕获与分析①
Windows系统下动态磁盘卷的分析与研究
一种基于Linux 标准分区的快照方法
让时间停止 保留网页游戏进度