前言

Redis 官方在 2020 年 5 月正式推出 6.0 版本,提供很多振奋人心的新特性,所以备受关注。

一键获取Redis合集资料文档

提供了啥特性呀?知道了我能加薪么?

主要特性如下:

  1. 多线程处理网络 IO;
  2. 客户端缓存;
  3. 细粒度权限控制(ACL);
  4. RESP3 协议的使用;
  5. 用于复制的 RDB 文件不在有用,将立刻被删除;
  6. RDB 文件加载速度更快;

其中备受关注的就是「多线程模型 + 客户端缓存」,我们只有掌握了新特性原理,才能判断什么时候使用 6.0 版本,如何用的更好更快,不踩坑。

本篇先从 Redis 多线程模型开始,至于客户端缓存、等且听下回分解。

最后,点击下方卡片关注「码哥字节」能加薪。

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

官方答复:

  • 使用 Redis 时,几乎不存在 CPU 成为瓶颈的情况, Redis 主要受限于内存和网络。
  • 在一个普通的 Linux 系统上,Redis 通过使用pipelining 每秒可以处理 100 万个请求,所以如果应用程序主要使用 O(N) 或O(log(N)) 的命令,它几乎不会占用太多 CPU。
  • 使用了单线程后,可维护性高。多线程模型虽然在某些方面表现优异,但是它却引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。

Redis 通过 AE 事件模型以及 IO 多路复用等技术,处理性能非常高,因此没有必要使用多线程。

单线程机制让 Redis 内部实现的复杂度大大降低,Hash 的惰性 Rehash、Lpush 等等『线程不安全』的命令都可以无锁进行

在《 Redis 为什么这么快?》码哥有详细介绍快的原理

Redis 6.0 之前单线程指的是 Redis 只有一个线程干活么?

非也,Redis 在处理客户端的请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的「单线程」

其中执行命令阶段,由于 Redis 是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个 Socket 队列中,当 socket 可读则交给单线程事件分发器逐个被执行。

此外,有些命令操作可以用后台线程或子进程执行(比如数据删除、快照生成、AOF 重写)。

码老湿,那 Redis 6.0 为啥要引入多线程呀?

随着硬件性能提升,Redis 的性能瓶颈可能出现网络 IO 的读写,也就是:单个线程处理网络读写的速度跟不上底层网络硬件的速度

读写网络的 read/write 系统调用占用了Redis 执行期间大部分CPU 时间,瓶颈主要在于网络的 IO 消耗, 优化主要有两个方向:

  • 提高网络 IO 性能,典型的实现比如使用 DPDK 来替代内核网络栈的方式。
  • 使用多线程充分利用多核,提高网络请求读写的并行度,典型的实现比如 Memcached。

添加对用户态网络协议栈的支持,需要修改 Redis 源码中和网络相关的部分(例如修改所有的网络收发请求函数),这会带来很多开发工作量。

而且新增代码还可能引入新 Bug,导致系统不稳定。

所以,Redis 采用多个 IO 线程来处理网络请求,提高网络请求处理的并行度。

需要注意的是,Redis 多 IO 线程模型只用来处理网络读写请求,对于 Redis 的读写命令,依然是单线程处理

这是因为,网络处理经常是瓶颈,通过多线程并行处理可提高性能。

而继续使用单线程执行读写命令,不需要为了保证 Lua 脚本、事务、等开发多线程安全机制,实现更简单。

架构图如下

主线程与 IO 多线程是如何实现协作呢?

如下图:

主要流程

  1. 主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列;
  2. 主线程通过轮询将可读 socket 分配给 IO 线程;
  3. 主线程阻塞等待 IO 线程读取 socket 完成;
  4. 主线程执行 IO 线程读取和解析出来的 Redis 请求命令;
  5. 主线程阻塞等待 IO 线程将指令执行结果回写回 socket完毕;
  6. 主线程清空全局队列,等待客户端后续的请求。

思路:将主线程 IO 读写任务拆分出来给一组独立的线程处理,使得多个 socket 读写可以并行化,但是 Redis 命令还是主线程串行执行。

如何开启多线程呢?

Redis 6.0 的多线程默认是禁用的,只使用主线程。如需开启需要修改 redis.conf 配置文件:io-threads-do-reads yes。

码老湿,线程数是不是越多越好?

当然不是,关于线程数的设置,官方有一个建议:4 核的机器建议设置为 2 或 3 个线程,8核的建议设置为 6 个线程,线程数一定要小于机器核数。

线程数并不是越大越好,官方认为超过了 8 个基本就没什么意义了。

另外,开启多线程后,还需要设置线程数,否则是不生效的

io-threads 4
1.

总结与思考

随着互联网的飞速发展,互联网业务系统所要处理的线上流量越来越大,Redis 的单线程模式会导致系统消耗很多 CPU 时间在网络 I/O 上从而降低吞吐量,要提升 Redis 的性能有两个方向:

  • 优化网络 I/O 模块
  • 提高机器内存读写的速度

后者依赖于硬件的发展,暂时无解。所以只能从前者下手,网络 I/O 的优化又可以分为两个方向:

  • 零拷贝技术或者 DPDK 技术
  • 利用多核优势

模型缺陷

Redis 的多线程网络模型实际上并不是一个标准的 Multi-Reactors/Master-Workers 模型,Redis 的多线程方案中,I/O 线程任务仅仅是通过 socket 读取客户端请求命令并解析,却没有真正去执行命令。

