摘要: Redis做为高性能的K-V数据库,由于其高性能,丰富的数据结构支持,易用等特性,而得到广泛的应用。但是由于redis单进程单线程的模型限制,单Redis Server QPS最高只能达到10万级别。本文试图通过对Redis做多线程的优化,来达到增强性能的目的。

背景

众所周知redis是单进程单线程模型(不完全是单进程单线程,还有若干后端线程主要做刷脏数据,关闭文件描述符等后台清理工作)。redis中负责主要工作的是主线程,主线程的工作包括但不限:接收客户端连接,处理连接读写事件,解析请求,处理命令,处理定时器事件,数据同步等相关工作。单进程单线程只能跑满一个CPU核,在小包场景下,单个redis server的QPS在8~10万级别。如果QPS超过这个级别,单个redis server就无法满足需求。而常用的解决办法就是数据分片,采用多server的分布式架构予以解决。然而数据分片,多redis server方式也存在若干问题:redis server过多,难以管理;分片之后一些在单redis server上使用的命令无法支持;分片无法解决热点读写问题;分片后数据倾斜,数据重分布,数据扩缩容等也比较复杂。由于单进程单线程的局限,我们期望通过多线程的改造以期充分利用SMP多核架构的优势,从而达到提高单redis server吞吐的目的。对redis做多线程化,最容易想到的方案是每个线程既做IO又做命令处理等工作,但由于redis处理的数据结构相对比较复杂,多线程需要锁来保证线程安全性,而锁粒度处理不好性能反而可能会出现下降。

我们的思路是通过增加IO线程,将连接中数据的读写,命令的解析和数据包的回复放到单独的IO线程来处理,而对命令的处理,定时器事件的执行等仍让单一的线程来处理,以此达到提高单redis server吞吐的目的。

单进程单线程的优点和不足

优点

• 因为单进程单线程模型的限制,redis在实现上将耗时的操作分解成多步,多次来执行(例如dict rehash, 过期key删除等操作),尽量避免长时间执行一个操作,从而避免长时间阻塞在一个操作上。单进程单线程代码编写简单,可以减少多进程多线程导致的上下文切换和锁的争抢。

不足

• 只能使用一个CPU核,无法发挥多核优势。

• 对于重IO应用来说,大量的cpu耗费在网络IO操作上。对于将redis做为缓存的应用,往往都是重IO的应用。这类应用基本上都是QPS很高,使用的命令相对比较简单(多为get,set,incr等操作),但是对RT响应很敏感。这类应用通常带宽占用很高,甚至会跑到百兆级别。当前由于万兆,25G网卡的普及,网络往往已不再是瓶颈,而如何发挥多核优势,充分发挥网卡性能成为需要考虑的事情。

实现

• 线程划分

• 主线程(MAIN THREAD)

• IO线程(IO THREAD)

• WORKER线程(WORKER THREAD)

线程模型

• 主线程:接受连接,创建client,将连接转发给IO线程。

• IO线程:处理连接的读写事件,解析命令,将解析的完整命令转发给WORKER线程处理,发送response包,负责删除连接等。

• WORKER线程:负责命令的处理,生成客户端回包,定时器事件的执行等。

• 主线程,IO线程,WORKER线程都有单独的事件驱动。

• 线程之间通过无锁队列交换数据,通过管道进行消息通知。

收益

压测结果

• 从压测结果来看,小包场景下,读写性能差不多有三倍左右的性能提升。

• 从压测结果来看,小包场景下,读写性能差不多有三倍左右的性能提升。

主从同步速度提升

主从同步优化

• Master向Slave发送同步数据时,数据在IO线程中发送,Slave从主读取数据时,全量数据在WORKER线程中读取,增量数据在IO线程中读取,因此可以相对比较有效的增加同步的速度。

后续工作

• 现在所做的第一部分工作是增加IO线程,优化IO读写能力。进一步的优化可以考虑对WORKER线程进行拆分:每个线程既负责IO读取,也负责WORKER工作处理。

IO线程数设置

• 从测试结果来看,IO线程数最大不要超过6个。超过之后对简单操作来说,WORKER线程往往已经成为瓶颈。

• 进程在启动时需要设置IO线程的个数,在进程运行期间IO线程个数无法修改,按当前的连接分配策略,修改IO线程的个数涉及到连接的重新分配,处理相对比较复杂。

展望

• 随着万兆网卡,25G网卡的普及,如何充分利用硬件的性能需要充分的考虑。多网络IO线程,By pass内核的用户态协议栈等都是可利用的技术。

• 通过IO线程实现数据的迁移,可以无阻塞,IO线程对数据进程Encode,或者命令转发,目标节点实现数据Decode,或者命令执行。

本文作者:kingpeterpaule

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

