【易客吧】_全网激活码总代_激活码商城

您现在的位置是:首页 > 热门资讯 > 正文

热门资讯

Redis 单线程的演进:探索其不断提升的性能 (redis单机qps上限)

用户投稿2024-04-19热门资讯14
Redis 是一个高性能的内存数据库,以其极高的吞吐量和低延迟而闻名。Redis 是一个单线程模型的数据库,这意味着它只能同时处理一个请求。这可能会成为一个瓶颈,特别是对于处理大量并发请求的高负载应用程序。但尽管是单线程模型,Redis 却能提供卓越的性能。这归功于其经过精心设计的架构和不断优化的算法。本文将深入探讨 Redis 单线程架构背后的演变,并分析其如何不断提升其性能。

Redis 的单线程架构

Redis 的核心是一个称为 I/O 多路复用器的单事件循环。这个事件循环负责监听所有连接到 Redis 实例的客户端,并处理来自这些客户端的请求。当一个请求被接收到时,它会被放入一个队列中,然后由事件循环依次处理。单线程架构的好处在于它简单且高效。它不需要复杂的同步机制,并且可以避免线程切换的开销。这使得 Redis 能够以极低的延迟处理请求。

性能优化的演进

虽然 Redis 的单线程架构提供了高性能的基础,但其开发者并没有止步于此。多年来,他们不断优化 Redis 的算法和数据结构,以进一步提升其吞吐量和延迟。

优化 I/O 操作

I/O 操作是 Redis 性能的关键因素之一。为了优化 I/O,Redis 采用了多种技术,包括:零拷贝:Redis 使用零拷贝技术来减少在客户端和服务器之间复制数据时所需的 I/O 操作。这显著提高了 Redis 的吞吐量。多路复用:如前所述,Redis 使用 I/O 多路复用器来监听多个客户端。这使得 Redis 能够在不阻塞的情况下同时处理多个请求。

优化数据结构

Redis 存储数据的方式也会影响其性能。为了优化其数据结构,Redis 使用了以下技术:跳表:Redis 使用跳表作为其底

Redis 6.0多线程介绍

Redis作为一个基于内存的缓存系统,一直以高性能著称, 在单线程处理情况下,读速度可达到11万次/s,写速度达到8.1万次/s。

官方曾做过类似问题的回复:使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于内存和网络。

但是,单线程的设计也给Redis带来一些问题:

针对上面问题,Redis在4.0版本以及6.0版本分别引入了Lazy Free以及多线程IO,逐步向多线程过渡。

Redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:

Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接。 文件事件就是服务器对套接字操作的抽象 。

服务器与客户端的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。 (eg: 连接accept,read,write,close等)

Redis服务器中的一些操作(eg: serverCron函数)需要在给定的时间点执行。 时间事件就是服务器对这类定时操作的抽象 (eg: 过期键清理,服务状态统计等)

Redis将文件事件和时间事件进行抽象,时间轮询器会监听I/O事件表: 一旦有文件事件就绪,Redis就会优先处理文件事件, 接着处理时间事件。 在上述所有事件处理上,Redis都是以单线程形式处理,所以说Redis是单线程的。 处理过程见下图

Redis基于Reactor模式开发了自己的I/O事件处理器,也就是文件事件处理器。 Redis在I/O事件处理上,采用了I/O多路复用技术,同时监听多个套接字, 并为套接字关联不同的事件处理函数,通过一个线程实现了多客户端并发处理。 处理过程见下图

Redis 单线程的演进:探索其不断提升的性能 (redis单机qps上限) 第1张

上述的设计,在数据处理上避免了加锁操作,既使得实现上足够简洁,也保证了其高性能。 当然, Redis单线程只是指其在事件处理上 ,实际上,Redis也并不是单线程的,比如生成RDB文件,就会fork一个子进程来实现。

背景: 客户端向Redis发送一条耗时较长的命令,比如删除一个含有上百万对象的Set键,或者执行flushdb,flushall操作, Redis服务器需要回收大量的内存空间,导致服务器卡住好几秒,对负载较高的缓存系统而言将会是个灾难。

为了解决这个问题,在Redis 4.0版本引入了Lazy Free, 将慢操作异步化 ,这也是在事件处理上向多线程迈进了一步。

将大键的删除操作异步化,采用非阻塞删除(对应命令UNLINK)。 大键的空间回收交由单独线程实现,主线程只做关系解除,可以快速返回,继续处理其他事件,避免服务器长时间阻塞。

