不羡鸳鸯不羡仙,一行代码调半天。原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

周末被一位小同学憋的很窝火。 他要和我探讨一下,redis到底是多线程的还是单线程的。这个问题本来比较好解释,但我遇到的却是一个杠精。

答案是显而易见的:redis6,逃不过真香定理,引入了多线程;而在redis6之前,却是单线程的。

也就是说,这不是一个是和否的问题,还涉及到第二维度的版本参与。

可是,这位同学要打我的脸。不知道小姐姐的脸皮很嫩么?摸不得。

“照你的逻辑,redis5是单线程的了?”

“是的。”

“那下面这张截图是怎么回事?”

同学甩给我一张图,并送来一个鄙视的眼神。

“使用top -Hp 查看。redis5有4个线程。该怎么解释?”

这个问题,我也不知道怎么跟他解释。使用top命令去观测,redis5肯定是多线程的,比如bgsaveaof等,肯定要开启一个线程去操作,否则早就炸了。

按照这个逻辑去说,redis就从来没有单进程过。看着这张图,我陷入了无尽的忧愁。

“Redis是否是单进程,主要是针对Redis的读写操作来说的”。但这句话对于杠精并没有什么信服力。

“写程序要严谨,你们这些人都太不严谨了。多线程就是多线程,你应该问’redis的读写操作到底是不是多线程的’”。

我问你个大头鬼。我并不想再和他交流,因为我为自己的博学感到无地自容。

但他接下来的一个问题,却让我陷入了真正的沉思。

1. redis的多线程有多快?

redis的多线程到底有什么性能提升呢?

官方的说法是:possible to easily speedup two times。可能会比较容易的提升到两倍速度。

我英文不太好,对这种英文的修饰感到很迷惑。既然easily了,为什么还有possibletwo times,到底是提升了2倍,还是提升到2倍。

官方说,到底能够提升多少,还要看硬件的能力。

官方推荐,只有你的CPU核数,达到4个的时候,才有必要试一试这个多线程的Feature。

不要用土豪的眼睛盯着我,这种4core的配置,已经打死了大多数公司了。所以Redis贴心的把多线程功能是关闭的。(好像有点语病)

我只能求助那些在一线的前同事们。他们有没有在生产环境,用上这划时代的多线程Redis6x呢?

结果很令我满意,没有!

其中有一个回复我特别满意。他说:“你竟然在问一个停留在JDK1.6的我,跑着Windows版本Redis的我,是否用到了Redis6。我还在用着Redis3呢。”

另外一个回复我感到更满意,他说:“滚!”

2. 怎么用?

新技术肯定是要吹捧一下的,否则没人实践踩坑,作为追随者就只能吃翔。

多线程在理论上,肯定是会有性能提升的。一个爸爸赚钱和2个爸爸赚钱,效果自然不一样,只是苦了妈妈了。

Redis6的多线程开启,需要配置一个参数。

io-threads 4

当开启之后,只有出流量使用多线程,如果你想要入流量也走多线程,那也可以配置以下参数。

io-threads-do-reads yes

就这么两个参数,可以看到现在的redis多线程,还是稍显寒碜了一些。

我们把它开启之后,仍然使用top -Hp 查看相关进程,可以看到多了3个io_thd进程。

这部分逻辑,是在networking.c种实现的。这个文件已经达到了3k多行,也是够庞大的了。

3. Redis为什么又搞多线程了

使用redis-benchmark测试,单机单核的吞吐量,能够达到10w+。

1秒是1000000000纳秒,单次内存操作大约是100纳秒左右,那内存操作可以达到1000w/s的速度。那Redis的瓶颈在哪里呢?

使用perf进行追踪,可以发现它的耗时,主要是体现在sys_write系统调用上,也就是向socket写数据。

既然瓶颈找到了,那就把它优化掉。redis选择的方式是使用多线程。

我使用benchmark测试了一下,4core的机器,CPU跑满的时候,QPS达到了16w,并没有翻倍(相对于单核的9w/s)。

benchmark 6379 clients 32164519.20 requests per second165411.09 requests per second

用这么强的硬件,获得这样有限的性能提升,差强人意。

这就不难解释为什么现在实践的人那么少。出了因为新,还是不够吸引人。

毕竟,4core的机器,我部署上3台redis cluster的实例,理论上会提升三倍呢。

redis配置文件里,有不少内容在注释这个新特性。

4. 怎么实现?

如图,一次redis请求,要建立连接,然后获取操作的命令,然后执行命令,最后将响应的结果写到socket上。

在redis的多线程模式下,获取、解析命令,以及输出结果着两个过程,可以配置成多线程执行的,因为它毕竟是我们定位到的主要耗时点。

但命令的执行,也就是内存操作,依然是单线程运行的。

这种设计造成了一个特性。

