18~19 Redis响应延迟

判断Redis变慢

  • 第一种方法:查看Redis的响应延迟
redis-cli --latency -h host -p port

当发现Redis命令的执行时间突然就增长到了几秒,基本可以认定Redis变慢。

  • 第二种方法:基于当前环境下的Redis基线性能做判断。
    基线性能:一个系统在低压力、无干扰的下的基本性能,这个性能只由当前的软硬件配置决定。
redis-cli --intrinsic-latency {time}

打印{time}秒内检测到的最大延迟。

一般来说,你要把运行时延迟和基线性能进行对比,如果你观察到的 Redis 运行时延迟是其基线性能的 2 倍及以上,就可以认定 Redis 变慢了。

在虚拟化环境,Redis的基线性能要比物理机差。

iPerf测量从redis客户端到服务端的网络延迟

如何应对Redis变慢

影响Redis性能的三大因素:

  • Redis自身的操作特性
  • 文件系统
  • 操作系统

在这里插入图片描述

Redis自身操作特性的影响

  • 慢查询命令
  • 过期key操作
慢查询命令

慢查询命令就是指在Redis中执行速度慢的命令,这会导致Redis延迟增加。Redis命令的执行速度和操作的复杂度有关。

当发现Redis性能变慢时,可以通过Redis日志或者通过latency monitor工具,查询变慢的请求,根据对应的具体命令以及官方文档,确认下是否采用了复杂度高的慢查询命令。

如果的确有大量的慢查询命令,有两种处理方式:

  1. 用其他高效命令代替。比如说,如果你需要返回一个 SET 中的所有成员时,不要使用 SMEMBERS 命令,而是要使用 SSCAN 多次迭代返回,避免一次返回大量数据,造成线程阻塞。
  2. 当你需要执行排序、交集、并集操作时,可以在客户端完成,而不要用sort、sunion、sinter这些命令,以免拖慢Redis实例。

因为KEYS命令需要遍历存储的键值对,所以操作延时高。KEYS命令一般不被建议用于生产环境中。

过期key操作

Redis键值对的key可以设置过期时间。默认情况下,Redis每100毫秒会删除一些过期key,具体算法如下:

  1. 采集最多 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 个数的要过期的key,并将其全部删除;
  2. 如果超过 25% 的 key 过期了,则重复删除的过程,直到过期 key 的比例降至 25% 以下。

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 是 Redis 的一个参数,默认是 20,那么,一秒内基本有 200 个过期 key 会被删除。这一策略对清除过期 key、释放内存空间很有帮助。如果每秒钟删除 200 个过期 key,并不会对 Redis 造成太大影响。

但是,如果触发了上面这个算法的第二条,Redis 就会一直删除以释放内存空间。注意,删除操作是阻塞的(Redis 4.0 后可以用异步线程机制来减少阻塞影响)。所以,一旦该条件触发,Redis 的线程就会一直执行删除,这样一来,就没办法正常服务其他的键值操作了,就会进一步引起其他键值操作的延迟增加,Redis 就会变慢。

算法第二条触发的一个重要来源:
频繁使用带有相同时间参数的 EXPIREAT 命令设置过期 key,这就会导致,在同一秒内有大量的 key 同时过期。

要检查业务代码在使用 EXPIREAT 命令设置 key 过期时间时,是否使用了相同的 UNIX 时间戳,有没有使用 EXPIRE 命令给批量的 key 设置相同的过期秒数。因为,这都会造成大量 key 在同一时间过期,导致性能变慢。

如果一批 key 的确是同时过期,你还可以在 EXPIREAT 和 EXPIRE 的过期时间参数上,加上一个一定大小范围内的随机数,这样,既保证了 key 在一个邻近时间范围内被删除,又避免了同时过期造成的压力。


Redis会持久化保存数据到磁盘,这个过程要依赖文件系统来完成,所以文件系统将数据写回磁盘的机制,会直接影响到Redis持久化的效率。而且在持久化的过程中,Redis还在接收其他请求,持久化的效率高低又会影响到Redis处理请求的性能。

另一方面,Redis是内存数据库,内存操作频繁,所以操作系统的内存机制会直接影响到Redis的处理效率。比如说,如果Redis的内存不够用了,操作系统会启动swap机制,这就会直接拖慢Redis。


