码迷,mamicode.com
首页 > 编程语言 > 详细

为什么单线程Redis能那么快?

时间:2021-06-07 20:43:17      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:维护   get   模式   存储   info   使用   内核   调用   控制   

1.Redis 真的只有单线程吗?

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

2.Redis 为什么用单线程?

多线程的模式对共享资源的并发控制问题:1,若没有额外机制保证情况下,不能保证共享资源的准确性;2,添加额外机制可能带来额外的开销

采用多线程开发一般会引入同步原语来保护共享资源的并发访问,这也会降低系统代码的易调试性和可维护性。为了避免这些问题,Redis 直接采用了单线程模式。 

3. 单线程 Redis 为什么那么快?

一方面,Redis 的大部分操作在内存上完成,再加上它采用了高效的数据结构,例如哈希表和跳表,这是它实现高性能的一个重要原因。

另一方面,就是 Redis 采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率。

比如为了处理一个 Get 请求,需要监听客户端请求(bind/listen),和客户端建立连接(accept),从 socket 中读取请求(recv),解析客户端发送请求(parse),根据请求类型读取键值数据(get),最后给客户端返回结果,即向 socket 中写回数据(send)。

在这里的网络 IO 操作中,有潜在的阻塞点,分别是 accept() 和 recv()。当 Redis 监听到一个客户端有连接请求,但一直未能成功建立起连接时,会阻塞在 accept() 函数这里,导致其他客户端无法和 Redis 建立连接。类似的,当 Redis 通过 recv() 从一个客户端读取数据时,如果数据一直没有到达,Redis 也会一直阻塞在 recv()。

基于多路复用的高性能 I/O 模型

Linux 中的 IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。

基于多路复用的 Redis IO 模型如下图所示

技术图片

 

 为了在请求到达时能通知到 Redis 线程,select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数。

(关键点在于accpet和recv时可能会阻塞线程,使用IO多路复用技术可以让线程先处理其他事情,等需要的资源到位后epoll会调用回调函数通知线程,然后线程再去处理存/取数据;这样一个redis服务端线程就可以同时处理多个客户端请求了。
redis之所以适合用多路复用技术有一个很重要的原因时它是在内存中处理数据速度极快,这时io成了瓶颈。为什么Mysql不用多路复用技术呢?因为Mysql的主要性能瓶颈在于数据的存/取,优化方向不一样。)

为什么单线程Redis能那么快?

标签:维护   get   模式   存储   info   使用   内核   调用   控制   

原文地址:https://www.cnblogs.com/zzq919/p/14858520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!