Redis核心技术 您所在的位置:网站首页 redis能做哪些功能 Redis核心技术

Redis核心技术

2023-09-18 11:15| 来源: 网络整理| 查看: 265

  Redis单线程处理网络IO、key-value操作、加载RDB文件等,但是部分操作会导致Redis主线程阻塞。那么都有哪些阻塞主线程的操作,以及哪些操作可以异步处理呢?

Redis实例交互式操作

  在了解Redis异步机制前,先了解下Redis都有哪些交互式的操作。

client和Redis的操作

  client和Redis的操作包含:网络 IO,键值对增删改查操作,清空数据库操作。

  另外,bgsave、bgrewriter等操作时主线程fork子进程处理,如果Redis实例不是大内存(32G以上)Redis主线程阻塞时间较短。

网络 IO

  Redis采用多路复用I/O机制,避免主线程一直阻塞在网络连接上,网络 IO不会导致Redis主线程阻塞。

  了解更多I/O多路复用查看另外一篇文章:计算机网络-I/O多路复用机制

key-value增删改查操作

  时间复杂度大的key-value操作是Redis主线程主要执行的任务,不同的操作命令时间复杂度不一样,MGET、HMGET、HGETALL等操作时间复杂度O(N),GET、SET等操作时间复杂度O(1)。所以key-value操作有可能导致Redis主线程阻塞(时间复杂度大Redis主线程阻塞)。

  删除操作也可能导致Redis主线程阻塞,删除操作的本质是要释放键值对占用的内存空间。释放内存只是第一步,为了更加高效地管理内存空间,在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序,所以,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞(bigKey删除Redis主线程阻塞)。

  例如一次性删除大量key、删除大hash表、删除大list 等bigKey。

  清空数据库操作,FLUSHDB、FLUSHALL操作释放所有key-value(与删除bigKey类型)可能造成 Redis 主线程的阻塞(清空数据库操作Redis主线程阻塞)。

FLUSHDB、FLUSHALL区别: FLUSHALL清空数据库并执行持久化操作,也就是rdb文件会发生改变。FLUSHALL不仅仅是当前 select 的数据库,将清空整个 Redis 中的数据。 FLUSHDB清空数据库,但是不执行持久化操作,也就是说rdb文件不发生改变。清空当前 select 数据库中的所有 key。

磁盘

  磁盘的操作包含:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;

  生成 RDB 快照、AOF日志重写 生成 RDB 快照、AOF日志重写是Redis主线程fork子进程异步处理,不会阻塞Redis主线程。

  记录 AOF 日志 记录 AOF 日志以及AOF日志同步写盘(通过写入策略控制)由Redis主线程进行,磁盘的写入速度远低于内存的,大量的AOF日志写盘时会导致Redis主线程阻塞。

主从节点

  master生成、传输 RDB 文件,slave接收 RDB 文件、清空数据库、加载 RDB 文件;

  master生成、传输 RDB 文件由子进程处理,不会阻塞Redis主线程。   但是slave接受RDB文件包含写磁盘操作,RDB文件接收结束后,slave需要FLUSHDB清空数据库,并且把RDB文件加载到内存,如果RDB文件很大,接收、加载RDB文件有可能阻塞slave主线程。

cluster集群

  cluster集群新增、删除节点时,Redis实例向其他Redis实例传输哈希槽信息,数据迁移。

  如果使用了 Redis Cluster 方案,而且同时正好迁移的是 bigkey 的话,就会造成主线程的阻塞,因为 Redis Cluster 使用了同步迁移。

集群相关文章: Redis核心技术-高可靠-集群(cluster) Redis核心技术-高可靠-集群方案(客户端分片、代理分片、Redis Cluster)

Redis异步机制

  我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。

但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。

创建子线程

  说到异步机制,那么有那些子线程以及子线程分别执行那些操作呢?

  Redis 主线程启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,分别由它们负责 AOF 日志写操作(Redis核心技术-持久化-AOF)、key-value删除(Redis核心技术-高频问题-过期/删除Key)以及文件关闭的异步执行。

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

异步解决主线程阻塞操作

  前面说到时间复杂度高的操作、删除bigKey操作、FLUSHDB和FLUSHALL操作、AOF日志写盘、加载RDB文件操作、cluster迁移bigKey操作会导致主线程阻塞。

删除bigKey操作、FLUSHDB和FLUSHALL操作异步执行

  当Redis实例收到key-value删除和清空数据库的操作时,主线程会把这个操作封装成一个任务,放入到任务队列中,然后给客户端返回一个完成信息,表明删除已经完成。

  这个时候删除操作还没有执行,等到后台子线程从任务队列中读取任务后,才开始实际删除键值对,并释放相应的内存空间。因此,我们把这种异步删除也称为惰性删除(lazy free)。此时,删除或清空操作不会阻塞主线程,这就避免了对主线程的性能影响。

  Redis 4.0开始提供惰性删除,由两个新的命令支持:

1.key-value删除:当你的集合类型中有大量元素(例如有百万级别或千万级别元素)需要删除时,我建议你使用 UNLINK 命令。

2.清空数据库:可以在 FLUSHDB 和 FLUSHALL 命令后加上 ASYNC 选项,这样就可以让后台子线程异步地清空数据库,如下所示:

> flushdb async OK > flushall async OK AOF日志写盘

  和惰性删除类似,当 AOF 日志配置成 everysec 选项后,主线程会把 AOF 写日志操作封装成一个任务,也放到任务队列中。后台子线程读取任务后,开始自行写入 AOF 日志,这样主线程就不用一直等待 AOF 日志写完了。

从库(slave)加载RDB文件操作

可以查看另外一篇博客:Redis核心技术-高可靠-主从复制

cluster迁移bigKey操作


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有