文件系统的影响

文件系统:AOF模式

为了保证数据可靠性,Redis会采用AOF日志或者RDB快照。其中,AOF日志提供了三种日志写回策略:no、everysec、always。这三种写回策略依赖文件系统的两个系统调用完成:write和fsync。

write只要把日志记录写到内核缓冲区中就可以返回,并不需要等待日志实际写回到磁盘;而fsync需要把日志记录写回到磁盘后才能返回,时间较长。
在这里插入图片描述
在使用everysec时,Redis允许丢失一秒的操作记录,所以Redis主线程并不需要确保每个操作记录都写回磁盘。而且fsync的执行时间很长,如果是在Redis主线程中执行fsync,就容易阻塞主线程。所以,当写回策略配置为everysec时,Redis会使用后台的子线程异步完成fsync操作。

对于always策略,Redis需要确保每个操作记录日志都写回到磁盘,如果使用后台线程则无法及时知道每个操作是否已经完成。所以always策略并不使用后台子线程来执行。

另外,在使用 AOF 日志时,为了避免日志文件不断增大,Redis 会执行 AOF 重写,生成体量缩小的新的 AOF 日志文件。AOF 重写本身需要的时间很长,也容易阻塞 Redis 主线程,所以,Redis 使用子进程来进行 AOF 重写。

AOF重写会对磁盘进行大量IO操作,同时fsync又需要等到数据写到磁盘之后才能返回,所以当AOF重写的压力比较大时,就会导致fsync被阻塞。虽然fsync是由后台子线程负责执行的,但是主线程会监控fsync的执行进度。

当主线程使用后台子线程执行了一次 fsync,需要再次把新接收的操作记录写回磁盘时,如果主线程发现上一次的 fsync 还没有执行完,那么它就会阻塞。所以,如果后台子线程执行的 fsync 频繁阻塞的话(比如 AOF 重写占用了大量的磁盘 IO 带宽),主线程也会阻塞,导致 Redis 性能变慢。

在这里插入图片描述
由于 fsync 后台子线程和 AOF 重写子进程的存在,主 IO 线程一般不会被阻塞。但是,如果在重写日志时,AOF 重写子进程的写入量比较大,fsync 线程也会被阻塞,进而阻塞主线程,导致延迟增加。

操作系统的影响

操作系统:swap

内存swap是操作系统里将内存数据在内存和磁盘之间来回换入和换出的机制,涉及到磁盘的读写,所以一旦触发swap,无论是被换入数据的进程,还是被换出数据的进程,其性能都会受到慢速磁盘读写的影响。

swap触发后影响的是Redis主IO线程,会极大增加Redis的响应时间。

通常,触发swap的原因主要是物理机器内存不足,对于Redis而言,有两种常见的情况:

  • Redis实例自身使用了大量的内存,导致物理机器的可用内存不足
  • 和Redis实例在同一台机器上运行的其他进程,在进行大量的文件读写操作。文件读写本身会占用系统内存,这会导致分配给Redis实例的内存变少,进而触发Redis发生swap。

解决思路:
增加机器的内存或者使用Redis集群

操作系统:内存大页

除了内存swap,还有内存大页机制(Transparent Huge Page,THP)也会影响Redis性能。

Linux 内核从 2.6.38 开始支持内存大页机制,该机制支持 2MB 大小的内存页分配,而常规的内存页分配是按 4KB 的粒度来执行的。

Redis采用写时复制机制,即一旦有数据发生修改,Redis并不直接修改内存中的数据,而是将这些数据拷贝一份,然后进行修改。

如果采用内存大页,那么即使客户端请求只修改100B的数据,Redis也需要拷贝2MB的大页。相反,如果是常规内存机制,只用拷贝4KB。所以当客户端请求修改或新写入数据较多时,内存大页机制将导致大量的拷贝,会影响Redis正常的访存操作,最终导致性能变慢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。   本课程主要讲解以下内容:1. Redis的基本使用2. Redis数据库的数据类型3. Redis数据库数据管理4. Redis的主从复制5. Redis数据库的持久性6. Redis的高可靠性和集群7. Redis的优化和性能测试8. Redis服务器的维护和管理9. Redis服务器的常见问题排错 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值