首页 > 编程知识 正文

redis单线程多路复用,为什么redis快

时间:2023-05-05 15:43:40 阅读:130347 作者:4310

Redis线程模型消息处理进程I/O复用器实现文件事件类型文件事件处理器连接响应处理器命令请求处理器命令响应处理器为什么Redis是单线程Redis快

线程模型

Redis基于Reactor模式开发了自己的网络事件处理器。 该处理器被称为http://www.Sina.com/(文件事件处理程序)

文件处理器使用文件事件处理器,访问I/O 多路复用(multiplexing)程序

套接字相关(动词)根据套接字当前正在执行的任务而不同的监听 多个套接字-Socket

消息处理流程在套接字-套接字准备执行连接响应(accept )、读取(read )、写入(right )、关闭(close ) )等操作时,发生与操作对应的文件事件

此时,3358www.Sina.com/或事件处理器套接字-套接字-套接字之前相关联的3358www.Sina.com/为http://www.Sina.com

虽然可能同时发生多个文件事件,但文件事件处理器始终有调用事件发生的3358www.Sina.com/在一个队列中

然后,通过该队列,有序地(sequentially )、同步地(synchronously ),对每个套接字以套接字-Socket方式向文件事件调度器传输套接字

I/O复用器在处理了在前一个套接字-套接字中生成的事件之后,由与该事件相关联的事件处理器执行该套接字-套接字,然后在事件处理器中发送下一个套接字

I/O多路复用器实现“多路复用”是指多个网络连接

“复用”是指复用同一线程

复用I/O复用技术使单个线程能够高效地处理多个连接请求。 可以将网络I/O的时间消耗降到最低

Redis在内存中操作数据的速度非常快,这意味着内存中的操作不会成为影响Redis性能的瓶颈

redis I/O复用程序的所有功能都是通过包装I/o复用函数库实现的,如选择、轮询、ev端口和kqueue

每个I/O复用库都对应于Redis源代码中的一个单独文件

因为Redis为每个I/O复用库实现了相同的API,所以I/O复用程序的基本实现是兼容的

Redis在I/O多路复用器的实现源代码中用#include宏定义了适当的规则

程序在编译时自动选择系统中性能最高的I/O复用函数库作为redis I/o复用程序的基础

文件类型I/O复用器可以接收多个套接字的ae.h/AE_READABLE和ae.h/AE_WRITABLE事件

这些事件与套接字操作的对应关系如下。

套接字变为可读时(客户端可以对套接字执行write操作, 执行close操作)或新的响应)套接字出现时)客户端对服务器的监听套接字执行connect操作)套接字生成AE_READABLE事件对套接字可写入时) 套接字生成的AE_WRITABLE事件I/O复用器允许服务器同时接收套接字的AE_READABLE和AE_WRITABLE事件

如果套接字同时生成这两个事件,则文件事件调度程序将优先处理AE_READABLE事件,并且在处理AE_READABLE事件之前不会处理AE_WRITABLE事件

也就是说,如果套接字是可读和可写的,则服务首先读取套接字,然后写入套接字

文件事件处理器Redis为文件事件创建了多个处理器。 这些处理器分别用于满足不同的网络通信要求。 典型的处理器包括:

连接应答处理器为了应答与服务器连接的各客户端,服务器为了接收插座相关命令而与处理器命令要求处理器连接,为了接收来自客户端的命令要求,服务器针对客户端插座相关命令,对处理器命令应答处理器为了向客户机返回指令的执行结果,服务器将应答处理器连接到客户机套接字相关指令应答处理器的networking.c中的acceptTcpHandler函数是Redis的连接应答处理器

该处理器用于对接收连接到(动词)服务器)的套接字的客户端进行应答,具体实现为sys/socket.h/accept函数的包装

初始化Redis服务器后,程序将响应处理器和服务器接收套接字AE_R的连接

EADABLE事件关联起来
当有客户端用sys/socket.h/connect函数 连接(动词) 服务器(的)监听套接字的时候, 套接字就会产生AE_READABLE 事件, 引发连接应答处理器执行, 并执行相应的套接字应答操作

命令请求处理器

networking.c中readQueryFromClient函数 是 Redis的命令请求处理器
这个处理器 负责 从套接字中 读入 客户端 发送的命令请求内容, 具体实现为unistd.h/read函数的包装

当一个客户端通过 连接应答处理器 成功连接到 服务器之后,
服务器 会 将客户端套接字的AE_READABLE事件 和 命令请求处理器关联起来
当客户端向服务器发送命令请求的时候,套接字 就会产生 AE_READABLE事件,引发命令请求处理器执行,并执行相应的套接字读入操作
在客户端连接服务器的整个过程中,服务器 都会 一直为 客户端套接字的AE_READABLE事件 关联 命令请求处理器

命令回复处理器

networking.c中sendReplyToClient函数 是 Redis的命令回复处理器
这个处理器 负责 将服务器执行命令后得到的命令回复 通过 套接字 返回 给客户端,具体实现为unistd.h/write函数的包装

当服务器有命令回复 需要传送给 客户端的时候,服务器 会将 客户端套接字的AE_WRITABLE事件 和 命令回复处理器 关联起来
当客户端 准备好 接收服务器传回的命令回复时,就会产生AE_WRITABLE事件,引发命令回复处理器执行,并执行相应的套接字写入操作
当命令回复发送完毕之后, 服务器就会 解除 命令回复处理器 与 客户端套接字的 AE_WRITABLE 事件之间的关联

为什么Redis是单线程的 不需要各种锁的性能消耗
Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除
一个对象
这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加
在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗单线程多进程集群方案
单线程的威力实际上非常强大,每核心效率也非常高,多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的
所以单线程、多进程的集群不失为一个时髦的解决方案CPU消耗
采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU

但是如果CPU成为Redis瓶颈,或者不想让服务器其他CUP核闲置,可以怎么做?
可以考虑多起几个Redis进程,Redis是key-value数据库,不是关系数据库,数据之间没有约束
只要客户端分清哪些key放在哪个Redis进程上就可以了

Redis为什么快? Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以 读取 速度快Redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度Redis采用自己实现的事件分离器,效率比较高,内部 采用 非阻塞的执行方式,吞吐能力比较大

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。