比Redis快50倍的中间件,为啥这么快?
作者:羽洵
来源:http://suo.im/4Cx7u
今天给大家介绍的是KeyDB,KeyDB项目是从redis fork出来的分支。众所周知redis是一个单线程的kv内存存储系统,而KeyDB在100%兼容redis API的情况下将redis改造成多线程。
上次也跟大家说了,redis多线程正式版将在今年底发布,大家拭目以待
线程模型
KeyDB将redis原来的主线程拆分成了主线程和worker线程。每个worker线程都是io线程,负责监听端口,accept请求,读取数据和解析协议。如图所示:
KeyDB使用了SO_REUSEPORT特性,多个线程可以绑定监听同个端口。
每个worker线程做了cpu绑核,读取数据也使用了SO_INCOMING_CPU特性,指定cpu接收数据。
解析协议之后每个线程都会去操作内存中的数据,由一把全局锁来控制多线程访问内存数据。
主线程其实也是一个worker线程,包括了worker线程的工作内容,同时也包括只有主线程才可以完成的工作内容。在worker线程数组中下标为0的就是主线程。
主线程的主要工作在实现serverCron,包括:
处理统计
客户端链接管理
db数据的resize和reshard
处理aof
replication主备同步
cluster模式下的任务
链接管理
在redis中所有链接管理都是在一个线程中完成的。在KeyDB的设计中,每个worker线程负责一组链接,所有的链接插入到本线程的链接列表中维护。链接的产生、工作、销毁必须在同个线程中。每个链接新增一个字段
int iel; /* the event loop index we're registered with */
用来表示链接属于哪个线程接管。
KeyDB维护了三个关键的数据结构做链接管理:
clients_pending_write:线程专属的链表,维护同步给客户链接发送数据的队列
clients_pending_asyncwrite:线程专属的链表,维护异步给客户链接发送数据的队列
clients_to_close:全局链表,维护需要异步关闭的客户链接
分成同步和异步两个队列,是因为redis有些联动api,比如pub/sub,pub之后需要给sub的客户端发送消息,pub执行的线程和sub的客户端所在线程不是同一个线程,为了处理这种情况,KeyDB将需要给非本线程的客户端发送数据维护在异步队列中。
同步发送的逻辑比较简单,都是在本线程中完成,以下图来说明如何同步给客户端发送数据:
如上文所提到的,一个链接的创建、接收数据、发送数据、释放链接都必须在同个线程执行。异步发送涉及到两个线程之间的交互。KeyDB通过管道在两个线程中传递消息:
int fdCmdWrite; //写管道
int fdCmdRead; //读管道
本地线程需要异步发送数据时,先检查client是否属于本地线程,非本地线程获取到client专属的线程ID,之后给专属的线程管到发送AE_ASYNC_OP::CreateFileEvent的操作,要求添加写socket事件。专属线程在处理管道消息时将对应的请求添加到写事件中,如图所示:
redis有些关闭客户端的请求并非完全是在链接所在的线程执行关闭,所以在这里维护了一个全局的异步关闭链表。
锁机制
KeyDB实现了一套类似spinlock的锁机制,称之为fastlock。
fastlock的主要数据结构有:
struct ticket
{uint16_t m_active; //解锁+1uint16_t m_avail; //加锁+1
};
struct fastlock
{volatile struct ticket m_ticket;volatile int m_pidOwner; //当前解锁的线程idvolatile int m_depth; //当前线程重复加锁的次数
};
使用原子操作__atomic_load_2,__atomic_fetch_add,__atomic_compare_exchange来通过比较m_active=m_avail判断是否可以获取锁。
fastlock提供了两种获取锁的方式:
try_lock:一次获取失败,直接返回
lock:忙等,每1024 * 1024次忙等后使用sched_yield 主动交出cpu,挪到cpu的任务末尾等待执行。
在KeyDB中将try_lock和事件结合起来,来避免忙等的情况发生。每个客户端有一个专属的lock,在读取客户端数据之前会先尝试加锁,如果失败,则退出,因为数据还未读取,所以在下个epoll_wait处理事件循环中可以再次处理。
Active-Replica
KeyDB实现了多活的机制,每个replica可设置成可写非只读,replica之间互相同步数据。主要特性有:
每个replica有个uuid标志,用来去除环形复制
新增加rreplay API,将增量命令打包成rreplay命令,带上本地的uuid
key,value加上时间戳版本号,作为冲突校验,如果本地有相同的key且时间戳版本号大于同步过来的数据,新写入失败。采用当前时间戳向左移20位,再加上后44位自增的方式来获取key的时间戳版本号。
猜你喜欢
1、GitHub 标星 3.2w!史上最全技术人员面试手册!FackBoo发起和总结
2、如何才能成为优秀的架构师?
3、从零开始搭建创业公司后台技术栈
4、程序员一般可以从什么平台接私活?
5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
6、滴滴业务中台构建实践,首次曝光
7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事
8、15张图看懂瞎忙和高效的区别!
比Redis快50倍的中间件,为啥这么快?相关推荐
- 震惊,使用imba.io框架,得到比 vue 快50倍的性能基准
上图表示了vue, react 以及 imba 在 todo 这个项目中拥有60个 todoItem 不同进行 crud 操作的表现.可以看到 imba 达到了每秒操作5w次以上.如果你也想试一试该测 ...
- C++比Python快50倍?如何让C++和Python优势互补?(Boost::Python)
目录 1 为什么需要多语言联合编程? 2 Python调用C++的主要方式 2.1 SWIG 2.2 Boost::Python 2.3 ctypes 3 Boost::Python安装 4 测试实例 ...
- 论文解读:FastSAM | Fast Segment Anything | 基于yolov8-seg实现 比SAM快50倍
发表时间:2023.06.21 论文地址:http://export.arxiv.org/pdf/2306.12156 项目地址:https://github.com/CASIA-IVA-Lab/Fa ...
- 比Redis快5倍的中间件,为啥这么快?
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 来源:http://suo.im/4Cx7u 今天给大家介 ...
- 比 Redis 快 5 倍的中间件,KeyDB
KeyDB项目是从redis fork出来的分支.众所周知redis是一个单线程的kv内存存储系统,而KeyDB在100%兼容redis API的情况下将redis改造成多线程. 线程模型 KeyDB ...
- 比Redis快5倍的中间件,究竟为什么这么快?
来自:云栖社区 作者:羽洵 原文:https://yq.aliyun.com/articles/705239 今天给大家介绍的是KeyDB,KeyDB项目是从Redis fork出来的分支.众所周知R ...
- Batoo JPA –比领先的JPA提供商快15倍
介绍 我早在2000年代就喜欢JPA 1.0. 我甚至在稳定版本发布之前就将其与EJB 3.0一起使用. 我非常喜欢它,因此我为JBoss 3.x实现贡献了一些零碎的部分. 那时我们公司规模还很小. ...
- 掌握这个小技巧,让你的 C++ 编译速度提升 50 倍!
随着 C++ 项目的持续扩大,编译效率越来越是一个问题了.想一想你每天花在这上面的时间,再乘以团队成员的个数,是不是成本很高? 那有没有什么办法,在不需要修改源码,也不更换硬件的情况下提升效率呢?一起 ...
- 【安全资讯】Chrome 的网络钓鱼检测速度提高近 50 倍
作者|御坂弟弟 来源|开源中国 发布时间|2021-07-21 图片来源:开源中国 在最新发布的 Chrome 92 中,Google 改进了网络钓鱼检测算法,使网络钓鱼检测速度快 50 倍,而电量消 ...
- clickhouse大数据分析技术与实战_比Hive快500倍!大数据实时分析领域的黑马
戳蓝字"小强的进阶之路"关注我们哦! 大数据实时分析领域的黑马是ClickHouse一个用于联机分析(OLAP)的列式数据库管理系统(DBMS). clickhouse背景 俄罗斯 ...
最新文章
- 计算机上没有找到服务was,win10系统搭建网站提示计算机“.”上没有找到wAs服务的步骤介绍...
- chemdraw怎么画拐弯的箭头_性感皮衣皮裤的质感服装该怎么画?
- 循序渐进,学习开发一个RISC-V上的操作系统 5.1答案
- [云炬创业基础笔记]第二章创业者测试1
- 【oracle】oracle jdbc驱动与c3p0的一个兼容问题
- 十条实用的jQuery代码片段
- 理论基础 —— 排序
- [Grid Layout] Use auto-fill and auto-fit if the number of repeated grid tracks is not to be def
- matlab 图像读取长宽_计算机视觉学习笔记1 图像读取显示和尺寸变换
- OPPO宣布与哈苏达成影像战略合作
- python编程(python开发的三种运行模式)
- THREEJS - 动态标签(dom方式)
- C语言解决迭代递推问题
- 【过拟合】再也不用担心过拟合的问题了
- 国企“造船”转行测试,成功拿下11K,如今谁又甘心平庸呢?
- 新手程序员如何快速上手公司项目
- android 调用webservice实现手机号码归属地查询
- 大量数据导出Excel 之 多重影分身之术
- SpringBooot
- 移动用户远程接入L2TP配置详解
热门文章
- 【转】python编写规范——中标软件有限公司测试中心
- webpack vs gulp 一张图说明
- 读Zepto源码之assets模块
- 【原】Eclipse部署Maven web项目到tomcat服务器时,没有将lib下的jar复制过去的解决办法...
- 阅读《程序员修炼之道-从小工到专家》阅读笔记02
- [Music]乡村摇滚:Any man of mine
- 自己编写的新闻显示控件(列表显示不过不够完善还需努力)
- inDesign教程,如何将内容与参考线对齐?
- 苹果mac pdf编辑器:Acrobat Pro DC
- 如何使用 Siri 拨打电话并使用电话功能?