所有客户端命令最后还需要回到主线程去执行,因此对多核的利用率并不算高,而且每次主线程都必须在分配完任务之后忙轮询等待所有 I/O 线程完成任务之后才能继续执行其他逻辑。

在我看来,Redis 目前的多线程方案更像是一个折中的选择:既保持了原系统的兼容性,又能利用多核提升 I/O 性能。

最后

分享一张Redis知识图谱,拿图请点赞。

另外还整理成了40多套PDF文档:全套的Java面试宝典手册,“性能调优+微服务架构+并发编程+开源框架+分布式”等七大面试专栏,包含Tomcat、JVM、MySQL、SpringCloud、SpringBoot、Dubbo、并发、Spring、SpringMVC、MyBatis、Zookeeper、Ngnix、Kafka、MQ、Redis、MongoDB、memcached等等。如果你对这个感兴趣,小编可以免费分享。

「JAVA知识每日一问」:Redis6.0为什么引入多线程?相关推荐

  1. 【JAVA知识每日一问】:Redis6.0为什么引入多线程?

    前言 Redis官方在 2020 年 5 月正式推出 6.0 版本,提供很多振奋人心的新特性,所以备受关注. 提供了啥特性呀?知道了我能加薪么? 主要特性如下: 多线程处理网络 IO: 客户端缓存: ...

  2. 【JAVA知识每日一问】:JDK和JRE的区别是什么?

    前言 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java ...

  3. 单线程不香吗?Redis6.0为何引入多线程?

    Redis 作为一个基于内存的缓存系统,一直以高性能著称,因没有上下文切换以及无锁操作,即使在单线程处理情况下,读速度仍可达到 11 万次/s,写速度达到 8.1 万次/s. 但是,单线程的设计也给 ...

  4. 「Java面试题精华集」Java基础知识篇(2022最新版)附PDF版

    两个星期前,我和我的好朋友决定做一系列的 Java 知识点常见重要问题的小册.小册的标准就一个,那就是:取精华,取重点.每一本小册,我们都会充分关注我们所总结的知识点是否达到这个标准. 昨天晚上终于把 ...

  5. 「每日一问」数据库事务隔离级别有哪些?

    未提交读 在未提交读(Read Uncommitted)级别中,事务中的修改即使没有提交,对其他事务也是可见的.读取到了事务没有提交的数据,就被成为脏读(Dirty Read).事务没有提交的数据是很 ...

  6. 「每日一问」面向对象的基本原则是什么?

    单一职责原则 单一职责原则(Single Responsibility Principle):类应该仅具有一种单一功能,并且该功能应该由这个类完全封装起来.如果一个类承担的职责过多,就等于把这些职责耦 ...

  7. Github 总结!「Java知识体系详细汇总2021版」开放下载了!

    前言 本文是为了帮大家快速回顾了Java中知识点,这套面试手册涵盖了诸多Java技术栈的面试题和答案,相信可以帮助大家在最短的时间内用作面试复习,能达到事半功倍效果. 本来想将文件上传到github上 ...

  8. java集群_「Java知识」MyCat的图文视频讲解,MyCat分片集群分表分库策略

    在一个项目当中,项目经理要求把原先的MySQL数据连接基于mycat来进行改造 .当时就在想MyCat是什么东西?为什么要用它呢? 蚂蚁课堂带你学Java 一.什么是MyCat: MyCat是一个开源 ...

  9. 有小数点是什么类型_「JAVA零基础入门系列」Day3 Java基本数据类型

    前两篇已经将开发环境搭建完成,如果你已经按之前的教程按部就班的完成了部署,那么世界上最优秀的编程语言之一和世界上最优秀的IDE之一已经出现在你的电脑上(此处应有掌声),如果你还没入门,或者正在台阶上踱 ...

最新文章

  1. MySQL安装失败出现could not start the service mysql error:0 错误提示
  2. 拦截器获取请求参数post_SpringBoot拦截器如何获取http请求参数
  3. poj1062昂贵的聘礼(Dijkstra**)
  4. 讲真话的朋友才是我们需要的!
  5. 由一个计数器出发:关于vue使用独立js文件的问题
  6. 8月28日服务器例行维护公告,天涯明月刀8月28日更新了什么-8月28日更新内容介绍...
  7. mysql 垂直分表技术的实战演练,有实战代码。
  8. android碎片实验报告,《Android 移动应用开发》实验报告-范本78(29页)-原创力文档...
  9. poj 3841 Double Queue (AVL树入门)
  10. Mysql客户端的安装
  11. cms完整视频教程+源码 孔浩老师 全131讲
  12. React:setting Styles+ Radium
  13. 使用脚本批量上传内购商品
  14. SQLite 命令行客户端 sqlite3 使用指南
  15. ios系统有哪些好用的思维导图软件?
  16. C 语言隐式类型转换
  17. 2018年计算机考研408操作系统真题(客观题)
  18. 计算机电缆流程,电线电缆生产加工工艺流程介绍(太全了)
  19. 强大的PubMed插件Scholarscope
  20. Web前端工程师必备的PS技能之切图

热门文章

  1. Python入门程序【七】
  2. 如何使用云平台接口群发短信
  3. Altium designer 如何快速生成贴片图 装配图
  4. 无需编译智能研判——您身边的作业自动批改助手
  5. 2022-2-1 牛客 C++项目 —— 线程同步
  6. IT产品经理工作职责
  7. POJ3353 1000进制大整数|水题|题意揣摩
  8. Linux 知:gdb
  9. ATmega16开发板教程(8)——ADC
  10. 锡膏粘度计/手持式锡膏粘度测量采用JIS标准