意义: Redis在4.0版本引入了Lazy Free,自此Redis有了一个 Lazy Free线程专门用于大键的回收 。 同时,也去掉了聚合类型的共享对象,这为多线程带来可能。 这为Redis在6.0版本实现了多线程I/O打下了基础。

Redis 6.0的多线程并未将事件处理改成多线程,而是在I/O上。 因为,如果把事件处理改成多线程,不但会导致锁竞争,而且会有频繁的上下文切换, 即使用分段锁来减少竞争,对Redis内核也会有较大改动,性能也不一定有明显提升。

流程简述如下:

见下图

Redis6.0的多线程默认是禁用的,只使用主线程。 如需开启需要修改配置文件:

开启多线程后,还需要设置线程数,否则是不生效的。 同样修改配置文件:

redis是单线程还是多线程

Redis采用的是单进程单线程模型的KV数据库,由C语言编写。

官方提供的数据是可以达到+的qps。这个数据不比采用单进程多线程的同样基于内存的KV数据库Memcached差。Redis并没有直接使用Libevent,而是自己完成了一个非常轻量级的对select、epoll、evport、kqueue这些通用的接口的实现。在不同的系统调用选用适合的接口,linux下默认是epoll。

因为Libevent比较重更通用代码量也就很庞大,拥有很多Redis用不上的功能,Redis为了追求“轻巧”并且去除依赖,就选择自己去封装了一套。

Redis单线程的优点

1、高效执行:Redis的单线程模型意味着所有的操作都在同一个线程中执行,这使得操作指令的执行速度非常快。因为线程切换和调度等开销在单线程中不存在,所以Redis在处理大量请求时,能够保持高效的执行速度。

2、简化编程模型:对于开发者来说,单线程模型使得编程和调试更为简单。由于只有一个主线程,不存在线程同步和数据一致性问题,这让开发者无需花费太多精力去处理并发问题,而可以专注于业务逻辑的实现。

3、高吞吐量:由于Redis的单线程设计,它能够高效地处理大量的请求。在处理大量读/写操作时,Redis的性能非常出色。特别是在高并发场景下,Redis可以有效地保证操作的实时性。

redis源码解读:单线程的redis是如何实现高速缓存的?

redis可能是最近几年最火的缓存数据库方案了,在各个高并发领域都有应用。 这篇文章,我们将从源代码的角度来分析一下,为何如此一个高性能,高应用的缓存,会是单线程的方案,当然一个方案的高性能,高并发是多方面的综合因素,其它的因素我们将在后续解读。 后续分析主要以LINUX操作系统为基础,这也是redis应用最广的平台。 单线程最大的受限是什么?就是CPU,现在服务器一般已经是多CPU,而单线程只能使用到其中的一个核。 redis作为一个网络内存缓存数据库,在实现高性能时,主要有4个点。 1.网络高并发,高流量的数据处理。 一个异步,高效,且对CPU要求不高的网络模型,这个模型主要是由OS来提供的,目前在LINUX最主流使用的是EPOLL,这个网上介绍很多,主要是基于事件驱动的一个异步模型。 2.程序内部的合理构架,调用逻辑,内存管理。 redis在采用纯C实现时,整体调用逻辑很短,但在内存方面,适当的合并了一些对象和对齐,比如sds等,在底层使用了内存池,在不同情况下使用的不太一样。 但整体处理上没有NGINX的内池设计巧妙,当然二者不太一样,NGINX是基于请求释放的逻辑来设计的,因此针对请求,可以一次申请大块,分量使用,再最后统一释放。 3.数据复制的代价,不管是读取数据或是写入数据,一般都是需要有数据复制的过程。 数据复制其实就是一次内存copy,真正的代价是在于存在大VALUE,当value值长度超过16KB时,性能会开始下降。 因为单线程的原因,如果存在一个超大VALUE,比如20MB,则会因为这个请求卡住整个线程,导致后续的请求进不来,虽然后面的请求是能快速处理的小请求。 中数据结构中算法的代价,有些结构在大数据量时,代价是很高的。 很多时间,大家忽略了算法的运算代码,因为像memcached等这类是完全的KV缓存,不存在什么算法,除了一个KEY的查找定位HASH算法。 而redis不一样,提供了不少高阶的数据对象,这些对象具有上层的一些算法能力,而这些能力是需要比如GEO模块。

若对本页面资源感兴趣,请点击下方或右方图片,注册登录后

搜索本页相关的【资源名】【软件名】【功能词】或有关的关键词,即可找到您想要的资源

如有其他疑问,请咨询右下角【在线客服】,谢谢支持!

Redis 单线程的演进:探索其不断提升的性能 (redis单机qps上限) 第2张

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~
欢迎你第一次访问网站!