为什么我们放弃TiDB而选择研究新闻

2020-04-08 14:13 来源:科创网

最初的标题:为什么我们放弃TiDB而选择研究新闻QL

作者介绍

李鑫,Didi高级软件开发工程师,具有多年分布式存储的设计和开发经验。他曾参与设计和开发NoSQL/纽什尔数据库融合,分布式时间序列数据库哨兵,纽什尔数据库SDB和其他系统。

一、背景

Fusion-NewSQL是滴滴晏子在分布式千伏存储基础上构建的一个NewSQL存储系统。Fusion-NewSQ与MySQL协议兼容,支持二级索引功能,提供超大规模数据持久存储和高性能读写。

我们的问题

滴滴的业务正在快速持续发展。数据量和请求量正在快速增长。存储系统的压力日益增加。虽然通过划分数据库和表可以在一定程度上满足增加数据量和请求的需求,但由于滴滴多条业务线(特快列车、特种列车、双轮列车等)的业务变化迅速,向数据库添加字段和索引的需求非常频繁。),数据库和表的划分方案不利于频繁的模式更改操作,这将导致数据库管理员任务繁重、更改周期长,并对庞大的表操作产生一定的影响。同时,子库和子表方案对二级索引不友好或根本不支持。鉴于上述情况,NewSQL数据库解决方案已经成为我们解决业务问题的方向之一。

开源产品调研

首先,我们研究了开源分布式新闻QL方案TiDB。虽然TiDB是一个非常好的新闻QL产品,但TiDB不太适合我们的业务场景,原因如下:

我们需要一个具有高吞吐量和低延迟的数据库解决方案,但是因为TiDB必须满足事务,2pc自然不能满足低延迟(100毫秒内99rt,甚至50毫秒内99rt)。

我们的大多数业务并不真正需要分布式事务,或者可以通过其他补偿机制绕过分布式事务。这由业务场景决定。

TiDB三个副本的存储空间成本相对较高。

我们的一些内部离线数据被导入在线系统,不能直接与TiDB连接。

基于上述原因,我们开始了自我研究的道路,以满足我们自己的业务需求。

我们的基础

我们不打算从0开始开发一个完整的NewSQL系统,而是在自行开发的分布式KV存储融合的基础上,构建一个能够满足我们业务场景的NewSQL。融合是一个NoSQL数据库,采用Codis架构,兼容Redis协议和数据结构,使用RocksDB作为存储引擎。融合在滴滴内有数百项服务,是滴滴的主要在线存储之一。

融合的架构图如下:

b51b1aa36865493985211f2c8c99dcda.jpeg

我们使用哈希碎片来进行数据分片。从上到下,用户可以通过Redis协议的客户端访问融合。用户的访问请求被发送到代理,然后代理将数据转发到后端融合的数据节点。代理转发到后端数据节点是根据请求的密钥计算哈希值,然后取剩余的时隙片段得到一个固定的slotid,每个slotid将以固定的方式映射到一个存储节点来解决数据路由问题。

对于高并发、低延迟和大容量的存储层,我们需要做的是在其上构建MySQL协议和二级索引。那么如何将MySQL的数据格式转换成Redis的数据结构存储是我们必须面对的问题,这将在后面详细描述。

二、需求

9d8430e1550840979b326bd3a4d60f92.jpeg

考虑到大多数用户的需求,我们挑选出了我们的NewSQL需要提供的几个核心功能:

高吞吐量、低延迟、大容量。

兼容MySQL协议和下游生态。

支持主键查询和辅助索引查询。

模式更改是灵活的,不会影响在线服务的稳定性。

三、架构设计

Fusion-NewSQL由以下部分组成:

解析MySQL协议的禁用程序;

存储数据的融合集群——数据集群;

存储索引信息的融合聚类——索引聚类;

负责架构的管理配置中心-配置服务器;

异步索引程序-消费者负责将数据集群写入的MySQL-Binlog格式的数据消费到MQ,根据模式信息生成索引数据,并将索引数据写入索引集群;

外部依赖,MQ,动物园管理员。

架构图如下:

3bd785e8f3b946129034b5347fad9fdf.jpeg

四、详细设计

存储结构

如何将MySQL表结构数据转换成Redis数据结构是我们面临的第一个问题。

下图:

63234502406d405da45ea18624652156.jpeg

我们将一行MySQL表记录转换为Redis的Hashmap结构。Hashmap的键由表名主键值组成,它满足全局唯一特性。下图显示了MySQL如何通过主键查询转换为Redis协议:

4471c6bc3b70451eaf7a5973c3de2789.jpeg

除了数据之外,索引还需要存储在Fusion-NewSQL中。与hashmap中存储的数据不同,索引存储在键值结构中。根据不同的索引类型,键值的格式略有不同(为了直观起见,下面的格式实际上编码了分隔符indexname):

唯一索引:

Key:

table_indexname_indexColumnsValue

Value: Rowkey

非唯一索引:

Key:

table_indexname_indexColumnsValue_Rowkey

Value:null

