前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一周收获上千stars的Tendis的存储秘密

一周收获上千stars的Tendis的存储秘密

作者头像
腾讯云数据库 TencentDB
发布2021-02-09 12:10:39
1.1K1
发布2021-02-09 12:10:39
举报

之前,我们开源了腾讯云数据库Tendis存储版,同时又对这个产品的适用场景、架构、特性和发展历程进行了分享。

而这次,我们还对Tendis存储版的技术特性进行深度解读。

进入公众号,后台回复“0120刘锐”,即可下载分享PPT。本文将主要分为简介,架构,和特性三个部分展开。

tendis存储版是一款支持redis协议,数据存放在磁盘的存储引擎。架构可以简单的分为三层,一个是tendis的server层,然后是rocksdb的引擎层,底层我们通常采用ssd来提高io速度,当然sata盘也是可以的。我们通过集群的方式进行分布式部署,可以使得集群有pb级的存储能力,可以进行动态扩展,自适应容灾等功能。

同时,我们也在2020年12月20日进行了开源。

可能有的人不太清楚,我们为什么要提供tendis存储版这么一款产品?

这里最主要的原因是,redis为我们提供高性能的同时,因为是数据全部存于内存,所以成本是非常高的。tendis存储版通过讲数据存放在磁盘上面,来大幅度的减少成本。举个简单的例子,如果用户有640G的数据,每台服务器提供64G的内存,那么需要10台服务器。如果用tendis存储版,可以将640G的数据全部存放于磁盘中,这样就只需要1台服务器就可以了。

既然我们把数据存放在磁盘上面,这里肯定会带来性能的牺牲。但是因为我们采用了多线程,而redis是单线程,所以我们利用线程的优势可以获得单实例高于redis的性能。举例来说,一台32核的服务器,tendis可以获得大约30万的qps,而redis单实例大约为10万qps。当然,redis通过部署多实例的话,性能会比tendis快。

所以:tendis适合数据量大,同时对性能要求不是非常高的场景。

当然这里并不是说tendis的性能就不高,我们假设提供100台服务器的集群,那么可以提供3000万每秒的QPS,我们可以支持大约1000台服务器规模的集群,服务器数量和总qps大约成线性增长关系,相信绝大部分应用是足以支撑的。

我们支持redis的所有数据结构,采用redis同样的resp协议,支持redis的绝大部分命令,同时支持redis-cluster同样的集群管理功能,支持lua功能。所以使用和管理tendis是非常容易和方便的。

在性能上,通过优秀的设计,和一系列的优化,最后我们的性能是非常突出的。具体的数据是:在48核上,set 性能大约48万,延迟p99.9大约是2ms。

因此可以看到我们的性能对比市面上的类似产品,性能还是有较大优势的。

我们线程模型主要分为网络io线程,命令处理线程,分片模块,锁模块,命令处理模块,底层rocksdb引擎。主从复制线程,cluster集群管理模块,搬迁模块,底层compaction线程,过期线程。

我们的命令处理是多线程的,主要的目的是发挥多线程的性能优势,同时解决单线程模型下,慢查询卡住所有请求的问题。这样也可以减少实例,方便运维,同时,相比单线程的多实例部署,单个节点存储的数据更多,对gossip也有好处。

Rocksdb我们采用多实例:这样可以减少资源竞争,充分发挥存储引擎的性能优势。这样我们的key就需要按hash模以store的个数。 

因为我们采用了多线程,而rocksdb内部的锁是kv级别的,如果两个线程同时操作一个redis层的key,会有并发问题。所以这里引入了数据库锁。

同样,在server层一些模块的资源需要加上mutex锁。另外rocksdb内部会有key级锁。

这里有一个死锁的问题要特别小心。这里的解决方法是,对于一个命令,要先上SX锁,再上模块锁,对于多key来说,需要排序,排序的时候,先按store排序,再按chunk排序,最后按key排序。通过固定排序的规则,来保证这些资源上锁的顺序相同,从而避免死锁的产生。

因为我们引入了SX锁,所以在rocksdb层锁冲突基本是不存在的,所以我们可以直接采用悲观事务,这样写代码就不需要retry,会简化相关逻辑。

另外,我们增加了动态调整线程数的功能,这样可以在线上环境进行方便的调整,来达到最高的性能。

这里讲解一下我们的主从复制实现方案:

