当前位置: 首页 > 科技观察

程序员过关--请不要误解Redis6.0的多线程

时间:2023-03-22 02:01:18 科技观察

你对redis的单线程有一点误解吗?你是不是对redis6.0的多线程也有一点误解?redis多线程一定能提升性能吗?redis正式发布的6.0版本在业界掀起了一阵热潮。此版本中添加了许多新功能。打开redis官网,可以看到6.0现在是稳定版了。imageredis现在已经成为面试官必问的知识点之一,尤其是新版本加入了“多线程”的概念后,面试题又多了一个问题。Redis单线程Redis6.0之前的版本,很多同学认为是单线程的,其实这种说法严格意义上不是很准确。“单线程”是指接收、解析、执行、返回客户端发送的结果的过程。这个过程由一个线程来处理,这个线程就是主线程。这也是redis中“单线程”定义的来源。但是redis也有其他后台线程处理其他操作,比如一些比较慢的,不适合主线程执行的操作,比如删除大key,重写AOF,生成快照,释放无用连接等。-thread机制大大降低了redis内部代码实现的复杂度和难度。请求按串行顺序顺序执行,大大减少了线程切换带来的资源消耗,并且可以避免锁。一系列的问题。因此,我们在开发和使用redis时,可以实现分布式锁等一系列操作。这与Actor模型中单个actor的行为非常相似。串行操作让我们摆脱了多线程带来的一系列执行顺序。的痛苦。至于为什么redis不用多线程?官方已经对类似问题做出了回复。大致意思就是redis因为CPU成为瓶颈的概率几乎不存在。Redis的性能主要受限于内存和网络。当然,我认为这种解释并不绝对。当redis开启持久化后,吞吐量会明显下降。除非非常必要,否则很多业务场景尽量不要开启redis持久化。Redis单线程瓶颈Redis将所有数据放在内存中。充分利用流水线技术后,QPS可达百万级。这个水平对于普通的中小企业来说已经足够了。即使是更大的请求量,使用redis集群模式也能抗住。但是redis集群也有缺陷:redis集群需要更多的服务器资源来支撑,这无疑增加了公司的开支和资源成本。虽然redis集群可以通过增加副本的方式解决读热键的问题,但是写热键还是有难度的。从redis自身处理请求过程来看,读写网络数据和解析命令占用了大部分的cpu时间,瓶颈在于网络IO的消耗和CPU的利用率不足。要突破这个瓶颈,一般有两种解决方案:网络请求的处理不再依赖内核,而是在用户态处理。但是这种方式需要修改内核网络栈的实现,会带来很大的开发工作量,而且修改核心代码可能会引入新的bug,导致系统不稳定。特点,使用多个IO线程并行处理网络请求。很明显,redis6.0采用了多线程的方式。无论是对于redis集群还是单体架构,提高单机redis的处理速度和吞吐量目前都是有利无害的。Redis的多线程不管redis是使用单线程还是多线程,每个请求的整体处理流程其实是一样的。image整个过程中,读取解析redis客户端命令和返回客户端结果这两个步骤分别对应网络数据的读写。对于redis来说,这两个步骤占用了大部分的cpu时间,所以redis6.0的多线程机制就是针对这两个步骤的。为了更直观更好的理解整个过程,一般分为以下几个步骤:当客户端有新的socket连接时,主线程会负责接收连接,并将socket放入全局等待队列中。事件发生后,这些连接通过循环分配给IO线程。主线程会一直阻塞,直到IO线程读取到Socket并解析。这个解析过程是由多个IO线程并行处理的,所以会很快。等到IO线程解析命令完成,主线程以单线程方式执行这些命令,并将执行结果写入缓冲区,然后阻塞等待IO线程写回socket数据。IO线程读取buffer结果数据,将数据写回socket返回给客户端。这个过程也是由多个IO线程并行处理的,所以会很快。当所有IO线程写回socket后,主线程会清空全局队列,等待下一个新的请求。image从上面的步骤可以看出,IO线程只涉及到socket的读写,实际命令的执行还是由主线程顺序执行。这样既利用了多线程的优点,又保留了单线程的优点,不会有多线程执行命令的问题,比如加锁耗时,key的控制,lua,transaction、LPUSH/LPOP等并发和线程安全问题。》其实关于上面的,我有点不想理解:如果有两个socket,主线程可以保证当有两个socket时,先到达的socket命令数据先执行,但是当有多个时加入IO线程分析并行处理后,原来最先收到的命令能不能先执行呢,希望大佬在评论区指点一下,Redis6.0默认关闭了多线程机制,如果需要开启,请修改redis.conf:io-threads-do-readsyes开启时,必须设置线程数,否则多线程机制不会生效,至于线程数设置,官方有个建议:4核机器建议设置2或3线程,8核机器建议设置6线程,线程数一定要小于线程数机器核心。还应该注意的是,升线程数越多越好。官方认为,超过8个基本没有意义。redis6.0多线程测试Redis作者antirez在RedisConf2019分享时提到:Redis6引入的多线程IO特性,性能提升至少翻了一倍。国内也有大牛用unstable版本在阿里云esc上测试过。GET/SET命令的性能相比4线程IO单线程几乎翻了一倍。”Redis服务器:阿里云Ubuntu18.04,8CPU2.5GHZ,8G内存,主机型号ecs.ic5.2xlargeRedisBenchmarkClient:AlibabaCloudUbuntu18.04,82.5GHZCPU,8G内存,Host型号ecs.ic5.2xlargeimageimage》这些性能验证测试没有针对严格的延迟控制和不同的并发场景进行压力测试。数据仅供验证参考,不能作为在线指标。”如果开启多线程,建议至少使用4核机器,Redis实例已经占用相当大的CPU时间,否则用多线程是没有意义的。所以估计80%的公司开发人员只是看看而已。写在最后,redis6.0利用多线程的优势解决了目前redis的瓶颈问题,同时保留了核心命令执行过程的单线程机制。但是单线程的命令执行机制会不会成为redis未来的瓶颈呢?这就留给评论区的大佬们了!!最后提一个我的问题:redis6开启多线程机制后。有没有可能是socket数据在执行命令的时候不是按照数据到达的先后顺序来的?redis6.0有机制保证这个顺序吗?请在留言区赐教!!本文转载自微信公众号“架构师修行之路”,可关注以下二维码,转载请联系架构师修行之路公众号。