原文地址:https://www.douyacun.com/article/844557c441f1514259eb7b42a614c080
延迟是 客户端从发出命令与客户端接收命令的回复之间的最大延迟,通常redis的处理时间是非常低的,但是存在高延迟的某些条件
解决思路:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
, 然后重启redisredis-cli --intrinsic-latency 100
, 需要redis-server服务器上运行1Gbit/s的网络延迟大约为200us,uninx域套接字的延迟低至30us,如果在同一个服务器可以用unix_socket加速,redis启用unix_socket
redis.conf
unixsocket /var/run/redis/redis.sock
unixsocketperm 777
php 连接redis
$redis->connect('/var/run/redis/redis.sock');
解决方案:
redis主要使用单线程设计,多路复用为客户端的请求提供服务,所有请求都是安装顺序提供
单线程的结果是,当有慢查询时所有其他客户端将等待该请求完成
如果有慢查询时必须的可以放在salve上执行所有慢查询
查看慢查询日志
slowlog get 2
sort\lrem\sunion\keys 这些都慢查询命令,用scan代替keys
开启RDB和AOF重写,redis必须fork后台进程,fork操作可能会阻塞主进程,fork涉及到复制大量对象,尤其对于使用虚拟内存机制的页表 linux/64,内存为4kb每页,每个进程存储一个页表,对于24G内存的redis实例需要(24GB/4kb)*8=48M,每次fork都会分配和复制48M内存
transparent_hugepage linux内核尽可能的尝试分配2M的页大小给程序使用,内核空间在内存中自身是2M对齐的,目的是减少内核TLB的压力(cpu使用的一小块关联内存),如果内存没有2M的连续大小的空间可分配,内核会回退到分配4kB
echo never > /sys/kernel/mm/transparent_hugepage/enabled
strace只显示慢速系统调用:
sudo strace -f -p $(pidof redis-server) -T -e trace=fdatasync,write 2>&1 | grep -v '0.0' | grep -v unfinished
[root@00h ~]# vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 93016 16576 212056 0 0 81 151 1 11 2 0 98 0 0
0 0 0 92892 16588 212116 0 0 44 0 288 591 1 0 98 1 0
0 0 0 92892 16616 212068 0 0 28 0 322 663 0 1 99 0 0
0 0 0 92892 16628 212084 0 0 12 0 326 650 1 1 98 0 0
^C
swap si/so 为0,说明swap没有内存交换活动
[www@00h www.00h.tv]$ iostat -xk 1
Linux 3.10.0-957.1.3.el7.x86_64 (00h) 06/15/2019 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
1.54 0.00 0.43 0.20 0.00 97.83
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.16 1.14 1.58 1.71 81.23 150.43 140.57 0.04 10.98 14.13 8.08 0.97 0.32
如果延迟问题是由于redis内存在磁盘上交换造成,需要降低系统内存压力,增加更多的内存
AOF有两个系统调用:
write:将数据写入aof文件,产生阻塞的情况:1. 当系统缓冲区已满 2. 系统正在将缓冲区的内容写入到文件
fdatasync: 刷新内核文件缓冲区的文件到磁盘上,相比fsync要高效
redis可以配置3种fsync:
可以使用strace查看进程对fdatasync/write的调用
sudo strace -p $(pidof redis-server) -T -e trace=fdatasync,write
redis使key过期的方式:
redis没100毫秒会启动一个serverCron来执行定期淘汰策略
ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
移除所有已过期的键正常情况下,ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
默认情况下设置为20,每秒执行10次,通常每秒只有200个密钥主动过期,每秒200个key过期对redis实例是没有影响的,
然而算法是自适应的,如果发现该组采样key中发现超过25%的key已经过期,该算法会循环,如果数据库有超过25%的key可以在同一秒过期,并且这些key占当前key的25%
设置延迟阀值(单位:毫秒),只有超过阀值的事件才会被记录成为延迟峰值,根据需要设置
config set latency-monitor-threshold 100
redis慢查询配置:
获取慢查询日志:
slowlog get [n]
[work@cpc-dev01 ~]$ redis-cli -p 6379 --intrinsic-latency 100
Max latency so far: 1 microseconds.
Max latency so far: 3 microseconds.
Max latency so far: 4 microseconds.
Max latency so far: 5 microseconds.
Max latency so far: 9 microseconds.
Max latency so far: 13 microseconds.
Max latency so far: 17 microseconds.
Max latency so far: 28 microseconds.
Max latency so far: 110 microseconds.
Max latency so far: 159 microseconds.
Max latency so far: 548 microseconds.
^C
685295282 total runs (avg latency: 0.1459 microseconds / 145.92 nanoseconds per run).
Worst run took 3755x longer than the average latency.
这个命令要在服务器上运行
latency latest
最新延迟事件latency history command
从事件时间序列中获取原始数据非常有用latency reset
不带参数,重置所有事件latency graph command
生成ASCII图形#
|
|
|_
11
77
mm
这个图要竖着看,17m 代表17分钟前发生
latency history
EXISTS
、DEL
这样的操作,很多场景下是不需要的,QPS不必要的情况,取消这些可以提升有效用户请求的数量
keepalive + twemproxy
也能有效提升redis的CPU利用率