为什么单线程的Redis能够达到百万级的QPS?
作者:在江湖中coding
juejin.im/post/5e6097846fb9a07c9f3fe744
性能测试报告
查看了下阿里云 Redis 的性能测试报告如下,能够达到数十万、百万级别的 QPS(暂时忽略阿里对 Redis 所做的优化),我们从 Redis 的设计和实现来分析一下 Redis 是怎么做的。
Redis 的设计与实现
其实 Redis 主要是通过三个方面来满足这样高效吞吐量的性能需求
高效的数据结构
多路复用 IO 模型
事件机制
高效的数据结构
Redis 支持的几种高效的数据结构 string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集 合)
以上几种对外暴露的数据结构它们的底层编码方式都是做了不同的优化的,不细说了,不是本文重点
多路复用 IO 模型
假设某一时刻与 Redis 服务器建立了 1 万个长连接,对于阻塞式 IO 的做法就是,对每一条连接都建立一个线程来处理,那么就需要 1万个线程,同时根据我们的经验对于 IO 密集型的操作我们一般设置,线程数 = 2 * CPU 数量 + 1,对于 CPU 密集型的操作一般设置线程 = CPU 数量 + 1,当然各种书籍或者网上也有一个详细的计算公式可以算出更加合适准确的线程数量,但是得到的结果往往是一个比较小的值,像阻塞式 IO 这也动则创建成千上万的线程,系统是无法承载这样的负荷的更加弹不上高效的吞吐量和服务了。
而多路复用 IO 模型的做法是,用一个线程将这一万个建立成功的链接陆续的放入 event_poll,event_poll 会为这一万个长连接注册回调函数,当某一个长连接准备就绪后(建立建立成功、数据读取完成等),就会通过回调函数写入到 event_poll 的就绪队列 rdlist 中,这样这个单线程就可以通过读取 rdlist 获取到需要的数据
需要注意的是,除了异步 IO 外,其它的 I/O 模型其实都可以归类为阻塞式 I/O 模型,不同的是像阻塞式 I/O 模型在第一阶段读取数据的时候,如果此时数据未准备就绪需要阻塞,在第二阶段数据准备就绪后需要将数据从内核态复制到用户态这一步也是阻塞的。而多路复用 IO 模型在第一阶段是不阻塞的,只会在第二阶段阻塞
通过这种方式,就可以用 1 个或者几个线程来处理大量的连接了,极大的提升了吐吞量
事件机制
redis 客户端与 redis 服务端建立连接,发送命令,redis 服务器响应命令都是需要通过事件机制来做的,如下图(来自互联网的某处...)
首先 redis 服务器运行,监听套接字的 AE_READABLE 事件处于监听的状态下,此时连接应答处理器工作,
客户端与 redis 服务器发起建立连接,监听套接字产生 AE_READABLE 事件,当 IO 多路复用程序监听到其准备就绪后,将该事件压入队列中,由文件事件分派器获取队列中的事件交于连接应答处理器工作处理,应答客户端建立连接成功,同时将客户端 socket 的 AE_READABLE 事件压入队列由文件事件分派器获取队列中的事件交命令请求处理器关联
客户端发送 set key value 请求,客户端 socket 的 AE_READABLE 事件,当 IO 多路复用程序监听到其准备就绪后,将该事件压入队列中,由文件事件分派器获取队列中的事件交于命令请求处理器关联处理
命令请求处理器关联处理完成后,需要响应客户端操作完成,此时将产生 socket 的 AE_WRITEABLE 事件压入队列,由文件事件分派器获取队列中的事件交于命令恢复处理器处理,返回操作结果,完成后将解除 AE_WRITEABLE 事件与命令恢复处理器的关联
reactor模式
大体上可以说 Redis 的工作模式是,reactor 模式配合一个队列,用一个 serverAccept 线程来处理建立请求的链接,并且通过 IO 多路复用模型,让内核来监听这些 socket,一旦某些 socket 的读写事件准备就绪后就对应的事件压入队列中,然后 worker 工作,由文件事件分派器从中获取事件交于对应的处理器去执行,当某个事件执行完成后文件事件分派器才会从队列中获取下一个事件进行处理
可以类比在 netty 中,我们一般会设置 bossGroup 和 workerGroup 默认情况下 bossGroup 为 1,workerGroup = 2 * cpu 数量,这样可以由多个线程来处理读写就绪的事件,但是其中不能有比较耗时的操作如果有的话需要将其放入线程池中,不然会降低其吐吞量。在 redis 中我们可以看做这二者的值都是 1
为什么说存储的值不宜过大
比如一个 string key = a,存储了 500MB,首先读取事件压入队列中,文件事件分派器从中获取到后,交于命令请求处理器处理,此处就涉及到从磁盘中加载 500MB,比如是普通的 SSD 硬盘,读取速度 200MB/S,那么需要 2.5S 的读取时间,此时其它 socket 所有的请求都将处于等待过程中,就会导致阻塞了 2.5S,同时又会占用较大的带宽导致吞吐量进一步下降
为什么单线程的Redis能够达到百万级的QPS?相关推荐
- socket io 不使用redis_为什么Redis单线程能够达到数十万、百万级的QPS?
性能测试报告 查看了下阿里 Redis 的性能测试报告如下,能够达到数十万.百万级别的 QPS(暂时忽略阿里对 Redis 所做的优化),我们从 Redis 的设计和实现来分析一下 Redis 是怎么 ...
- 技术如何秒懂你?阿里百万级QPS资源调度系统揭秘
阿里妹导读:TPP(Taobao Personalization Platform, 也称阿里推荐平台 ) 平台承接了阿里集团300+重要个性化推荐场景,包括手淘首页猜你喜欢.首图个性化.购物链路等. ...
- 阿里百万级QPS资源调度系统揭秘
TPP(Taobao Personalization Platform, 也称阿里推荐平台 ) 平台承接了阿里集团300+重要个性化推荐场景,包括手淘首页猜你喜欢.首图个性化.购物链路等.除了提供应用 ...
- 总结:如何使用redis缓存加索引处理数据库百万级并发
前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...
- 使用redis缓存加索引处理数据库百万级并发
使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...
- 刘志勇:微博短视频百万级高并发架构
本文来自新浪微博视频平台资深架构师刘志勇在LiveVideoStackCon 2018讲师热身分享,并由LiveVideoStack整理而成.分享中刘志勇从设计及服务可用性方面,详细解析了微博短视频高 ...
- oom 如何避免 高并发_微博短视频百万级高可用、高并发架构如何设计?
本文从设计及服务可用性方面,详细解析了微博短视频高可用.高并发架构设计中的问题与解决方案. 今天与大家分享的是微博短视频业务的高并发架构,具体内容分为如下三个方面: 团队介绍 微博视频业务场景 &qu ...
- 微博短视频百万级高可用、高并发架构如何设计?
本文从设计及服务可用性方面,详细解析了微博短视频高可用.高并发架构设计中的问题与解决方案. 今天与大家分享的是微博短视频业务的高并发架构,具体内容分为如下三个方面: 团队介绍 微博视频业务场景 &qu ...
- 百万级商品数据实时同步,查询结果秒出
来自:微微科技公司 前阵子老板安排了一个新任务,要建设一个商家商品搜索系统,能够为用户提供快速.准确的搜索能力,在用户输入搜索内容时,要能从商家名称和商品名称两个维度去搜索,搜索出来的结果,按照准确率 ...
- 百万级PHP网站架构工具箱
百万级PHP网站架构工具箱 在了解过世界最大的PHP站点,Facebook的后台技术后,今天我们来了解一个百万级PHP站点的网站架构:Poppen.de.Poppen.de是德国的一个社交网站,相对F ...
最新文章
- python类型转换-Python中如何进行数据类型转换?
- Python 工具链让你写的代码更规范
- FPGA组合逻辑部件LUT的基本原理
- CheckedListBox扩展方法代码
- [html] 通过设置表单的target=“_blank“来下载文件会被浏览器拦截吗?如何解决?
- 【ZOJ - 3210】A Stack or A Queue? (模拟)
- Python安装扩展库与打包成exe可执行文件的方法
- 不满 C 的繁琐,崛起的 Python 正在蚕食编程语言界!
- 调用feign接口时,如何往header中添加参数
- macOS:实现 声音内录 不用其它App
- 戴维斯分校 计算机硕士,加州大学戴维斯分校计算机研究生录取条件是什么?
- 代码埋点、可视化埋点、无埋点几种数据埋点方案的分析报告
- 网易互娱2017实习生招聘在线笔试第一场-题目3
- Xposed获取微信好友列表(通讯录),看看这是你要的详细吗
- 解决STM8S103K3T6打开BEEP功能遇到的无法操作BEEP_CSR的问题
- 开源免费的舆情系统的架构
- ios sinaweibo 客户端(一)
- 2023 易语言 MuX云切片转码系统前端源码
- 地图标绘软件_6.1地图标绘
- Golang基础链表
热门文章
- 《教孩子学编程(Python语言版)》——1.3 运行Python程序
- 随机生成30道四则运算题3—用户可以参与答题,并且有错误提示和计数
- 设计模式之(Facade)外观模式
- 用Java编写的简单手绘程序--原创
- Android 4.0 API新特性之OVERVIEW
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(3)...
- 数据库练习集1--读书笔记
- poj 2828 Buy Tickets 线段树!!!
- Office for Mac升级提醒如何去掉?关闭Mac的Microsoft AutoUpdate弹框提示
- Illustrator 教程,如何在 Illustrator 中添加文本段落?