【JavaP6大纲】Redis篇:redis单线程模型

Redis采用单线程模型处理网络IO和键值对读写,但其持久化、集群同步等任务由额外线程执行。利用IO多路复用(如epoll)实现高效并发处理,结合内存操作的高速特性,避免了线程切换的开销,确保了高性能。同时,Redis通过指令队列和响应队列有序处理客户端请求。阻塞IO在等待数据时会暂停,而非阻塞IO则允许读写操作尽可能进行。

你是如何理解redis单线程模型的?

Redis 里面的单线程主要是 Redis 的网络 IO 和键值对读写,它是由一个线程来完成的,但是 Redis 的其他功能,比如说持久化、异步删除、集群数据同步等等,这些其实是由额外的线程执行的,这里的单线程主要是Redis 对外提供键值存储服务来说的。

主要流程是这样的:

  1. redis 会将每个客户端都关联一个指令队列,客户端的指令通过队列来按顺序处理,先到先处理,一个客户端指令队列中的指令是按顺序执行的。
  2. redis 的每个客户端都关联一个响应队列,通过响应队列有顺序地将指令的返回结果返回给客户端。
  3. redis同一时间每次都只能处理一个客户端队列中的指令或者响应。

Redis 如何处理高并发客户端连接?

redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。

为什么redis使用单线程模型还能保证高性能?

  1. 第一个是因为redis 是纯内存操作,内存的响应时长是 100 纳秒左右,这是 redis 的 QPS 过万的重要基础。
  2. 第二个是因为redis 的核心是基于非阻塞的IO多路复用机制,单线程模型避免了线程切换和竞态产生的消耗,解决了多线程的切换性能损耗问题。
  3. 第三个是因为redis 底层使用C语言实现,一般来说,C 语言实现的程序"距离"操作系统更近,执行速度相对会更快。

什么是阻塞IO?

当我们调用 Scoket 的读写方法,默认它们是阻塞的。

  • 读方法读取多个字节完成后再返回,如果没有读够足够的字节线程就会阻塞,直到新的数据到来或者连接关闭了,读方法才可以返回,线程才能继续处理。
  • 写方法会把数据写到缓冲区中,如果缓存区中的数据还没有写入到磁盘,就有新的数据要写到缓存区时,写方法就会阻塞,直到写缓存区中有空闲空间。

什么是非阻塞IO?

读写方法不会阻塞,能读多少读多少,能写多少写多少。能读多少取决于内核为 Scoket 分配的读缓冲区的大小,能写多少取决于内核为 Scoket 分配的写缓冲区的剩余空间大小。读方法和写方法都会通过返回值来告知程序实际读写了多少字节数据。

IO多路复用机制?

假设redis 需要处理 3 个 IO 请求,同时把 3 个请求的结果返回给客户端,所以总共需要处理 6 个 IO 事件,由于 redis 是单线程模型,同一时间只能处理一个 IO 事件,于是 redis 需要在合适的时间暂停对某个 IO 事件的处理,转而去处理另一个 IO 事件,这样 redis 就好比一个开关,当开关拨到哪个 IO 事件这个电路上,就处理哪个 IO 事件,其他 IO 事件就暂停处理了。这就是IO多路复用技术。

评论 56
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员廖志伟

赏我包辣条呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值