泉州官方网站,国家林业工程建设协会网站,郴州网约车,网站推广优化如何做01——Redis单线程与多线程
一、Redis是单线程还是多线程
在谈Redis的单线程或多线程时#xff0c;需要根据版本来区分。
在redis 3.x之前#xff0c;redis是单线程的从redis 4.x开始#xff0c;redis引入多线程。处理客户端请求时#xff0c;使用单线程#xff1b;在异…01——Redis单线程与多线程
一、Redis是单线程还是多线程
在谈Redis的单线程或多线程时需要根据版本来区分。
在redis 3.x之前redis是单线程的从redis 4.x开始redis引入多线程。处理客户端请求时使用单线程在异步删除等操作时使用多线程在2020年发布的6.x以及2022年发布的7.x版本使用全新的多线程来解决问题。
Redis重要里程碑
Redis 2.6 支持lua脚本Redis 3.0 支持集群Redis 4.0 混合持久化、多线程异步删除Redis 5.0 核心代码重构Redis 6.0 多线程IO 二、Redis为什么选择单线程
Redis单线程
定义主要是指Redis的网络IO和键值对读写是由一个线程来完成的Redis在处理客户端的请求时包括获取Socket读、解析、执行、内容返回Socket写都是由一个顺序串的主线程处理这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。 但是Redis的其他功能比如持久化RBD、AOF、异步删除、集群数据同步等其实是由额外的线程执行的。
Redis命令工作线程是单线程的但是对整个Redis来说是多线程的。
Redis在3.x版本时性能依旧很快的主要原因
基于内存操作 Redis的所有数据都存在内存中因此所有的运算都是内存级别的数据结构简单 Redis的数据结构是专门设计的而这些简单的数据结构的查找和操作时间复杂度都是O(1)多路复用和非阻塞IO Redis使用IO多路复用功能来监听多个socket连接客户端这样就可以使用一个线程连接来处理多个请求减少线程切换带来的开销同时也避免了IO阻塞操作避免上下文切换 因为是单线程模型因此就避免了不必要的线程上下文切换和多线程竞争省去了多线程切换带来的时间和性能上的消耗
在多CPU时代Redis如何使用多个CPU
官网Redis是基于内存操作的因此Redis的瓶颈可能是机器的内存或网络带宽而非CPU。既然CPU不是瓶颈那么自然采用单线程。但是在Redis4.0中开始支持多线程了例如后台删除、备份等功能。
三、为什么Redis加入了多线程特性
单线程的痛点 正常情况下使用del删除数据很快但是删除一个非常大的key则会导致Redis主线程卡顿。 解决方案使用惰性删除把删除数据的工作交给后台的其他线程来完成。 unlink keyflushdb asyncflushall async 本质上来说就是将耗时的操作从主线程剥离交给BIO子线程来处理减少主线程阻塞时间从而减少因为耗时操作导致的性能和稳定性问题。
四、Redis多线程特性和IO多路复用
Redis性能影响因素
CPU官网文档说明CPU不大可能是Redis的性能瓶颈内存在当下的开发环境中内存越来越便宜因此内存也不性能瓶颈网络IO因为Redis从网络IO处理到实际的读写命令处理都是由单个线程完成的所以网络IO可能会成为Redis的性能瓶颈。
单个线程处理网络请求的速度有可能跟不上底层网络硬件的速度。为了应对这个问题Redis6、7采用多个IO线程来处理网络请求提高网络请求处理的并行度。
Redis只是使用多线程来处理网络IO操作此操作可以提升实例的整体处理性能。执行命令操作还是单线程这就不用开发多线程的互斥枷锁机制。因此Redis线程模型的实现就很简单。
主线程和IO线程是怎么协作完成请求处理的 阶段一服务端和客户端建立Socket连接并分配处理线程 首先主线程负责接收建立连接的请求。当有客户端请求和实例建立Socket连接时主线程会创建和客户端的连接并把Socket放入全局等待队列中。紧接着主线程通过轮训方法把Socket连接分配给IO线程。 阶段二IO线程读取并解析请求 主线程一旦把Socket分配给IO线程就会进入阻塞状态等待IO线程完成客户端请求读取和解析。因为有多个IO线程在并行处理所以这个过程很快就可以完成。 阶段三主线程执行请求操作 等到IO线程解析完请求主线程还是会以单线程的方式执行这些命令操作。 IO线程回写Socket和主线程清空全局队列 当主线程执行完请求操作后会把需要返回的结果写入缓冲区。然后主线程阻塞等待IO线程把结果写回到Socket中并返回给客户端。和IO线程读取解析一样IO线程回写Socket时也是多个线程并发执行所以速度很快。等到IO线程回写Socket完毕主线程会清空全局队列等待客户端的后续请求。 Unix网络编程中的五种IO模型: Blocking IO阻塞IO NoneBlocking IO非阻塞IO IO multiplexingIO多路复用 Linux世界一切皆文件 文件描述符简称FD、句柄 IO多路复用是什么 一种同步的IO模型实现一个线程监视多个文件句柄一旦某个文件句柄就绪就能通知到对应的应用程序进行相应的读写操作没有文件句柄就绪时就会阻塞应用程序从而释放CPU资源。 IO网络IO在操作系统层面指数据在内核态和用户态之间的读写操作多路多个客户端连接连接就是套接字描述符即socket或者channel复用复用一个或几个线程IO多路复用也就是说一个或一组线程处理多个TCP连接使用单进程就能够实现同时处理多个客户端的连接无需创建或者维护过多的进程、线程实现IO多路复用的模型有三种select、poll、epoll epoll 总结 Redis问什么这么快 IO多路复用epoll函数才是redis为什么这么快的直接原因而不是单线程命令redis安装在内存中。 signal driven IO信号驱动IO asynchronous IO异步IO
五、Redis7是否默认开启多线程
如果在实际应用中发现redis CPU开销不大但吞吐量却没有提升可以考虑使用redis7的多线程机制加速网络处理进而提升实例的吞吐量。
Redis7讲所有的数据放在内存中内存的响应时长大约是100纳秒对于小的数据包Redis服务器可以处理8w到10w的QPS这也是Redis处理的极限对于大多数业务来说单线程Redis已经足够使用了。
在redis6、7中多线程机制默认是关闭的如果需要使用redis多线程功能需要修改redis.conf配置文件
# 启用多线程
io-thread-do-reads yes
# 设置线程个数。官方建议4核cpu线程数设置为2或38核cpu设置为6。线程数一定要小于机器核数线程数并不是越大越好
io-threads 6六、总结