造成这种差异的原因是添加行键之前的非唯一索引部分可能是重复的,并且不能是全局唯一的。此外,唯一索引不在键中编码Rowkey,因为当查询语句是简单的"="查询时,相应的Rowkey内容扫描可以通过直接获取操作找到,而不是扫描,这样更有效。

89dac32d6b6549458241cc9bf1db49d9.jpeg

稍后,我们将重点介绍如何在查询过程中通过二级索引查询数据。

数据读写流程

1)数据写入

用户将协议发送到dise-server;通过MySQl-SDK;

Dise-server根据模式检查用户编写的SQL

Dise-server将通过检查的SQL转换为Redis的Hashmap结构,并通过Redis协议将其发送到数据集群。

数据集群将数据写入wal文件,并将数据存储在rocksdb中;

数据集群后台线程使用wal文件,并将它们转换成MySQL-Binlog格式。向MQ发送数据;

异步索引模块使用MQ,根据操作类型(插入、更新、删除)和模式信息通过MySQL-Binlog建立索引信息,并将索引数据写入索引簇。

通过以上链接,用户通过MySQL写操作完成数据存储和索引构建。因为从数据建立索引的步骤是由MQ异步完成的,所以数据和索引之间会有一定的时间差。

2)查询

下面是使用辅助索引查询数据的一个例子:

Dise-server接收SQL查询并根据条件选择索引。如果没有索引被命中,它将向用户返回一个错误(Fusion-NewSQL不能使用非索引字段作为查询条件)。

根据选择的索引,构造查询范围,并通过扫描命令遍历索引簇以获得合格的主键集。下图显示了使用扫描通过一个带有SQL查询的辅助索引的示例:

52bcd0412d7c458cb3056698124be412.jpeg

根据主键,通过hgetall命令在数据集群中查询合格的结果集。

将结果集构建到MySQL中,并将结果返回给用户。

根据上述索引数据的格式,当扫描范围时,前缀必须是固定的,并映射到SQL语句。到时候,这意味着范围查询只能有一个字段,不能有多个字段。例如:

d339d7ad0f734a4e8a5c34df32ad4757.jpeg

该索引是年龄和姓名字段的联合索引。如果查询语句如下:

从20岁的学生中选择*并命名为“W”;

扫描无法确定前缀,也无法通过索引索引名称查询满足条件的数据。因此,使用KV将数据存储在索引中只能满足where条件中的一个字段是范围查询的要求。当然,可以通过分别存储联合索引和通过多个交互来搜索交集来解决这个问题,但是这违背了我们减少RPC时间和延迟的最初设计意图。为了解决这个问题,我们引入了弹性搜索引擎,这将在后面详细描述。

Schema变更

当用户涉及模式变更时,它们将以工作指令的形式发送到控制系统。管理和控制系统批准后,变更请求将被推送到配置中心。在配置中心执行安全检查后,新的模式将被写入存储,更改将被推送到每个节点。

字段更改:

节点接收推送并更新本地模式。对于历史数据,数据实际上并没有被修改,但是在查询期间根据模式信息匹配字段。如果数据中缺少某些字段,则使用默认值。如果数据的字段比模式多,额外的字段将隐藏起来。

新索引分为两个步骤:

新建索引时,历史数据不处理,增量数据立即进入索引构建过程。

通过历史索引构建工具,扫描历史数据以构建新索引的千伏,并对历史数据进行索引。这里有一个优化点。扫描从机而不是主机,以避免对线路造成任何影响。

五、生态构建

单一存储产品解决所有问题的时代早已过去。数据孤岛不能很好地服务于业务。Fusion-NewSQL从设计之日起就考虑开放其他存储系统。

Fusion-NewSQL到其他存储系统

融合-新闻QL通过与MySQL兼容的Binlog格式向MQ发送数据。所有可以访问MySQL数据的下游系统都可以通过在MQ中使用相同格式的Fusion-NewSQL数据将数据保存到其他系统。这样,以最小的工作量最大限度地实现了兼容性。

Hive到Fusion-NewSQL

Fusion-NewSQL还支持通过Fusion-NewSQL提供的快速加载(DTS)工具将离线配置单元表中的数据传输到Fusion-NewSQL,以满足离线数据到在线数据的数据流。

如果用户自己完成数据流,他通常会扫描Hive表,然后构建MySQL的写语句,将数据一个接一个地写入Fusion-NewSQL。流程如下:

46cccb1c3c784263b9ec86852927ce0f.jpeg

MySQL客户端向DiseServer发送写请求。

DiseServer解析MySQL,将其转换为hashmap,并通过Redis协议将转换后的数据发送到数据集群。

数据集群的存储节点接收数据并将数据写入wal文件。

数据集群的存储节点遵循RocksDB写入过程,包括写入memtable。也有可能memtable已满,发生刷新,并触发后台压缩。

异步线程使用wal并将数据以MySQL-Binlog格式发送到MQ。

异步索引器使用MySQL-Binlog,构建索引集群所需的数据,并向索引集群发送写请求。

索引群集的存储节点写wal。

索引簇的存储节点进入RocksDB的写入过程。

从以上过程可以看出,这种迁移方法有几个难点:

