

和 杠精 聊Redis多线程 :(
source link: https://mp.weixin.qq.com/s?__biz=MzA4MTc4NTUxNQ%3D%3D&%3Bmid=2650522713&%3Bidx=1&%3Bsn=274194f7b2a190c1a47e60c2eb429f7f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

不羡鸳鸯不羡仙,一行代码调半天。原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。
周末被一位小同学憋的很窝火。他要和我探讨一下,redis到底是多线程的还是单线程的。这个问题本来比较好解释,但我遇到的却是一个杠精。
答案是显而易见的:redis6,逃不过真香定理,引入了多线程;而在redis6之前,却是单线程的。
也就是说,这不是一个是和否的问题,还涉及到第二维度的 版本
参与。
可是,这位同学要打我的脸。不知道小姐姐的脸皮很嫩么?摸不得。
“照你的逻辑,redis5是单线程的了?”
“是的。”
“那下面这张截图是怎么回事?”
同学甩给我一张图,并送来一个鄙视的眼神。
“使用 top -Hp
查看。redis5有4个线程。该怎么解释?”
这个问题,我也不知道怎么跟他解释。使用top命令去观测,redis5肯定是多线程的,比如 bgsave
, aof
等,肯定要开启一个线程去操作,否则早就炸了。
按照这个逻辑去说,redis就从来没有单进程过。看着这张图,我陷入了无尽的忧愁。
“Redis是否是单进程,主要是针对Redis的读写操作来说的”。但这句话对于杠精并没有什么信服力。
“写程序要严谨,你们这些人都太不严谨了。多线程就是多线程,你应该问'redis的读写操作到底是不是多线程的'”。
我问你个大头鬼。我并不想再和他交流,因为我为自己的博学感到无地自容。
但他接下来的一个问题,却让我陷入了真正的沉思。
1. redis的多线程有多快?
redis的多线程到底有什么性能提升呢?
官方的说法是: possible to easily speedup two times
。可能会比较容易的提升到两倍速度。
我英文不太好,对这种英文的修饰感到很迷惑。既然 easily
了,为什么还有 possible
。 two 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 32 164519.20 requests per second 165411.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,欢迎添加好友,进一步交流。
推荐阅读:
Recommend
-
61
流言止于智者,聊天止于呵呵。 在 2013 年之前,“呵呵”还只是呵呵,然而风云突变,这个一直被用作表达礼貌、微笑的词汇,却在 2013 年被网友...
-
104
职场话题 - @leoyanpc - 领导丢过来一个新人让带一带,今年刚毕业,技术还可以。缺点是太能抬杠了,分配的任务,总是质疑为什么,该做的还没有做,就非要和我探讨有没有更好的实现手段。讨论一件事情的时候,总是想绕着弯,举例子证明自
-
56
程序员 - @gdky005 - 前两天吐槽一个开源库 OkGo, 今天有一个杠精,非要跟我说不对,我意识到自己可能之前的话语比较激进,遂改之。结果这个杠精就纠缠上了,不好别用,有本事别删除之类的,真奶奶的虐心。不回复吧,邮件一直提醒
-
65
运营一个2.2亿用户规模的社区,算法可能是最优解。
-
57
杠精之所以为杠精
-
37
从 CHERRY 中国上热搜聊起
-
47
空中突然传来巨大的键盘打字声。中士举着望远镜在教堂钟楼上:“上尉!博主又开始写稿了!11点钟方向!目…
-
19
随想 - @Raven316 - 杠精的定义:享受和人杠的感觉并且争论的目的不是为了寻求真理而是单纯为了获得争论胜利的人。我想起上高中时一位朋友告诉我的观点:攻击一个人最好的方法不是攻击他不存在的短处,而是攻击他确实存在的短处
-
17
不想弹好吉他的撸铁狗,都不是好的程序猿 虽然说单机的Redis性能很好,也有完备的持久化机制,那如果你的业务体量真的很大,超过了单机能够承载的上限了怎么办?不做任何处理的话Redis挂了怎么办?带着这个问题开始我们今天的主...
-
3
杠精的圣经:维基百科认知偏差大全 - Buster Benson杠精的圣经:导致维基百科中200种偏见的4个宇宙难题:宇宙有 4 种品质限制了我们自己的智力以及其他所有人的智力:集合、有机复杂系统、机械、外星人或可以想象的上帝。我们已知的所有 200 左右的偏见...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK