`

[转]Redis 网络架构及单线程模型

    博客分类:
  • web
 
阅读更多

 

Redis 网络架构及单线程模型

http://blog.jobbole.com/100079/

最近略有闲暇时间,于是对Redis进行了一些学习,学习途径除了官方文档还有Redis源代码,我看的版本是2.8.13,Redis源码总行数不到5W行,不同组件拆分非常细致,阅读起来也很清晰。这篇博客主要介绍我对Redis网络层架构以及线程模型的一些了解,希望能对大家有所帮助。

Redis网络基础架构

网络编程离不开Socket,网络I/O模型最常用的无非是同步阻塞、同步非阻塞、异步阻塞、异步非阻塞,高性能网络服务器最常见的线程模型也就是基于EventLoop模式的单线程模型。我们看看Redis的网络架构是怎么样的:

Redis基础组建结构

这里解释下上图涉及的组件,Redis网络层基础组件主要包括四个部分:

  1. EventLoop事件轮训器,这部分实现在AE里面。
  2. 提供Socket句柄事件的多路复用器,这部分分别对于不同平台提供了不同的实现,比如epoll和select可以用于linux平台、kqueue可以用于苹果平台、evpoll可以用于Solaris平台,这里并没有看到iocp,也就是Redis对于Windows支持并不是很好。
  3. 包括网络事件处理器实现的networking,这部分主要包括两个重要的今天要讲的事件处理器:acceptTcpHandler和acceptCommonHandler。
  4. 处理网络比较底层的部分,比如网络句柄创建、网络的读写等。

Redis单线程模型

要理解Redis的单线程模型,我们先抛出一些问题,当我们有多个客户端同时去跟Redis Server建立连接,之后又同时对某个key进行操作,这个过程中发生了什么呢?会不会有并发问题?

网络初始化

好了,这些问题先丢在这了,我们看看Redis启动初始化的过程中会做什么事情,这里尽量省略了与本文无关的部分:

  1. 初始化Redis Server参数,这部分代码通过initServerConfig实现。
  2. 初始化Redis Server,这部分代码在initServer里面。
  3. 启动事件轮训器。

对,这里我们就把Redis的启动部分简化为三步,跟网络操作有关的主要在第二步和第三步里面,来看看initServer里面发生了什么:

initServer流程

initServer里面首先创建了一个EventLoop,然后监听Server的IP对应的端口号,假设我们监听的是127.0.0.1:3333这个IP:端口对,我们得到的一个Server Socket句柄,最后通过createFileEvent将我们得到的Server Socket句柄和我们关心的网络事件mask注册到EventLoop上面。EventLoop是什么呢,我们看看它的定义:

上面我们关注的主要是两个东西:events和fired。他们分别是两个数组,events用于存放被注册的事件以及相应的句柄,fired用于存放当EventLoop线程从多路复用器轮训到有事件的句柄的时候,EventLoop线程会把它放入fired数组里面,然后处理。

事件注册示意图

我用上面的示意图描述createFileEvent做的事情,就是将Server Socket句柄和关心的事件mask以及当事件产生的时候的事件处理器accptHandler生成一个aeFileEvent注册到EventLoop的events的数组里面,当然在这之前会首先将事件注册到多路复用器上,也就是epoll、kqueue等这些组件上。事件注册完之后需要对多路复用器进行轮训,来分离我们关心切发生的事件,那就是最后一步,启动事件轮询器。

接收网络连接

上面的步骤完成了服务端的网络初始化,而且事件轮询器已经开始工作了,事件轮询器做什么事情呢,就是不断轮训多路复用器,看看之前注册的事件有没有发生,如果有发生,则将会将事件分离出来,放入EventLoop的fired数组中,然后处理这些事件。

很显然,上面注册的事件是客户端建立连接这个事件,因此当有两个客户端同时连接Redis服务器的时候,事件轮询器会从多路复用器上面分离出这个事件,同时调用acceptHandler来处理。acceptHandler做的事情主要是accept客户端的连接,创建socket句柄,然后将socket句柄和读事件注册到EventLoop的events数组里面,不一样的是对于客户端的事件处理器是readQueryClient。

accept客户端连接以及注册客户端连接句柄示意图

上面示意图表示了acceptHandler处理客户端连接,得到句柄之后再将这个句柄注册到多路复用器以及EventLoop上的示意图。之后再同样再处理下一个客户端的连接,这些都是串行的。

事件轮训

上面接收客户端这部分其实都发生在事件轮训的主循环里面:

Redis会不断的轮训多路复用器,将网络事件分离出来,如果是accept事件,则新接收客户端连接并将其注册到多路复用器以及EventLoop中,如果是查询事件,则通过读取客户端的命令进行相应的处理,这一切都是单线程,顺序的执行的,因此不会发生并发问题。

应用分析

Redis官网对Redis的读写性能测试结果达到10左右,这是非常吸引人的。Redis的单线程的行为主要是对内存的读写,这些操作其实用不了多少时间,因此瓶颈在网络I/O上面,我们一般提供较好的网络环境就可以提升Redis的吞吐量,比如提高网络带宽,除此之外还可以通过合并命令提交批处理请求来代替单条命令一次次请求从而减少网络开销,提高吞吐量。

参考文献

《Redis源码》

分享到:
评论

相关推荐

    Redis经典面试题:redis是单线程架构还是多线程架构

    尽管Redis的单线程模型在大多数场景下表现出色,但在Redis 6.0版本中,引入了多线程的概念,主要是为了优化网络IO读写性能。这里的多线程仅用于数据的读写操作,命令执行仍保持单线程顺序执行,因此不会引发线程安全...

    Redis线程模型,分布式一致性1

    Redis的线程模型是基于Reactor模式的单线程模型。Reactor模式是指在服务器端使用单线程来处理所有的客户端请求,而不是使用一个线程来处理一个客户端请求。这种模型可以减少线程切换的开销,提高服务器的性能。 在...

    01 缓存通识与Redis架构原理.pdf

    Redis的优势在于其单线程模型,这在早期版本中保证了操作的原子性,避免了多线程下的竞态条件,从而简化了并发控制。然而,随着技术的发展,Redis在6.0版本引入了多线程机制,以应对更高的并发需求。这种改变主要是...

    redis单线程快的原因和原理

    Redis作为一个高性能的键值存储系统,其单线程模型是其设计的一大特色,也是它能够实现高速处理的关键因素。下面我们将详细探讨Redis单线程快速响应的原因和原理。 首先,Redis之所以快速,首要原因是它执行所有...

    Redis配置详解和企业级项目应用架构

    - **单进程模型**:Redis采用了单进程多线程模型,避免了多进程之间的数据同步问题,使得CPU不再是Redis的性能瓶颈。 - **持久化机制**:Redis提供了两种持久化方式:RDB(Snapshotting)和AOF(Append Only File)...

    01-VIP-Redis核心数据结构与核心原理1

    Redis的核心原理之一是单线程模型,这意味着所有客户端的请求都在一个线程中顺序执行。由于Redis主要操作内存,避免了多线程间的上下文切换,从而提高了性能。然而,单线程也意味着对于耗时的操作(如`keys`命令),...

    redis-win-2.8.9,redis-win-2.8.9

    此外,由于Redis是单线程模型,虽然在处理并发请求时效率稍逊于多线程数据库,但其简单的架构和高效的内存管理使其在许多应用场景下仍具有显著优势,如缓存、计数器、队列服务等。在Windows环境下,Redis提供了便捷...

    Redis实战中文高清有目录有源码,源码中文注释

    同时,通过分析源码,你可以发现Redis是如何利用单线程模型来提高效率的,以及它是如何通过 slab 分配器进行内存管理,避免内存碎片。此外,还可以深入了解Redis的事件驱动模型,即使用epoll或kqueue等I/O多路复用...

    Redis:高性能内存数据库的核心特性和应用解析

    ③ 理解Redis的架构设计,包括单线程模型和集群方案;④ 掌握Redis的持久化机制和性能优化方法。 阅读建议:本文内容全面且详细,适合逐步学习和实践。建议从Redis的核心特性开始,逐步深入到应用场景、架构设计、...

    redis面试题热门20道以及解析

    问题触及了Redis的性能优势、单线程模型、主从复制、集群架构、内存淘汰策略、分布式锁实现、发布/订阅模式等,旨在评估候选人对Redis实际应用和潜在问题的理解和解决能力。掌握这些知识点对于构建高效、可靠的数据...

    redis container 问题梳理

    4. **并发访问**:Redis默认单线程模型可能导致并发处理能力受限。可通过主从复制、Sentinel哨兵系统或Cluster集群来提高并发处理能力。 5. **数据结构选择**:正确选用合适的数据结构能大幅提升效率。例如,如果...

    JAVA架构面试_Redis高频面试题 - 2.pdf

    9. **Redis 单线程模型**:Redis 使用单线程处理所有客户端请求,避免了线程切换带来的开销,通过高效的操作系统I/O多路复用技术如epoll实现高性能。 10. **Redis 数据类型**:包括String、Hash、List、Set、Sorted...

    Redis Windows源码

    Redis基于单线程模型,通过事件驱动机制处理客户端请求。它使用I/O多路复用(例如epoll或kqueue)来高效地处理大量并发连接,确保系统性能不受连接数增加的影响。在Windows环境下,Redis使用WSAEventSelect进行I/O...

    redis学习笔记.pdf

    4. 简单稳定:Redis的简单主要表现在三个方面:源码很少、使用单线程模型、客户端开发变得简单。 Redis的应用场景包括: 1. 缓存:Redis提供了键值过期时间设置,并且也提供了灵活控制最大内存和内存溢出后的淘汰...

    redis介绍文档学习

    4. **单线程**:Redis采用单线程模型来处理客户端请求,这简化了其内部实现并保证了一致性。 5. **订阅/发布模型**:Redis支持消息队列模式,可以用于实现消息的发布和订阅。 #### 三、Redis的优势 1. **高性能**...

    Redis day01.pdf

    随着业务需求的增长和技术的演进,Redis在保证其基础设计原则——内存操作的高效性和单线程模型的简洁性的同时,不断地优化和改进,以适应更加复杂和多样的应用场景。这使得Redis在现代的互联网架构中成为不可或缺的...

    最新Redis面试题及答案.docx

    Redis 的单进程单线程模型确保了操作的原子性,但也限制了其并发处理能力。然而,通过主从复制和读写分离,Redis 实现了分布式架构,允许数据在多个实例间分散,提高了读取性能。主节点负责写操作,而从节点提供读...

    架构师系列书籍--Redis实战

    - Redis采用单线程模型,所有的命令都在同一线程中执行。 - 使用内存作为主要存储介质,因此拥有极高的读写速度。 ##### 1.3.5 提供API的语言 - Redis支持多种编程语言的客户端API,如Java、Python、PHP等。 - ...

    Redis设计与实战

    通过使用单线程模型,避免了线程切换带来的开销,实现了极高的吞吐量。此外,Redis还支持客户端缓存、命令阻塞策略以及Lua脚本等优化手段,进一步提升了性能。 实战部分,书中可能涵盖了如何在Web应用中使用Redis...

Global site tag (gtag.js) - Google Analytics