阿里云Redis多线程性能提升思路解析相关推荐

  1. 【转】Redis学习---阿里云Redis多线程性能增强版详解

    [原文]https://www.toutiao.com/i6594620107123589635/ 摘要 Redis做为高性能的K-V数据库,由于其高性能,丰富的数据结构支持,易用等特性,而得到广泛的 ...

  2. 深度解析双十一背后的阿里云 Redis 服务

    在一片欢呼之中,2018年的双十一完美收官,各项数据不出意外的刷出了新的记录,亮眼的数据背后是阿里过硬的技术支撑.其中阿里云Redis不仅保障了阿里集团内部业务双十一的流量洪峰平稳度过,也让使用阿里云 ...

  3. 前端性能优化方法与实战17 横向对比:百度、阿里云、美团性能方案对比

    前面我介绍了性能优化实践及在 Hybrid下的进阶优化方案,这是我们目前的做法,那么,业界是什么样的情况呢?在这里我就挑选三家互联网公司--百度.阿里云.美团,一起来看看他们是怎么做的? 为什么选它们 ...

  4. 阿里云Redis开发规范

    本文作者:carlosfu 原文链接:https://yq.aliyun.com/articles/531067 摘要: 本文介绍了在使用阿里云Redis的开发规范,从键值设计.命令使用.客户端使用. ...

  5. 王义成:阿里云Redis服务助力游戏行业发展

    2018数据库直播大讲堂峰会Redis专场,来自阿里云高级产品专家王义成带来Redis助力游戏行业的相关演讲.主要从传统数据库的压力开始谈起,着重介绍了阿里云Redis产品架构以及不同的版本,接着对R ...

  6. 阿里云Redis开发规范学习总结

    文章目录 一.键值设计 1. key名设计 2. value设计 3.[推荐]:控制key的生命周期,redis不是垃圾桶. 二.命令使用 1.[推荐] O(N)命令关注N的数量 2.[推荐]:禁用命 ...

  7. 一份完整的阿里云 Redis 开发规范,值得收藏!

    简介:本文介绍了在使用阿里云Redis的开发规范,从键值设计.命令使用.客户端使用.相关工具等方面进行说明,通过本文的介绍可以减少使用Redis过程带来的问题. 一.键值设计 1. key名设计 (1 ...

  8. 阿里云Redis百万千万读写慢排查实战

    背景 20万数据 100M,单条平均大小100K写入redis花费6-8分钟,计算一下NetWork有多少,公式2:100 *1024 KB/360S=284KB/S,发现只有这么点,验证实际是否这样 ...

  9. 阿里云Redis数据过期和淘汰策略解答

    背景 阿里云Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用阿里云Redis时,除了对性能,稳定性有很高的要求外,对内存占用也比较敏感.在使用过程中,有些用户 ...

最新文章

  1. 985博士:导师是院士,直到毕业,我们都没单独说过一句话
  2. word邮件合并一页8个_利用word邮件合并批量制作准考证
  3. 使用Kryo的序列化方式提升Netty性能
  4. 报错:org.apache.hadoop.hive.metastore.HiveMetaException: Failed to get schema version.
  5. 避免需求分析与定义误区的7个招式:作为产品新人,我所遇到的坑(续)
  6. 树莓派-语音聊天机器人+语音控制引脚电平高低
  7. vs2008怎么创建c语言程序,VS2008的使用
  8. 中标麒麟Linux系统串口,中标麒麟操作系统串口调试方法研究-嵌入式-电子工程世界网...
  9. 计算机课外兴趣小组活动教案,科技兴趣小组教案
  10. python绘制图像频谱_python傅里叶变换FFT绘制频谱图
  11. odroid xu4安装ROS melodic+远程登录+Roboware 开发
  12. SSM+天山产业园访客与疫情防控系统 毕业设计-附源码191123
  13. html制作菱锥旋转,几何画板实现三棱锥的旋转的操作方法
  14. 脱单攻略 | 如何找到心仪的另一半?
  15. Linux内核在中国大发展的黄金十年-写于中国Linux存储、内存管理和文件系统峰会十周年之际...
  16. python-os模块使用
  17. Python(x,y)安装
  18. Direx 自学总结一
  19. 那些实用有趣的网站,建议低调收藏
  20. php绕过refer,绕过referer检测url跳转

热门文章

  1. ignite服务中的bean注入为空
  2. 推荐10个很棒的AngularJS学习指南
  3. 简单创建序列和触发器示例
  4. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)
  5. 转: 理解AngularJS中的依赖注入
  6. 再谈工作的主动性和有效提问
  7. 话里话外:按单制造(MTO II)企业的资源瓶颈是怎么形成的?
  8. 1.Hello,World all the time
  9. wget抓取数据,需要用户登录验证
  10. PHP过滤器 filter_has_var() 函数