需要将Hive导入到Fusion-NewSQL数据中的用户需要开发一组具有相同逻辑的代码,维护成本很高。

每个Hive数据都必须经过一个长链接,数据导入需要很长时间。

离线平台数据量大,吞吐量高,直接大大提高了在线系统的QPS,对在线系统的稳定性有很大的影响。

基于上述难点,我们设计了一个快速加载数据导入平台。通过约定从Hive到Fusion-NewSQL的表格式,我们使用Hadoop并发地处理数据,并构造由RocksDB识别的sst存储文件,绕过复杂的DISE写链接,并将数据直接导入到Fusion-NewSQL中。过程如下:

2321d2328f934d64a07fbe4da3134793.jpeg

用户填写工作单,并选择将指定配置单元表的某些字段映射到融合-新闻查询表的字段(这里配置单元中的多个字段可以形成一个融合-新闻查询表字段)。

Hadoop遍历配置单元表,并通过Zookeeper获得数据应该存储在数据集群和索引集群中的路由信息。

经过上述遍历和计算,数据被直接构造成可被Rocksdb识别的sst,并且存储的数据已经是由DISE表结构信息组成的千伏数据。

sst文件直接发送到指定的存储节点,存储节点或通过Rocksdb提供的摄取功能,sst文件直接加载到Fusion-NewSQL中,用户可以读取。

该方案避免了冗长复杂的写链接,不增加系统的QPS,并且在磁盘和网络IO没有达到瓶颈的情况下,对在线访问几乎没有影响。同时,用户只需要填写从Hive到Fusion-NewSQL的模式映射关系,他们不再需要关心实现。

通过ElasticSearch实现复杂查询

在使用MySQL或Fusion-NewSQL的过程中,我们发现了一个场景:业务的查询条件非常复杂,涉及大量的字段、条件和聚合。在这种情况下,企业将选择弹性搜索作为MySQL或Fusion-NewSQL的下游,并将数据导入弹性搜索。然后通过弹性搜索丰富的搜索能力,先从弹性搜索中获取MySQL或Fusion-NewSQL中数据的主键,然后根据主键获取所有数据。

根据上面的场景,Fusion-NewSQL提供了一种特殊的索引类型:ES。创建索引时,用户可以检查需要复杂查询的字段,并共同构建一个专家系统索引。这不仅满足了业务需求,还避免了为每项业务开发一套与弹性搜索交互的复杂逻辑,并将数据库使用界面统一到MySQL。同时,它也弥补了前面提到的融合新闻的千伏二级索引不能支持多场距离检索的能力。

架构图如下:

96bb2aab9f5f41fca8976883dba1f6a7.jpeg

专家系统索引只将专家系统索引中包含的字段信息和主键写入上图红色4处的弹性搜索。如果在查询中选择了专家系统类型的索引,绿色1将根据where条件中涉及的字段组装弹性搜索的DSL语句,从弹性搜索中获取主键,然后从数据集群中获取主键。由于弹性搜索查询的延迟较慢,融合新闻查询可以对一个表的多个索引同时支持KV索引和ES索引,KV索引的延迟要求较高,查询条件相对简单。对于复杂的查询条件和低延迟要求,使用了专家系统索引。

六、总结

Fusion-NewSQL目前拥有70项核心业务,如订单、预测、账单、客户中心、交易引擎等。总QPS功率超过200瓦,总数据超过600兆字节。

8662708fc86e4549a026081f6cc87a31.jpeg

当然,Fusion-New不是一个通用的、完整的NewSQL方案,但它基于现有的NoSQL数据库,通过支持SQL协议并结合各种组件来构建一个外部表达的数据库。然而,这种方法能够以最小的开发成本和高投入产出比满足大多数业务场景。

七、后续工作

支持的东西是有限制的,比如允许业务规划落入一个可以支持单个跨线交易的数据节点。

实时索引取代了异步索引,满足了读写操作的要求。目前,已经有一种直写补偿机制的方案,该方案满足正常状态的实时索引,没有分布式事务,并保证异常情况下数据索引的最终一致性。

更多的SQL协议和功能支持。

作者李欣

来源:滴滴科技(身份证:滴滴科技)

dbaplus社区欢迎所有技术人员提交他们的贡献。提交的电子邮件地址是editor@dbaplus.cn

活动推荐

2020年4月17日,北京,Gdevops全球敏捷运维峰会将开启年度首站!专注于数据库、智能运维、金融科技等领域,与阿里、中国银行、平安银行、中国邮政消费金融、中国联通大数据、新居网等技术代表合作。展望云时代数据库的发展趋势,解决运维转型的困境。

今晚8点和58家庭运营和维护专家杨经营将带来 《业务上云后,58到家运维平台的演进之路》 主题分享,回答如何对全业务托管公共云进行高效运营和维护。基于公共云的操作平台和IDC有什么区别?应该如何在公共云上构建操作和维护自动化?获取直播地址,添加vx:dbafeifei

b0e996d7115e49e29ff2ebc0fea48e86.jpeg

标签: 存储 NewSQL Fusion

热门文章

热点图文