你对redis的单线程是不是有点误会?

你对redis 6.0的多线程是不是也有点误会?

redis多线程一定可以提高性能吗?

redis官方刚刚发布的6.0版本已经掀起了业界一阵热波,在这个版本中新加了很多新特性,如果你打开redis的官网,可以看到6.0现在已经是稳定版本了。

image

redis现在已经成为了面试官必问的知识点之一,尤其是当新版本加入了“多线程”概念之后,面试题又是增加了一道难题。

redis单线程

redis在6.0之前的版本,很多同学认为是单线程,其实这个说法严格意义上来讲不太准确。“单线程”是指客户端发送的命令的接收,解析,执行,结果返回这个过程是由一个线程处理,这个线程就是主线程,这也是redis素有“单线程”定义的来源。

但是,redis也有其他后台线程在处理其他操作,比如那些比较慢,不太适合放主线程执行的操作,例如大key的删除,AOF的重写,快照的生成,无用连接的释放等。

单线程机制使得redis内部代码实现的复杂度和难度大大降低,请求都是按照串行化的顺序来依次执行,这大大降低了由于线程切换带来的资源消耗,而且又可以避免锁带来的一系列问题。所以平时开发使用redis的时候,我们可以实现分布式锁等一系列骚操作,这和Actor模型中,单个Actor的行为十分类似,串行的操作使我们可以摆脱多线程带来的一系列执行顺序的痛苦。

至于redis为什么不使用多线程呢?官方曾经做过类似问题的回复,大体意思是,redis由于cpu成为瓶颈的几率几乎不存在,redis的性能主要受限于内存和网络,当然,我认为这个解释并非是绝对的。当redis开启持久化之后,吞吐量会大幅度下降,除非非常必要,不然在很多业务场景下尽量不要开启redis的持久化。

redis单线程瓶颈

redis将所有数据放在内存中,在充分利用pipelining技术的情况下,QPS可达百万,这个量级对于普通的中小公司已经足以,就算是再大一点的请求量,利用redis集群方式也能抗住。但是redis集群也是有缺陷的:

  • redis集群需要更多的服务器资源来支撑,这无疑加大了公司的支出费用和资源成本。

  • redis集群虽然可以通过增加副本的方式来解决热点key的读问题,但是热点key的写依然比较棘手

从redis自身的处理请求过程来看,对网络数据的读写以及对命令的解析占用了大部分cpu时间,瓶颈在于网络IO的消耗以及对CPU不能充分的利用。而要突破这个瓶颈呢,一般有两种解决方案:

  • 网络请求的处理不再依靠内核,而在用户态处理。但是这种方式需要修改内核网络栈的实现方式,这会带来很多开发工作量,而且设计到核心代码修改,可能会引入新的bug,导致系统不稳定

  • 利用多线程优势,充分利用服务器多核的特性,采用多个IO线程来并行处理网络请求。

很显然,redis6.0采用的是多线程的方式。

无论是针对redis集群,还是针对单体架构,提高单机redis的处理速度和吞吐量目前看百利而无一害。

redis多线程

无论redis采用单线程还是多线程,其实每个请求的整体处理流程是一致的。

image

在整个流程中,读取解析redis客户端命令和返回客户端结果两个步骤分别对应网络数据的读取和写入,这两个步骤对于redis来说,占用了大部分cpu时间,所以redis6.0多线程机制是针对这两个步骤的。

为了直观的更好了解整个流程,一般分为以下几个步骤:

  1. 当客户端有新的socket连接时,主线程会负责接收连接,并把socket放入全局的等待队列中,当主线程处理完读事件之后,通过轮训的方式将这些连接分配给IO线程。

  2. 主线程会一直阻塞到IO线程读取Socket并解析完毕,这个解析过程是多个IO线程并行处理的,所以会很快。

  3. 等到IO线程解析命令完成,主线程以单线程的方式来执行这些命令,并把执行结果写入缓冲区,然后阻塞的等待IO线程回写socket数据

  4. IO线程读取缓冲区结果数据,把这些数据回写socket,返回给客户端。这个过程也是多个IO线程并行处理的,所以也会很快。

  5. 当所有的IO线程回写socket完毕,主线程回清空全局队列,等待下次新的请求到来。

image

从以上步骤可以看出,IO线程只涉及到socket的读和写,而实际命令的执行还是主线程以顺序化的方式来执行,这不仅仅是利用多线程的优势,同时又保留了单线程的优势,在命令执行上不会产生多线程的一系列问题,比如加锁带来的耗时,控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。

其实关于上面所说,我有一点没想明白:假如有两个socket,在单线程的时候,主线程可以保证优先到来的socket命令数据优先被执行,但是在加入了多个IO线程并行解析过程之后,本来先接收的命令是否可以保证优先执行呢?希望大佬在评论区给予指点

redis 6.0默认是禁用多线程机制的,如果需要开启,请修改redis.conf:

io-threads-do-reads yes

开启时候还要设置线程数,否则多线程机制是不生效的。至于设置多少个线程,官方有一个建议:4核的机器建议设置为2或3个线程,8核的建议设置为6个线程,线程数一定要小于机器核数。还需要注意的是,线程数并不是越大越好,官方认为超过了8个基本就没什么意义了。

redis6.0多线程测试

Redis 作者 antirez 在 RedisConf 2019 分享时曾提到:Redis 6 引入的多线程 IO 特性对性能提升至少是一倍以上。国内也有大牛曾使用 unstable 版本在阿里云 esc 进行过测试,GET/SET 命令在 4 线程 IO 时性能相比单线程是几乎是翻倍了。

Redis Server:阿里云 Ubuntu 18.04,8 CPU 2.5 GHZ, 8G 内存,主机型号 ecs.ic5.2xlarge Redis Benchmark Client:阿里云 Ubuntu 18.04,8 2.5 GHZ CPU, 8G 内存,主机型号 ecs.ic5.2xlarge

image

image

这些性能验证的测试并没有针对严谨的延时控制和不同并发的场景进行压测。数据仅供验证参考而不能作为线上指标。

如果开启多线程,至少要4核的机器,且Redis实例已经占用相当大的CPU耗时的时候才建议采用,否则使用多线程没有意义。所以估计80%的公司开发人员看看就好。

写在最后

redis6.0利用多线程的优势很好的解决了当前redis的瓶颈问题,同时又保留了核心命令执行过程单线程机制。不过将来单线程的命令执行机制会不会是redis的瓶颈呢?这个留给大佬们在评论区!!

最后提出一个我的疑问:redis6.0在启用了多线程机制之后,那先后到达的socket数据,在命令执行的时候是否有可能不是按照数据到达的顺序呢?redis6.0 是否有机制来保证这个顺序呢?请大佬在留言区赐教!!

程序员过关斩将--论系统设计的高可扩展性

程序员过关斩将--从未停止过的系统架构设计步伐

程序员过关斩将--真的可以用版本号的方式来保证MQ消费消息的幂等性?

