Redis基线性能
- 系统在低压力、无干扰下的基本性能,这个性能只由当前的软硬件配置决定
redis-cli --intrinsic-latency 120 -h host -p 6379
120秒统计基线性能,打印出的最大延迟就是基线性能- 如果Redis运行时的延迟是基线性能2倍以上,就可以认定为Redis慢了
Redis变慢原因与应对
- Redis自身操作特性
- 文件系统
- 操作系统
Redis自身操作特性
- 慢查询命令
- 过期key操作
慢查询命令
- 用其他命令代替 smembers替换为sscan
- 需要执行排序,交集操作时,用客户端程序处理
过期key操作
- 默认情况下,Redis 每 100 毫秒会删除一些过期 key
- ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 每次删除多少个key
- 如果超过25%的key过期了,重复删除的过程,直到过期的key占比少于25%
- 不要频繁使用带有相同时间戳参数的explainat命令设置过期时间,会导致同一时间大量的key过期然后重复在执行删除操作
使用scan命令代替keys
SCAN $cursor COUNT $count
,初始游标是0,可以得到一批key,最多返回count个元素,以及下一个游标,直到游标再次返回0后,数据就全部遍历完了- rehash(哈希缩容)会造成scan获得重复的key
- count限定的是每次scan遍历的哈希槽数
高位进位法
- 解决rehash扩缩容是,scan遍历容易产生重复的问题
- 如果按照顺序加一的方式进行遍历,当rehash后,key的顺序被打乱,就可能会有重复key或者遗漏key
- https://blog.csdn.net/u014439693/article/details/108325632
HSCAN/SSCAN/ZSCAN命令
- Hash/Set/Sorted Set
- 元素数量比较少时,底层会采用intset/ziplist方式存储,以这种方式存储,在执行HSCAN/SSCAN/ZSCAN命令时,会无视count参数,直接把所有元素一次性返回,得到的元素数量是会大于count参数的
- 底层转为哈希表或跳表存储时,使用发count参数,最多返回count个元素
文件系统对Redis的影响
- 文件系统将数据写回磁盘的机制,直接影响Redis持久化的效率,持久化的同时又会处理新请求,Redis持久化效率高低就影响到了Redis处理请求的能力
- Redis是内存数据库,内存不够用,操作系统开启swap,就会大幅减缓Redis速度
文件系统AOF模式
- AOF模式,no、everysec、always依赖文件系统的两个调用完成write和fsync
- write 只把日志记录写到内核缓冲区,就返回,并不需要等待日志实际写回到磁盘
- fsync 需要把日志记录写回到磁盘后才返回
- Redis 会执行 AOF 重写,生成体量缩小的新的 AOF 日志文件。AOF 重写本身需要的时间很长,也容易阻塞 Redis 主线程
- AOF 重写会对磁盘进行大量 IO 操作,同时,fsync 又需要等到数据写到磁盘后才返回,当 AOF 重写的压力比较大时,会导致 fsync 被阻塞
- fsync 是由后台子线程负责执行的
- 主线程会监控 fsync 的执行进度,当主线程使用后台子线程执行了一次 fsync,需要再次把新接收的操作记录写回磁盘时,如果主线程发现上一次的 fsync 没有执行完,就会阻塞。所以,如果后台子线程执行的 fsync 频繁阻塞的话(比如 AOF 重写占用了大量的磁盘 IO 带宽),主线程也会阻塞,导致 Redis 性能变慢
操作系统swap
- 操作系统里将内存数据在内存和磁盘间来回换入和换出的机制,涉及到磁盘的读写
- swap 触发后影响的是 Redis 主 IO 线程,增加 Redis 的响应时间
- 触发 swap 的原因主要是物理机器内存不足
操作系统内存大页
- 2MB 大小的内存页分配,而常规的内存页分配是按 4KB 的粒度来执行的
- 写时复制机制,持久化的过程中的数据再修改时,计时修改100B的数据,也会复制2MB的内存页。而正常只需要拷贝4KB,大量修改数据时,就会频繁拷贝内存大页,造成阻塞