Redis学习笔记-避免Redis单线程阻塞

  • Post author:
  • Post category:其他




Redis学习笔记-避免Redis单线程阻塞

我们都知道

Redis

中的增删改查操作使用的是单线程模型(对于读写操作,

Redis 6.0

也是单线程),既然

Redis

是单线程就需要注意其潜在阻塞点,这篇文章学习一下

Redis

有哪些可能造成单线程阻塞的原因,这样可以提前避免性能问题。



1.笔记图

在这里插入图片描述



2.影响 Redis 性能的因素

  • 内部阻塞操作

  • CPU

    内核和

    NUMA

    架构

  • Redis

    关键系统配置

  • Redis

    内存碎片

  • Redis

    缓冲区



3.和 Redis 实例的交互方式

在这里插入图片描述


  • 客户端

    :网络

    IO

    ,键值对增删改查操作,数据库操作


  • 磁盘

    :生成

    RDB

    快照,记录

    AOF

    日志,

    AOF

    日志重写


  • 主从节点

    :主库生成、传输

    RDB

    文件,从库接收

    RDB

    文件、清空数据库、加载

    RDB

    文件


  • 切片集群实例

    :向其他实例传输哈希槽信息,数据迁移



4.Redis 潜在阻塞点


  • 和客户端交互时的阻塞点


  • 第一个阻塞点

    :集合全量查询和聚合操作,如

    HGETALL



    SMEMBERS

    ,其原因是一次性操作数据量大的聚合操作会阻塞

    Redis

    的主线程,导致其他操作无法进行

    在这里插入图片描述


  • 第二个阻塞点

    :删除占用内存较大的键值对,如

    del key

    (删除

    bigkey

    ),其原因是删除元素操作时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配,若一次性释放大量的内存,会导致空闲内存块链表操作时间增加,阻塞

    Redis

    主线程


  • 第三个阻塞点

    :清空数据,当删除所有键值对,需要释放内存空间,这个过程会阻塞

    Redis

    主线程


  • 和磁盘交互时的阻塞点



    AOF

    日志同步写,其原因是

    AOF

    日志采用同步写回策略时,若有大量写入会阻塞

    Redis

    主线程(而生成

    RDB

    快照采用的是子进程不会阻塞

    Redis

    主线程)


  • 主从节点交互时的阻塞点

    :从库在第一次全量同步的时候需要清空当前所有数据,从库同步主库的

    RDB

    快照文件,清空数据删除所有键值对,需要释放内存空间,这个过程会阻塞

    Redis

    主线程,加载的主库

    RDB

    快照文件越大,从库

    Redis

    主线程阻塞时间越长


  • 切片集群实例交互时的阻塞点



    Redis Cluster

    集群中迁移

    bigkey

    ,如果使用了

    Redis Cluster

    方案,且同时正好迁移的是

    bigkey

    的话,就会造成主线程的阻塞



5.潜在阻塞点优化(执行异步操作)



5.1 关键路径上的操作

客户端把请求发送给

Redis

后,等着

Redis

返回数据结果的操作,不适合使用异步操作

在这里插入图片描述

  • 操作

    A

    并不用给客户端返回具体的数据,主线程可以把它交给后台子线程来完成,可以使用异步操作
  • 操作

    B

    需要把结果返回给客户端,它就是关键路径上的操作,不适合使用异步操作

  • 读操作

    :典型的关键路径操作,因为客户端发送了读操作之后,就会等待读取的数据返回,它不适合使用异步操作

  • 从库加载 RDB 文件

    :从库要想对客户端提供数据存取服务,就必须把

    RDB

    文件加载完成,必须让从库的主线程来执行



5.2 非关键路径上的操作


  • 删除元素

    :删除操作并不需要给客户端返回具体的数据结果,所以不算是关键路径操作,可以使用异步操作,若要异步删除键值对,可使用

    UNLINK

    命令

  • 清空数据操作

    :清空数据不需要返回给客户端结果,可以使用异步操作

  • AOF日志同步写回策略

    :它并不会返回具体的数据结果,可以使用异步操作



6.异步子线程机制


  • Redis

    主线启动后,会使用操作系统提供的

    pthread_create

    函数创建

    3

    个子线程,分别负责

    AOF

    日志写操作、键值对删除、文件关闭的异步执行

  • 主线程通过一个链表形式的任务队列和子线程进行交互

    在这里插入图片描述

  • 键值对删除:若要异步删除键值对,可使用

    UNLINK

    命令

  • 清空数据库:可以在

    FLUSHDB



    FLUSHALL

    命令后加上

    ASYNC

    选项:

FLUSHDB ASYNC
FLUSHDB ASYNC

扫码关注

在这里插入图片描述



版权声明:本文为qq_38937634原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。