Redis线程模型详解

目录

前言

问题分析

详解

 redis和memcached的区别

 Redis支持服务器端的数据操作

 内存使用效率对比

 性能对比

 集群模式

redis的单线程模型为何效率高

redis 单线程模型

 文件事件处理器

文件事件


前言

redis应用越来越广泛,为单线程模型,面试中也常常会被问到,但您知道他的深层次原理吗?这几个问题您知道多少?

redis和memcached有什么区别?redis的线程模型是什么?为什么单线程的redis比多线程的memcached效率要高得多(为什么redis是单线程的但是还可以支撑高并发)?

问题分析

详解

 redis和memcached的区别

这个事儿吧,你可以比较出N多个区别来,但是我还是采取redis作者给出的几个比较吧

 Redis支持服务器端的数据操作

Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作

  • 通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去,这大大增加了网络IO的次数和数据体积
  • 在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

 内存使用效率对比

使用简单的KV存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。

 性能对比

  • Redis只使用单核
  • Memcached可以使用多核

所以平均每一个核上Redis在存储小数据时比Memcached性能更高
而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,稍有逊色。

 集群模式

  • memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据
  • 但是redis目前是原生支持cluster模式的,redis官方就是支持redis cluster集群模式的,比memcached来说要更好

redis的单线程模型为何效率高

  • 纯内存操作
  • 核心是基于非阻塞的IO多路复用机制
  • 单线程反而避免了多线程的频繁上下文切换问题

redis 单线程模型

Redis 在单线程下还可以支持高并发的一个重要原因就是 Redis 的线程模型:基于非阻塞的IO多路复用机制。这篇文章就 Redis 的线程模型做详细说明。

Redis 是基于 reactor 模式开发了网络事件处理器,这个处理器叫做文件事件处理器(file event handler)。由于这个文件事件处理器是单线程的,所以 Redis 才叫做单线程的模型。采用 IO 多路复用机制同时监听多个 Socket,根据 socket 上的事件来选择对应的事件处理器来处理这个事件。模型如下图:

 文件事件处理器

redis基于reactor模式开发了网络事件处理器,这个处理器叫做文件事件处理器,file event handler

这个文件事件处理器,是单线程的,redis才叫做单线程的模型,采用IO多路复用机制同时监听多个socket,根据socket上的事件来选择对应的事件处理器来处理这个事件。

如果被监听的socket准备好执行acceptreadwriteclose等操作时,跟操作对应的文件事件就会产生,这个时候文件事件处理器就会调用之前关联好的事件处理器来处理对应事件。

文件事件处理器是单线程模式运行的,但是通过IO多路复用机制监听多个socket,实现高性能的网络通信模型,又可以跟内部其他单线程的模块进行对接,保证了redis内部的线程模型的简单性。

文件事件处理器的结构包含了四个部分:

  • 多个 Socket
  • IO 多路复用程序
  • 文件事件分派器
  • 事件处理器

多个 socket 会产生不同的事件,不同的事件对应着不同的操作,IO 多路复用程序监听着这些 Socket,当这些 Socket 产生了事件,IO 多路复用程序会将这些事件放到一个队列中,通过这个队列,以有序、同步、每次一个事件的方式向文件时间分派器中传送。当事件处理器处理完一个事件后,IO 多路复用程序才会继续向文件分派器传送下一个事件。

在 Redis 中,Socket 会产生 AE_READABLE 和 AE_WRITABLE 事件:

  • 当 socket 变得可读时或者有新的可以应答的 socket 出现时,socket 就会产生一个 AE_READABLE 事件
  • 当 socket 变得可写时,socket 就会产生一个 AE_WRITABLE 事件。

文件事件

当socket变得可读时(比如客户端对redis执行write/close操作),或者有新的可以应答的sccket出现时(客户端对redis执行connect操作),socket就会产生一个AE_READABLE事件

当socket变得可写的时候(客户端对redis执行read操作),socket会产生一个AE_WRITABLE事件。

IO多路复用程序可以同时监听AE_REABLE和AE_WRITABLE两种事件,要是一个socket同时产生了AE_READABLE和AE_WRITABLE两种事件,那么文件事件分派器优先处理AE_REABLE事件,然后才是AE_WRITABLE事件。

文件事件派发器将事件交给事件处理器,事件处理器包括:连接应答处理器、命令请求处理器、命令回复处理器,每个处理器对应不同的 socket 事件:

  • 如果是客户端要连接 Redis,那么会为 socket 关联连接应答处理器
  • 如果是客户端要写数据到 Redis(读、写请求命令),那么会为 socket 关联命令请求处理器
  • 如果是客户端要从 Redis 读数据,那么会为 socket 关联命令回复处理器

下图是客户端与 Redis 通信的一次完整的流程:

 

  1. Redis 启动初始化的时候,Redis 会将连接应答处理器与 AE_READABLE 事件关联起来。
  2. 如果一个客户端跟 Redis 发起连接,此时 Redis 会产生一个 AE_READABLE 事件,由于开始之初 AE_READABLE 是与连接应答处理器关联,所以由连接应答处理器来处理该事件,这时连接应答处理器会与客户端建立连接,创建客户端响应的 socket,同时将这个 socket 的 AE_READABLE 事件与命令请求处理器关联起来。
  3. 如果这个时间客户端向 Redis 发送一个命令(set k1 v1),这时 socket 会产生一个 AE_READABLE 事件,IO 多路复用程序会将该事件压入队列中,此时事件分派器从队列中取得该事件,由于该 socket 的 AE_READABLE 事件已经和命令请求处理器关联了,因此事件分派器会将该事件交给命令请求处理器处理,命令请求处理器读取事件中的命令并完成。操作完成后,Redis 会将该 socket 的 AE_WRITABLE 事件与命令回复处理器关联。
  4. 如果客户端已经准备好接受数据后,Redis 中的该 socket 会产生一个 AE_WRITABLE 事件,同样会压入队列然后被事件派发器取出交给相对应的命令回复处理器,由该命令回复处理器将准备好的响应数据写入 socket 中,供客户端读取。
  5. 命令回复处理器写完后,就会删除该 socket 的 AE_WRITABLE 事件与命令回复处理器的关联关系。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值