2023-05-30:Redis6.0为什么要引入多线程呢?

发布时间 2023-05-30 21:20:37作者: 福大大架构师每日一题

2023-05-30:Redis6.0为什么要引入多线程呢?

答案2023-05-30:

Redis多线程比单线程性能提升一倍:

Redis 6.0 引入多线程 IO 特性对性能提升至少是一倍以上。据 Redis 作者 antirez 在 RedisConf 2019 分享中介绍,多线程 IO 特性可以显著提高 Redis 的性能和吞吐量,实测 GET/SET 命令在 4 线程 IO 下的性能相比单线程几乎翻倍。国内也有一些大牛在阿里云 ESC 上测试了 unstable 版本的 Redis,结果也证实了多线程比单线程性能提升一倍左右的结论。

巨头公司的需求

Redis 将所有数据放在内存中,因此具有非常快的响应速度,大约只需要 100 纳秒左右。对于小数据包,Redis 服务器可以处理 80,000 到 100,000 QPS 左右,这已经是 Redis 处理极限了。虽然对于 80% 的公司来说,单线程的 Redis 已经足够使用,但一些高并发和复杂的业务场景需要更大的 QPS。

随着业务的不断发展,越来越多的公司面临着上亿的交易量,需要更高的性能和吞吐量。为了应对这些挑战,Redis 引入了多线程 IO 特性,在多核 CPU 和高并发情况下充分利用现代硬件资源,从而提高 Redis 的性能和吞吐量,满足更复杂和高并发的业务需求。

集群方案的问题

常见的解决方案是在分布式架构中对数据进行分区,并采用多个 Redis 服务器来存储数据。然而,这种方案也存在着一些问题。例如,需要管理的 Redis 服务器数量太多,维护代价很大;同时,数据分区也可能不够灵活,无法满足一些特定业务场景下的需求。

在采用数据分区的 Redis 集群中,某些适用于单个 Redis 服务器的命令可能不再适用。例如,一些针对特定键值对的命令如果跨越多个节点,就会出现互相干扰和不一致的情况。

尽管 Redis 的数据分区方案可以提高性能和扩展性,但也存在一些问题。例如,数据分区无法解决热点读/写问题,这可能会导致某些节点的负载过高,而其他节点则处于闲置状态。此外,数据分区可能会导致数据偏斜和重新分配变得更加复杂,特别是在进行节点的放大/缩小时。

1.纯内存KV操作

Redis 是一款基于内存的数据存储系统,因此其操作都非常快速。相比于 CPU,Redis 的性能瓶颈更多来自于两个方面:机器内存和网络带宽。

在计算机的世界中,CPU的速度是远大于内存的速度的,同时内存的速度也是远大于硬盘的速度。redis的操作都是基于内存的,绝大部分请求是纯粹的内存操作,非常迅速。

在计算机的世界中,CPU 的速度是远大于内存和硬盘的速度的。然而,由于内存的速度比硬盘快得多,因此 Redis 将其所有数据存储在内存中,以获得更高的读写性能。

Redis 的操作都是基于内存的,因此绝大部分请求都是纯粹的内存操作,非常迅速。Redis 集群可以支持每秒数百万次的读取和写入操作,响应时间通常在微秒或毫秒级别。这种高速读写操作对于处理高并发、实时数据的场景非常有用。

2.单线程操作

使用单线程可以省去多线程时CPU上下文会切换的时间,也不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。对于内存系统来说,多次读写都是在一个CPU上,没有上下文切换效率就是最高的!既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章的采用单线程的方案了。

Redis 的单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求。而对于其他模块,Redis 仍然可以使用多线程来提高性能。

具体来说,在 Redis 中,网络请求模块和数据存储模块是两个独立的模块。网络请求模块负责接收和处理客户端请求,而数据存储模块则负责读取和写入数据。在 Redis 的单线程模型中,网络请求模块使用一个线程处理所有客户端请求,而数据存储模块仍然可以使用多线程来提高性能。

例如,在 Redis 中,主从复制和持久化等操作都会使用多线程来加速处理。此外,Redis 还引入了多线程 IO 特性,以充分利用现代硬件资源提高性能和吞吐量。

总之,Redis 的单线程模型指的是网络请求模块只使用一个线程处理所有客户端请求,这种模型可以最大化 Redis 的效率和简化代码实现。但是,其他模块仍然可以使用多线程来提高性能和并发处理能力。同时,Redis 的多线程 IO 特性也可以增强数据库的性能和扩展性。

3.I/O 多路复用

为什么 Redis 中要使用 I/O 多路复用这种技术呢?

Redis 是一款跑在单线程中的高性能 NoSQL 数据库,所有的操作都是按照顺序线性执行的。由于 Redis 的读写操作等待用户输入或输出都是阻塞的,因此 I/O 操作如果不能直接返回,会导致某一文件的 I/O 阻塞,从而整个进程无法对其他客户提供服务。

为了解决这个问题,出现了 I/O 多路复用技术。I/O 多路复用技术可以同时监视多个文件描述符,当某个文件描述符就绪时,通知程序进行相应的 I/O 操作,从而避免了阻塞等待带来的性能瓶颈。

4.Reactor 设计模式

Redis 基于 Reactor 模式开发了自己的网络事件处理器,称之为文件事件处理器(File Event Handler)。

文件事件处理器是 Redis 中网络事件的核心实现。它通过 select、poll 或 epoll 等系统级别的多路复用机制,对多个文件描述符进行轮询,当某个文件描述符就绪时,Redis 可以立即对其进行读取或写入操作,从而实现高效的异步非阻塞 I/O 操作。