首页 > PHP技术 > php高级 > Redis从单线程走到了多线程
2020
05-16

Redis从单线程走到了多线程


Redis简介:

Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:

  • 基于内存运行,性能高效
  • 支持分布式,理论上可以无限扩展
  • key-value存储系统
  • 开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API

 相比于其他数据库类型,Redis具备的特点是:

  • C/S通讯模型
  • 单进程单线程模型
  • 丰富的数据类型
  • 操作具有原子性
  • 持久化
  • 高并发读写
  • 支持lua脚本


为什么redis是高效率的单线程模式:

首先redis里的数据是存储在内存中,对redis里的数据操作的时候实际上是纯内存操作;其次,他的文件事件处理器的核心机制是非阻塞的IO多路复用程序;最重要的是单线程反而避免了多线程频繁上下文切换带来的损耗。


Redis的发展:

Redis从最初的2.4版本已经更新迭代到目前的6.0版本,每个版本都经过了优化和更新;其中最需要我们关注的是6.0之前的版本和6.0版本,6.0之前的版本Redis是单线程模式,6.0的最大新亮点是多线程的引入极大的提高了网络IO的读写负荷。


Redis为什么要引入多线程机制:

Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,对于小数据包,Redis服务器可以处理80,000到100,000 QPS,这也是Redis处理的极限了,对于80%的公司来说,单线程的Redis已经足够使用了。


    但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的QPS。常见的解决方案是在分布式架构中对数据进行分区并采用多个服务器,但该方案有非常大的缺点,例如要管理的Redis服务器太多,维护代价大;某些适用于单个Redis服务器的命令不适用于数据分区;数据分区无法解决热点读/写问题;数据偏斜,重新分配和放大/缩小变得更加复杂等等。


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

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


 协议栈优化的这种方式跟 Redis 关系不大,支持多线程是一种最有效最便捷的操作方式。所以总结起来,redis支持多线程主要就是两个原因:

    • 可以充分利用服务器 CPU 资源,目前主线程只能利用一个核
    • 多线程任务可以分摊 Redis 同步 IO 读写负荷


同样压力下Redis单线程和多线程的结果对比:

Redis多线程实现机制:


流程简述如下:

1、主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列

2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程

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

4、主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行

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

6、解除绑定,清空等待队列


扫码芷若 获取免费视频学习资料

编程学习

查 看2019高级编程视频教程免费获取