FastLoad致力于离线数据在线化,服务业务300+,单日运行次数1000+,在线搬运30TB+的数据,提供数百亿次高效查询,服务稳定性达到99.99%。
在没有FastLoad以前,业务一般都会自己维护读离线数据,写在线存储引擎的业务逻辑。比如,滴滴有很多重要的业务有如下的场景:前一天的订单数据会落到离线平台,经过一些特征提取和分析,转换成业务需要使用的数据。在第二天线上高峰期前,需要把这部分数据及时导入线上,才能够不影响业务逻辑。这些业务都需要定时更新在线数据、线上使用最新数据,下面我们对需求进行提取。
定时更新
像特征数据,一般需要小时级别甚至天级别的更新,所以业务需要有快捷的定时更新功能。
快速更新
特征数据还有一个特点,就是数据量特别大,以乘客特征为例,动辄上 TB 级别数据量。这么大的数据量通过 SDK 写入肯定是不行的。刚开始业务方也确实是这么玩的,直接通过 Hadoop 任务调用 Redis SDK,然后一条条的写入 Fusion,一般是每天凌晨开始写数据,等到早高峰 8 点时大量读取。但是这种方法实践下来,经常导致 Fusion 各类超时,在早高峰打车已经来临时还在写凌晨的数据,非常影响稳定性。因此第 3 个需求是必须快速更新。
稳定性
这个是毋容置疑的。
多表隔离
有些业务有很多类特征数据,他们有隔离存储的需求,也有分类更新、分类查找的需求,因此需要多表来支持逻辑到物理的隔离。
下面我们看下用户正常写存储的流程,如图展示了以RocksDB为引擎的存储的写入过程。
正常灌库流程
如图可见,从Hive写到最终存储的链路比较长,数据要经过几次中转才能最终落盘。我们做一个公式换算,1TB的数据,以5w的QPS写入存储,每个请求写512B,需要大约12个小时,也就是半天的时间才能将数据完全写入。要是每天更新的任务,在早高峰之前根本不能取到最新的数据,是不满足业务场景的。
为了满足上述提及的4点需求,我们需要转换思维,不能拘泥于传统的数据灌入方式。我们萌生了一个快速导入的想法,如果将文件直接拷贝到存储中,就可以避免上图中的1/2/3/4,直接对外开放读。
我们需要以文件方式导入到存储引擎中,借助了RocksDB提供的IngestFile接口,通过用户预先创建好的SST文件,直接加载到硬盘的LSM结构中,已达到快速导入的目的。直接构造SST文件并导入的方式,绕开了上图正常灌库的流程,避免了写WAL日志、写内存、刷盘等操作,同时RocksDB的Ingest能够尽可能地将数据放在LSM结构中最底层的位置,减少L0到Ln层不断Compact带来的写放大。
Ingest SST文件
Ingest SST文件流程为:
总的来说,Ingest导入是RocksDB的一个很关键的功能特性,适合用户数据的大批量写入。上述描述了一个将新文件Ingest到已存在的DB实例中的流程,可以看出是比较重的操作,除了会导致停写停Compact,还会导致MemTable强制刷盘。所以对于每天更新的任务,我们完全可以每天往新的DB实例里导文件,这样就能避免很多的阻塞。
从上述的Ingest文件可以看出,导入文件的堵塞需要付出比较大的代价,堵塞在线写和增大系统Compact。我们可以通过往新DB实例中导文件避免堵塞写,通过保证SST全局有序避免系统Compact。从Hive到SST这一步,我们依赖了大数据引擎进行Map/Reduce,将原始数据作为输入,按照用户提交的拼接Key的方式,启动Map/Reduce任务直接构造最终DB需要的SST文件。
经过上面的背景和技术细节,我们最终完成了如下图的系统架构。
一键式DTS平台——FastLoad系统架构
整个系统分为以下几个模块:
作者介绍:
赵锐,滴滴高级工程师
从事分布式存储NoSQL/NewSQL的相关研发,参与从零开始构建滴滴分布式存储Fusion,有PB级别存储、千万QPS的存储经验。
本文转载自公众号滴滴技术(ID:didi_tech)。
原文链接:
领取专属 10元无门槛券
私享最新 技术干货