Redis(十三):Redis多线程

1. Redis 3.0前多线程

2. Redis 4.0多线程

3. Redis 6.0多线程

    3.1 线程池初始化

    3.2 读取请求

    3.3 写回响应

    3.4 I/O线程主逻辑

    3.5 性能提升

    3.6 多线程总结 


    如果从Redis的核心网络模型来看,从 Redis 的 v1.0 到 v6.0 版本之前,Redis 的核心网络模型一直是一个典型的单 Reactor 模型:利用 epoll/select/kqueue 等多路复用技术,在单线程的事件循环中不断去处理事件(客户端请求),最后回写响应数据到客户端。这个单线程网络模型一直到 Redis v6.0 才改造成多线程模式。但是从Redis整个数据库服务器而言,这并不意味着整个 Redis 一直都只是单线程。

1. Redis 3.0前多线程

(1)Redis 3.0以前,在执行BGSAVE和BGREWRITEAOF这两条命令时,就会fork一个子进程进行RDB后台持久化和AOF的后台重写。

(2)此外,Redis还创建一个线程数为2的线程池:

bioInit();  // 初始化线程池;

void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3); // 将任务加入线程池:

   专门处理2类异步任务,分别是:

  • REDIS_BIO_CLOSE_FILE:异步关闭文件
  • REDIS_BIO_AOF_FSYNC:异步将缓冲区冲洗到磁盘文件中

2. Redis 4.0多线程

    Redis 在 v4.0 版本的时候就已经引入了的多线程来做一些异步操作,此举主要针对的是那些非常耗时的命令,通过将这些命令的执行进行异步化,避免阻塞单线程的事件循环。

    我们知道 Redis 的 DEL 命令是用来删除掉一个或多个 key 储存的值,它是一个阻塞的命令,大多数情况下你要删除的 key 里存的值不会特别多,最多也就几十上百个对象,所以可以很快执行完,但是如果你要删的是一个超大的键值对,里面有几百万个对象,那么这条命令可能会阻塞至少好几秒,又因为事件循环是单线程的,所以会阻塞后面的其他事件,导致吞吐量下降。

    于是,在 Redis v4.0 之后增加了一些的非阻塞命令如 UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC。UNLINK 命令其实就是 DEL 的异步版本,它不会同步删除数据,而只是把 key 从 keyspace 中暂时移除掉,然后将任务添加到一个异步队列,最后由后台线程去删除,不过这里需要考虑一种情况是如果用 UNLINK 去删除一个很小的 key,用异步的方式去做反而开销更大,所以它会先计算一个开销的阀值,只有当这个值大于 64 才会使用异步的方式去删除 key,对于基本的数据类型如 List、Set、Hash 这些,阀值就是其中存储的对象数量。

    Redis 在 v4.0 版本的时候就异步任务由两类增加到了3类,此时需要初始化线程数为3的线程池,需要处理的3类异步任务为:

  • BIO_CLOSE_FILE:异步关闭文件
  • BIO_AOF_FSYNC :异步将缓冲区冲洗到磁盘文件中
  • BIO_LAZY_FREE :异步删除键值对

  线程池提供的外部接口函数为:

void bioCreateCloseJob(int fd);    // 创建关闭文件的异步任务

void bioCreateFsyncJob(int fd);    // 创建冲洗文件缓冲区的异步任务

void bioCreateLazyFreeJob(lazy_free_fn free_fn, int arg_count, ...); // 创建删除键值对的异步任务

3. Redis

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值