你对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自身的处理请求过程来看,对网络数据的读写以及对命令的解析占用了大部分cpu时间,瓶颈在于网络IO的消耗以及对CPU不能充分的利用。而要突破这个瓶颈呢,一般有两种解决方案:
网络请求的处理不再依靠内核,而在用户态处理。但是这种方式需要修改内核网络栈的实现方式,这会带来很多开发工作量,而且设计到核心代码修改,可能会引入新的bug,导致系统不稳定
利用多线程优势,充分利用服务器多核的特性,采用多个IO线程来并行处理网络请求。
很显然,redis6.0采用的是多线程的方式。
无论是针对redis集群,还是针对单体架构,提高单机redis的处理速度和吞吐量目前看百利而无一害。
redis多线程
无论redis采用单线程还是多线程,其实每个请求的整体处理流程是一致的。
image
在整个流程中,读取解析redis客户端命令和返回客户端结果两个步骤分别对应网络数据的读取和写入,这两个步骤对于redis来说,占用了大部分cpu时间,所以redis6.0多线程机制是针对这两个步骤的。
为了直观的更好了解整个流程,一般分为以下几个步骤:
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 是否有机制来保证这个顺序呢?请大佬在留言区赐教!!
本文转载自微信公众号「架构师修行之路」,可以通过以下二维码关注。转载本文请联系架构师修行之路公众号。
2020年以来,由疫情停工减产所导致的缺芯困局影响着全球汽车发展,而本以为2021...
【51CTO.com快译】数字化转型使应用程序领导人必须找到有效的方法来更新改造遗留...
在疫情的影响下,人们的工作和生活方式在过去的一年发生了前所未有的变化。为了...
根据TrendForce的最新调查,自2020年初以来,COVID-19流感大流行加速了世界各地...
人头马君度(Rmy Cointreau)的历史非常重要,这家酒业公司以将最好的酒陈化100年...
时间真快呀!转眼又至周一。让我们卯足干劲继续前行,先来看看上周有哪些不容错...
本文中的五个步骤有助于您掌握转型的总体需求,并有助于您处理一些真正重要的事...
根据调查,随着用户对计算能力、存储和网络容量的需求增长,服务器需求比经济不...
在VMworld 2020,VMware宣布与NVIDIA进行全面合作,共同推出新一代的混合云架构...
2020年11月26日深圳潮数科技于石家庄成功召开数据安全 新时代新基建信息应用之基...