程序员过关斩将--请不要误会redis 6.0 的多线程相关推荐

  1. 程序员过关斩将--少年派登录安全的奇幻遐想

    " 据说,这篇也是快餐,完全符合年轻人口味 说到登录,无人不知无人不晓.每一个有用户体系的相关系统都会有登录的入口,登录是为了确认操作人的正确性.说到登录安全,其实是一个很伟大的命题,不过常 ...

  2. 程序员修神之路--redis做分布式锁可能不那么简单

    点击上方"蓝字"带你去看小星星 菜菜哥,复联四上映了,要不要一起去看看? 又想骗我电影票,对不对? 呵呵,想去看了叫我呀 看来你工作不饱和呀 哪有,这两天我刚基于redis写了一个 ...

  3. 程序员过关斩将--你为什么还在用存储过程?

    点击上面"蓝字"关注,带你看好电影 菜菜哥,我新接手了一个项目,看的我头疼呀 业务有这么复杂呀? 不是的,这个老项目完全是用存储过程写的,每个存储过程都好几百行 这样呀,是够头疼的 ...

  4. 程序员过关斩将--redis做消息队列,香吗?

    菜菜哥,我刚做完了一个订单系统,感觉很简单呀 说说看,大量的订单状态怎么处理的? 我设计的时候可是考虑了这一点,所以用了异步处理,采用了MQ 那用的什么MQ呢,透露一下呗 我用的redis做的MQ,很 ...

  5. 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?

    " 灵魂拷问: 应对高并发系统有没有一些通用的解决方案呢? 这些方案解决了什么问题呢? 这些方案有那些优势和劣势呢? 对性能孜孜不倦的追求是互联网技术不断发展的根本驱动力,从最初的大型机到现 ...

  6. 程序员过关斩将--解决分布式session问题

    微信搜一搜 架构师修行之路 session 说到 session,我相信每个程序员都不陌生,或多或少在项目中使用过.session 这个词,其实是一个抽象的概念,它不像 Cookie 那样有着明确的定 ...

  7. 程序员过关斩将--cookie和session的关系其实很简单

    喜欢就点关注吧! 月高风下,下班路上.... 菜菜哥,告诉你一个秘密,但是不允许告诉任何人 这么秘密,你有男票了?~ 不是,昨天我偷偷去面试了,结果挂了 这不是好事吗,上天让公司留住你..... 好吧 ...

  8. 程序员过关斩将--Http请求中如何保持状态?

    微信搜一搜 架构师修行之路 这是一个被无数程序员撸过的问题,却只有少数人了解了真相.大体上搜了一下,网上关于http协议保持状态误导大家的文章还是有的,比如:有人说利用ViewState,那是asp. ...

  9. 程序员过关斩将--作为一个架构师,我是不是应该有很多职责?

    点击上方"蓝字"关注我们领取架构书籍 每一个程序员都有一个架构梦. 上面其实本质上是一句富有事实哲理的废话,要不然也不会有这么多人关注你的公众号.这些年随着"企业数字化& ...

最新文章

  1. linux yum命令详解
  2. 模型花费几十万美元,五年之间指导无数项目,才发现负样本用的是null?
  3. django一个html先后两个form,django 一个页面两个表单 怎么提交
  4. HNCU 1741: 算法3-2:行编辑程序
  5. (三)Docker四种网络模式
  6. C语言重新定位文件,C语言代码重定位 (原创)
  7. 正则去除html行内样式,Android-富文本处理-html字符串去掉内部样式,统一添加body、style,统一支持换行等...
  8. LeetCode之Palindrome Number(回文数)
  9. thymealf 高级用法_Thymeleaf
  10. python导入requests库一直报错原因总结_python pip 安装库文件报错:pip install ImportError: No module named _internal...
  11. 沃尔玛牵手Gatik推行自动驾驶试点项目 为客户配送订单
  12. OpenShift 4 - 通过DaemonSet在指定Node上运行守护程序
  13. ElementUI-学生管理系统后台实例
  14. 【语音处理】基于matlab GUI音频数据处理【含Matlab源码 1734期】
  15. antd使用阿里巴巴矢量图标
  16. Context and Attribute Grounded Dense Captioning
  17. URAL 1389 Roadworks 贪心
  18. 微信公众平台 个人微信号订阅号发图文文章 总显示发送失败
  19. Microsemi Libero使用技巧1——查看芯片资源占用情况
  20. 高德地图看各省分界线_高德地图API生成地图(含有各个省份边界线)

热门文章

  1. windows 安装yaml支持和pytest支持等
  2. canvas特效代码详解(2)
  3. 驱动之LCD的介绍与应用20170209
  4. SharePoint 2010 master page 控件介绍(5):其他
  5. 博客园2013年5月份第1周源码发布详情
  6. DotNetMagic 5.4.0破解
  7. Kinect开发笔记之二Kinect for Windows 2.0新特性
  8. 在Teams app代码中enable nullable
  9. twitter推文不收录_如何使用Twitter书签保存推文供以后使用
  10. 下载: 虾米音乐_您所说的内容:如何组织凌乱的音乐收藏