redis现在依然没有多线程的锁竞争和线程安全问题,因为它的数据读取这一步骤,仍然是单线程的,要排队运行。一些耗时的操作,比如keys *hgetall等,仍然要注意。

redis并不是传统的reactor模型,说实话很多东西硬套概念的话肯定只能钻进个头去漏出个尾巴。它也并不是master,worker这种干干净净的类似于memcached的模型,因为它把命令执行操作给抽取出来了。其中缘由,看上面这张图就够了。

End

那么,下一个吸引杠精的问题难题来了:在这种多线程应用场景下,redis算是I/O密集型,还是计算密集型呢?

或许,如果redis多线程中,无处不在的轮询,属于“计算”的话,它算是一个计算密集型应用吧。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,​进一步交流。​

redis 多线程_唬人的Redis多线程,也就那么回事相关推荐

  1. linux redis客户端_为什么单线程Redis能那么快?

    我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程.但 Redis 的其他功能,比如持久化.异步 ...

  2. 狂神redis笔记_狂神说redis笔记(一)

    一.Nosql概述 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以下问题: 数据量增加到一定程度,单机数据库就放不下了 数据的索引(B+ ...

  3. java第七章多线程_第七章 多线程

    7 多线程 7.1 进程和线程 1.进程进程是一个正在执行中的程序 每一个进程都有一个执行顺序,该顺序是一个执行路径,或者叫做一个控制单元 2.线程线程就是进程中的一个独立控制单元 线程在控制着进程的 ...

  4. php redis 投票_高可用Redis服务架构分析与搭建

    HorstXuhttps://www.cnblogs.com/xuning/p/8464625.html 基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经 ...

  5. 狂神redis笔记_狂神说redis笔记(三)

    八.Redis.conf 容量单位不区分大小写,G和GB有区别 可以使用 include 组合多个配置问题 网络配置 日志 # 日志 # Specify the server verbosity le ...

  6. 易语言 mysql多线程_易语言数据库多线程 易语言数据库教程

    为什么易语言两个线程同时对一个MYSQL数据? 数据库有自己的连接锁定机制.如果同一台机器使用同一接口插入,则多线程和单线程是相同的. 除非您有多个数据库服务器,然后使用多线程来完成上述工作,否则效率 ...

  7. 单线程多线程_面试系列 redis为什么快amp;单线程amp;多线程

    redis为什么这么快 C语言实现,执行速度快 纯内存操作,数据读写在内存中,异步持久化到磁盘 丰富和高效的数据结构 基于非阻塞的I/O多路复用机制 单线程避免了上下文切换 Redis单线程 redi ...

  8. python3 多线程_图解|为什么 Python 多线程无法利用多核

    (给Python开发者加星标,提升Python技能) 来源:后端技术指南针 1.全局解释锁 如题: Python的多线程为什么不能利用多核处理器? 全局解释器锁(Global Interpreter ...

  9. 什么是java多线程_什么是java多线程,java多线程的基本原理?

    1.什么是多线程? 多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率.线程是在同一时间需要完成多项任务的时候被实现的. 2.线程的工作原理: 每当我们开启一个线程的时候,线程会为我们 ...

最新文章

  1. 【Codeforces】716B Complete the Word (26个字母)
  2. React之渲染元素
  3. IBM投资4000万美圆,加强对SAP®应用的支持
  4. java newline_Java BufferedWriter.newLine()方法示例
  5. hdu4604 不错的子序列问题
  6. oracle知识汇总
  7. directive多指令之间的异步调用
  8. 下拉默认选择_在Excel中制作二级联动下拉菜单,太有用了
  9. linux 双网卡bond命令,Linux的双网卡绑定(即bond0)
  10. androidstudio 评论栏_android-studio 添加没有菜单栏和actionBar的模板
  11. QT之实现斗鱼直播PC客户端
  12. android离线身份证识别(从相册选择)
  13. Uber中国获10亿美元融资,路演PPT曝光!
  14. 网络图库Cytoscape.js的使用(一):初始化配置
  15. 正确使用#include和前置声明(forward declaration)
  16. shell脚本保姆级教程,附赠100个shell脚本案例!
  17. Unicast RPF,单播逆向转发
  18. iPhone与小米的体验对比(一)
  19. 鼠标掠过显示图片的demo
  20. 人工智能与机器学习-梯度下降法

热门文章

  1. MySQL8权限,角色
  2. 关于fetch api这点事
  3. 今天开通一个真正属于自己的博客了《L.M》
  4. H265编码等级以及图像的基础知识
  5. E - More is better (并查集)
  6. 用户设置及用户默认设置
  7. HDU 2242 双连通分量 考研路茫茫——空调教室
  8. JVM JRE JDK,这些东西到底是什么?(转载)
  9. WCF系列(1)—— CustomBehavior 入门
  10. 如何将SAP数据传输到其他系统(Transferring Data from SAP to Other Systems)