【原文】https://www.toutiao.com/i6594620107123589635/

摘要

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吞吐的目的。

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

1、优点

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

2、不足

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

四、实现

1、线程划分

  • 主线程(MAIN THREAD)
  • IO线程(IO THREAD)
  • WORKER线程(WORKER THREAD)

2、线程模型

  • 主线程:接受连接,创建client,将连接转发给IO线程。
  • IO线程:处理连接的读写事件,解析命令,将解析的完整命令转发给WORKER线程处理,发送response包,负责删除连接等。
  • WORKER线程:负责命令的处理,生成客户端回包,定时器事件的执行等。
  • 主线程,IO线程,WORKER线程都有单独的事件驱动。
  • 线程之间通过无锁队列交换数据,通过管道进行消息通知。

五、收益

1、 压测结果

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

2、主从同步速度提升

3、主从同步优化

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

4、后续工作

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

5、IO线程数设置

  • 从测试结果来看,IO线程数最大不要超过6个。超过之后对简单操作来说,WORKER线程往往已经成为瓶颈。
  • 进程在启动时需要设置IO线程的个数,在进程运行期间IO线程个数无法修改,按当前的连接分配策略,修改IO线程的个数涉及到连接的重新分配,处理相对比较复杂。

六、展望

  • 随着万兆网卡,25G网卡的普及,如何充分利用硬件的性能需要充分的考虑。多网络IO线程,By pass内核的用户态协议栈等都是可利用的技术。
  • 通过IO线程实现数据的迁移,可以无阻塞,IO线程对数据进程Encode,或者命令转发,目标节点实现数据Decode,或者命令执行。

转载于:https://www.cnblogs.com/ftl1012/p/9569099.html

【转】Redis学习---阿里云Redis多线程性能增强版详解相关推荐

  1. 阿里云容器服务飞天敏捷版详解

    阿里云容器服务飞天敏捷版详解 libinjingshan 2017-04-24 23953浏览量 简介: 阿里云容器服务提供了公共云.专有云以及飞天敏捷版三种部署形态,全方位地满足企业客户利用CaaS ...

  2. 全解析阿里云Alibaba Cloud Linux镜像操作系统详解

    阿里云Alibaba Cloud Linux镜像系统是基于龙蜥社区OpenAnolis龙蜥操作系统Anolis OS的阿里云发行版,针对阿里云服务器ECS做了大量深度优化,Alibaba Cloud ...

  3. 阿里云 linux服务器安装tomcat(图文详解)

    阿里云 linux服务器安装tomcat(图文详解) 前言 博主昨天搞了jdk,现在就让我们一起来学习怎么在阿里云服务器上安装tomcat吧(注:本文极其适合小白!!! ) ------------- ...

  4. 阿里云物联网平台-数据解析脚本详解

    阿里云物联网平台-数据解析脚本详解 var COMMAND_REPORT = 0x00; //属性上报. var COMMAND_SET = 0x01; //属性设置. var COMMAND_REP ...

  5. 【超详细附参考】阿里云部署spring项目基本流程详解及踩坑经验

    文章目录 环境及前期准备 基本流程 购买云服务器 连接云服务器 工具准备 Xshell连接: Xftp连接: 环境配置 JDK安装 Tomcat安装 Mysql安装 Maven安装 项目打包部署 数据 ...

  6. 阿里云服务器共享计算型 n4 实例详解/优惠价格/如何选择

    阿里云服务器共享计算型 n4 实例是阿里云针对普通应用推出的云服务器类型,主要特点是在服务器上共享资源,最大限度的利用了服务器资源性能,性价比很高.看到网友被这么优惠的价格所吸引,又对这款共享计算型 ...

  7. 群晖 阿里云ddns_群晖QuickConnect功能详解

    先来了解下什么是QuickConnect,这是群晖的一个远程访问功能, 有这个功能直接注册一个QuickConnect账号就可以远程访问了, 这样就不需要你的宽带是否有公网ip, 也不需要配置路由器端 ...

  8. 阿里云备案流程和操作步骤详解(图文教程)

    备案前准备: 注册账号--备案前您需要拥有一个阿里云账号(支付宝账户可直接登录) 域名准备--备案前需完成域名注册及实名认证 服务器准备--购买阿里云大陆境内服务器,或获取服务器的备案服务号 备案负责 ...

  9. 阿里云域名备案和域名解析流程详解

    域名备案DNICP(Domain Name Internet Content Provider)的目的就是为了防止在网上从事非法的网站经营活动,打击不良互联网信息的传播,如果网站不备案的话,很有可能被 ...

最新文章

  1. 网络管理员&MCSE2003之12: 第8章 应用管理模板和审核策略
  2. 少年郎,你需要封装好的ViewPager工具类
  3. 深入解析阿里Android热修复技术原理
  4. MySQL(一)SQL执行流程与MySQL架构
  5. LeetCode 4. 寻找两个有序数组的中位数(二分查找,难)
  6. Linux下mysql源码包安装
  7. 人工智能为什么要从本科生抓起?
  8. 【PL/SQL】 学习笔记 (3)if 语句使用
  9. transact和onTransact的区别
  10. docker_3 docker 部署练习
  11. 工作流图形设计器参考资料
  12. [ora-02289] sequence does not exist
  13. 弹性计算 Region 化部署和跨可用区容灾介绍
  14. vue 音频文件打包后找不到文件
  15. node2vec python_图上的机器学习系列-聊聊Node2vec
  16. Error处理: android.media.MediaRecorder.start(Native Method) 报错:start failed: -19
  17. Python - PyMuPDF (fitz) 处理 PDF
  18. 与、或、非、与非、或非、异或、同或
  19. Windows 7的应用程序兼容性和絮叨的应用程序兼容性助手
  20. 项目开发中之如何对接

热门文章

  1. mysql getname_mysql别名取不出值(getColumnLabel和getColumnName的区别)
  2. python线性回归做预测_python-线性回归预测
  3. python求数组的所有组合_使用numpy构建两个数组的所有组合的数组
  4. 数据挖掘:数据清洗、转换和消减
  5. 聚类分析应用之市场细分
  6. Python 柱状图 横坐标 名字_Python爬虫实例(二)——爬取新馆疫情每日新增人数
  7. 用计算机算3次根号0.00005,数值分析复习题13
  8. 图的存储结构之邻接表
  9. 依据经纬度解析商圈scala实现
  10. Linux内核开发_将Linux内核打包成img文件