这里我们采用binlog进行同步,里面存储的是物理kv。我们没有采用逻辑命令同步,主要是为了使得实现更简单,不需要对不确定性命令进行特殊处理。同时我们把binlog跟普通kv在rocksdb的同一个事务里面提交,这样的好处是,可以保证binlog与kv的原子性。

主从复制一般是先把全量备份先复制给从,然后把增量binlog发送给从,从而实现主从复制功能。如果连接断开,从可以告诉主自己的最新binlogid给主,只要这些binlog都还在db里面,就可以实现断点续传。当然,如果断开时间太长,就需要重新全量同步。

Binlog落地,就是将binlog落地到磁盘,然后定期拷贝到冷备中心,主要是用来回档的时候使用。这里为了性能的考虑,master可以不用落地,slave落地。

Binlog因为存储在db目录,如果不回收的话,是非常浪费资源的,所以需要定期回收删除。这里的删除没有采用逐个删除的方式,采用了rocksdb的deleterange接口,来提高删除的效率。

前期存储的时候,我们的binlog和kv是在同一个cf里面的,这里会有一些性能的问题,所以我们将他们拆开了不同的cf,当然,还是在同一个事务进行提交,因为rocksdb是支持事物跨cf的。简单提一下,这个拆分对性能提升是比较大的,这里具体不展开了。

为了实现回档功能,我们需要定期生成备份,回档的时候,先加载备份,然后加载binlog,这样就可以实现秒级的定点回档。为了效率,我们生成备份的时候,可以采用ckpt备份,是通过文件硬链接的方式实现的,所以只需要毫秒级别的时间。如果文件系统不支持硬链,可以采用copy备份。其中,Binlog加载的时候,我们可以按照kvstore采用多线程并行,从而提高回档效率。

为了方便集群管理,我们引入了cluster能力,并尽量保持原生redis的cluster命令。元数据的同步同样采用gossip协议。这样实现了去中心化,自动故障转移,扩缩容的能力。

在扩缩容的时候,我们需要对数据进行节点间的搬迁。原生搬迁的逻辑,有一些缺点,主要体现在,性能差,复杂结构阻塞服务,需要错误重试,依赖第三方工具。

所以tendis在内核层实现了搬迁方案,以slot为单位,通过发送快照,增量发送binlog的方式实现数据迁移,迁移成功后源节点删除数据。这样带来的好处就是,使用起来很简单,一个命令就可以了。交互少,性能高,slot的归属可以实现原子切换,失败容易回滚,不影响服务,这一系列的好处。

这是我们搬迁的时序图。可以看到我们的搬迁源节点的服务是不中断的。复杂结构也不需要上锁,搬迁成功与否是可以保证原子性的。元数据和普通数据的一致性也可以得到保证。如果搬迁失败,我们可以直接回滚,也可以尝试继续搬迁。

为了快速降低源节点的压力,我们可以把搬迁任务分解成小任务,从而实现快速的,逐步的搬迁。

同时,为了降低对在线服务的影响,我们对搬迁进行了限速,可以设置搬迁线程数,设置扫描的速度,设置搬迁数据的流量。通过这些能力,我们可以准确的控制搬迁任务对服务的影响。

对于过期功能,我们分为被动过期和主动过期。被动过期就是用户访问某个key的时候,如果发现它已经过期了,则立即进行删除操作。

主动过期如果是string结构的话,我们通过rcoskdb提供的compactFilter功能进行过期删除。对于复杂结构,因为二级key非常多,而过期信息是存储在一级key上面的,所以无法使用compactfileter来实现。如果进行全量扫描,性能又不允许。所以我们生成了一个过期索引,启动一个线程定期扫描这个索引,发现有过期的,则进行一个删除。

Tendis对lua功能也提供了支持,支持了lua的核心功能。因为我们是多线程,所以我们创建了多个lua的环境lua_state,这样可以发挥多线程的优势,从而实现lua的性能跟普通命令差不多的性能qps。为了保证lua的原子性,我们是在整个eval命令开始的时候,对所有key上一个X锁,从而实现命令的隔离性。

另外,存储版在北京地域上线,大家可以自行访问腾讯云官网进行了解和购买,基于开源的力量,欢迎各位项目共建者,将Tendis打造成能业界最受欢迎的KV存储之一。欢迎点击「阅读原文」,在开源社区中提出您宝贵的Issue和Pull Requests!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云数据库 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档