Redis有哪些慢操作?( 三 )


  1. 每秒进行10次过期扫描,每次从过期字典中随机选出20个key
  2. 删除20个key中已经过期的key
  3. 如果过期key的比例超过1/4,则进行步骤一
  4. 每次扫描时间的上限默认不超过25ms,避免线程卡死
「因为Redis中过期的key是由主线程删除的,为了不阻塞用户的请求,所以删除过期key的时候是少量多次」 。源码可以参考expire.c中的activeExpireCycle方法
为了避免主线程一直在删除key,我们可以采用如下两种方案
  1. 给同时过期的key增加一个随机数,打散过期时间,降低清除key的压力
  2. 如果你使用的是redis4.0版本以上的redis,可以开启lazy-free机制(lazyfree-lazy-expire yes),当删除过期key时,把释放内存的操作放到后台线程中执行
内存达到上限,触发淘汰策略Redis是一个内存数据库,当Redis使用的内存超过物理内存的限制后,内存数据会和磁盘产生频繁的交换,交换会导致Redis性能急剧下降 。所以在生产环境中我们通过配置参数maxmemoey来限制使用的内存大小 。
当实际使用的内存超过maxmemoey后,Redis提供了如下几种可选策略 。
Redis有哪些慢操作?

文章插图
 
「Redis的淘汰策略也是在主线程中执行的 。但内存超过Redis上限后,每次写入都需要淘汰一些key,导致请求时间变长」
可以通过如下几个方式进行改善
  1. 增加内存或者将数据放到多个实例中
  2. 淘汰策略改为随机淘汰,一般来说随机淘汰比lru快很多
  3. 避免存储bigkey,降低释放内存的耗时
写AOF日志的方式为alwaysRedis的持久化机制有RDB快照和AOF日志,每次写命令之后后,Redis提供了如下三种刷盘机制
Redis有哪些慢操作?

文章插图
 
「当aof的刷盘机制为always,redis每处理一次写命令,都会把写命令刷到磁盘中才返回,整个过程是在Redis主线程中进行的,势必会拖慢redis的性能」
当aof的刷盘机制为everysec,redis写完内存后就返回,刷盘操作是放到后台线程中去执行的,后台线程每隔1秒把内存中的数据刷到磁盘中
当aof的刷盘机制为no,宕机后可能会造成部分数据丢失,一般不采用 。
「一般情况下,aof刷盘机制配置为everysec即可」
fork耗时过长在持久化一节中,我们已经提到「Redis生成rdb文件和aof日志重写,都是通过主线程fork子进程的方式,让子进程来执行的,主线程的内存越大,阻塞时间越长 。」
可以通过如下方式优化
  1. 控制Redis实例的内存大小,尽量控制到10g以内,因为内存越大,阻塞时间越长
  2. 配置合理的持久化策略,如在slave节点生成rdb快照
使用swap分区当机器的内存不够时,操作系统会将部分内存的数据置换到磁盘上,这块磁盘区域就是Swap分区,当应用程序再次访问这些数据的时候,就需要从磁盘上读取,导致性能严重下降
「当Redis性能急剧下降时就有可能是数据被换到Swap分区,我们该如何排查Redis数据是否被换到Swap分区呢?」
# 先找到redis-server的进程idps -ef | grep redis-server# 查看redis swap的使用情况cat /proc/$pid/smaps | egrep '^(Swap|Size)'[root@VM-0-14-centos ~]# cat /proc/2370/smaps | egrep '^(Swap|Size)'Size:1568 kBSwap:0 kBSize:8 kBSwap:0 kBSize:24 kBSwap:0 kBSize:2200 kBSwap:0 kB每一行Size表示Redis所用的一块内存大小,Size下面的Swap表示这块大小的内存,有多少已经被换到磁盘上了,如果这2个值相等,说明这块内存的数据都已经被换到磁盘上了
我们可以通过如下方式来解决
  1. 增加机器内存
  2. 整理内存碎片
最后我们总结一下Redis的慢操作
Redis有哪些慢操作?

文章插图
 




推荐阅读