单线程和多线程连接mysql_面试系列 redis为什么快&单线程&多线程

Redis是一款高性能的内存数据库,以其快速响应和丰富的数据结构而著名。其单线程模型确保了无上下文切换的高效执行,但随着网络IO成为瓶颈,Redis6.0引入了多线程来优化读写操作。多线程模型中,主线程负责连接管理和命令执行,而IO线程负责数据读写,实现了部分并行处理,提升了系统性能。
摘要由CSDN通过智能技术生成

说说redis和mysql区别类型:MySQL是关系型数据库,Redis是缓存数据库.

作用:MySQL用于持久化的存储数据到硬盘,功能强大,但是速度较慢;Redis用于存储使用较为频繁的数据到缓存中,读取速度快.

存放位置:MySQL数据放在磁盘,Redis数据放在内存

应用场景:Redis适合放一些频繁使用,比较热的数据,因为是放在内存中,读写速度都非常快:适合排行榜、计数器、消息队列推送、好友关注、粉丝。MySQL适合持久化存储,对数据存储的安全性有保证,而且MySQL支持sql查询,可以实现一些关联的查询以及统计.

redis为什么这么快/Redis原理C语言实现,执行速度快

纯内存操作,数据读写在内存中,异步持久化到磁盘

丰富和高效的数据结构

基于非阻塞的I/O多路复用机制

单线程避免了上下文切换

Redis单线程

redis单线程的核心就是它基于一个假设:它在内存中执行的操作耗时很快,以至于多线程带来的收益小于其上下文切换和锁管理的消耗。redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 就是效率最高的,为什么呢,因为多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的系统来说,它没有上下文的切换就是效率最高的。redis 用 单个CPU 绑定一块内存的数据,然后针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成的,所以它是单线程处理这个事。在内存的情况下,这个方案就是最佳方案 —— 阿里 沈询redis 用 单个CPU 绑定一块内存的数据,针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成。对于多个CPU的机器可以使用多个redis实例绑定不同的CPU

redis的单线程模型指的是文件事件处理器单线程,即单线程的处理请求。但是它也有自己的一些后台线程,比如说删除大key并行是为了快,多台处理器上同时处理多个任务

并发是为了能够同一时间间隔做多个事情,一台处理器上“同时”处理多个任务,它一定是慢过串行

redis的单线程模型/通信流程

核心就两大块,IO多路复用模块支撑高并发请求,文件事件处理器单线程从队列中获取socket并调用相应的请求处理器

1、首先在redis启动初始化的时候,redis会先将事件处理器中的连接应答处理器和AE_READABLE事件关联起来;

2、如果客户端向redis发起连接,会产生AE_READABLE事,产生该事件后会被IO多路复用程序监听到(步骤B),然后IO多路复用程序会把监听到的socket信息放入到队列中(步骤C),事件分配器每次从队列中取出一个socket(步骤D),然后事件分派器把socket给对应的事件处理器(步骤E)。

3、当客户端向redis发生写请求时,首先就会在对应的socket如socket01上会产生AE_READABLE事件,产生该事件后会被IO多路复用程序监听到(步骤B),然后IO多路复用程序会把监听到的socket信息放入到队列中,事件分配器每次从队列中取出一个socket(步骤D),然后事件分派器把socket给对应的事件处理器(步骤E)。

5、当客户端会查询redis是否完成相应的操作,就会在socket01上产生一个AE_WRITABLE事件,会由对应的命令回复处理器来处理,就是将准备好的相应数据写入socket01(由于socket连接是双向的),返回给客户端,如读操作,客户端会显示ok。

6、如果命令回复处理器执行完成后,就会删除这个socket01的AE_WRITABLE事件和命令回复处理器的关联。

7、这样客户端就和redis进行了一次通信。由于连接应答处理器执行一次就够了,如果客户端再次进行操作就会由命令请求处理器来处理,反复执行。

Redis底层IO模型代码封装

我感觉不会问,但是阿里面经有,先放着先。

Redis6.0多线程

redis单线程的核心就是它基于一个假设:它在内存中执行的操作耗时很快,以至于多线程带来的收益小于其上下文切换和锁管理的消耗。

而现在这个假设在真实场景下发生了瓶颈:网络IO消耗,当value比较大时:从socket中读取请求数据,会从内核态将数据拷贝到用户态 (read调用)

将数据回写到socket,会将数据从用户态拷贝到内核态 (write调用)

解决方案:主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列

主线程接收完所有读事件之后,通过 RR(Round Robin) 将这些连接分配给 IO 线程组

主线程阻塞等待 IO 线程组读取 socket 完毕

主线程通过单线程的方式执行请求命令(指客户端发送的命令),请求数据读取并解析完成

主线程阻塞等待 IO 线程组将数据回写 socket 完毕

解除绑定,清空等待队列命令的执行依然由主线程单线程串行顺序执行(保持单线程)

I/O线程要么同时读,要么同时写,不会同时读或写

IO 线程只负责读写 socket 解析命令,不负责命令处理

整个过程无锁参与

多线程肯定要低于机器CPU核数,并行才能提高性能,并发只会浪费

为什么之前不使用多线程?

官方曾经回应:使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于内存和网络。引入多线程,引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。

那为什么现在又要用多线程了呢?

因为现在业务场景越来越复杂,对性能要求越来越高,所以对redis做出了提高性能的要求

整理来源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值