本文介绍了redis出现延迟的几种因素和相应的解决办法。
latency是衡量 redis 性能好坏的最重要的SLI之一,也是SRE在运维过程中应该特别关注的一个维度,生产环境中我们处理 redis latency 的场合也是很多,那么今天我们来了解一下。
回顾上篇文章:
基于Pyinotify打造系统完整性检测工具
定位 redis 出现延迟
1
远端定位
使用 redis-cli --latency -h 127.0.0.1 -p 6379 命令绕过网络层,忽略网络带来的延迟,使用 redis 内部的延迟检测子系统测试。
2
自身定位
在 redis server 上运行 redis-cli --intrinsic-latency 50 (50 的单位是 s) 延迟不超过 100 微秒的性能算是正常的延迟。
出现延迟的因素和解决办法
1
网络造成的延迟
1)来自于硬件、当网络吞吐量达到网卡本身的处理能力时,延迟会明显增大,因此 redis server 最好使用万兆多队列网卡。
2)来自应用程序和服务器之间的交互过多。因此要减少不必要的连接,尽可能的延长与服务器的连接时间,启用长链接,使用连接池。
2
redis 自身的问题
redis 使用单线程设计的,这意味着单个线程需要使用一种多路复用的技术来服务所有的客户端请求,但是它又被设计成系统调用时不能阻塞。解决办法只能是尽量减少阻塞事件的发生,比如持久化的开关不要再一台主 master 开启,但也有在所难免的时候,比如 slave 和 master 由于网络波动,偏移量过大导致一次全量同步也会产生阻塞。
3
部署的问题
我们使用 redis sentail 模式或 redis cluster 模式时一般都会开启持久化配置,无论是 rdb 还是 aof 都会产生 fork 的操作,fork 操作会在主线程中被执行,这样会引发延迟,因为 fork 是一个很消耗的操作,因为它牵扯到赋值很多与进程相关的对象,因此在部署 redis 的时候尽量在 slave 的服务上启用持久化开关。
4
操作系统层面
1)透明大页引起的延迟,默认情况下透明大页是 always, 内存大页会引起以下几个问题 :
fork 被调用,共享内存大页的两个进程被创建。
在一个系统比较活跃的实例里, 部分循环时间运行需要几千个内存页, 期间引起的 copy-on-write 会消耗几乎所有的内存。
这个将导致更大的延迟和使用更多的内存。
2)swapping 引起的延迟
一般系统之所以要在内存和硬盘之间置换 redis 页数据主要是为了应对内存不足的压力和大量的读写 I/O 产生交换,交换会产生 I/O 阻塞,因次在生产环境中我们应在劲量保证 redis 主进程物理内存资源充足并考虑产生全量的 save 之后还要有一定的 buffer 内存空间,这也是为什么我们每台服务器内存使用率要在 50% 下的原因,再次情况下,我们系统配置禁用 swap。
3)服务器的 numa 架构导致的延迟
日常运维中有时你会发现服务器还有内存却发生了 swap, 甚至导致机器出现了停滞现象,元凶可能是是 numa 的限制, 因此你需要使用 numactl --interleave=all 取消 numa node 的限制。
5
应用层使用的问题
1) 慢命令造成的延迟
大数据集的交叉会花很长时间,如 sort, lrem,sunion,keys 这些操作,有些耗时的客户端查询可以在 relica 上执行,有些命令需要rename 如 keys
2) 数据过期造成的延迟
大量数据的过期会导致 redis 出现延迟,因此要合理设置 key 的过期时间。
PS,好了,以上就是我要和你分享的内容,希望对你有所帮助,谢谢。
领取专属 10元无门槛券
私享最新 技术干货