当前位置: 首页 > 科技观察

分析型数据仓库中读写分离的实现

时间:2023-03-16 00:17:34 科技观察

分析型数据仓库读写分离的实现与以MySQL为代表的传统事务型数据库相比,数据仓库有一个很大的特点,就是主要针对批量写入和查询进行优化,可能不支持更新,事务的这些高级特性.一些商业数据仓库分析系统,如Vertica,已经可以秒级导入和查询千亿级数据。神策数据一直致力于帮助企业构建数据仓库,实现数据秒级响应,积累数据资产。本文主要通过神策数据的技术探索和实践,探讨如何利用已有的开源组件实现分析型数据仓库的读写分离。为什么要分离读写分析型数据仓库一般具有以下特点:(1)面对复杂的多维分析需求,可以在任意维度进行上卷和下钻。(2)存储的数据一般有很多维度,所以是宽表,一般都是稀疏的。(3)数据量比较大,一次写入,多次查询。针对这样的特点,分析型数据库一般会选择列存储数据格式,比如Parquet。优点是统计分析效率高,对稀疏宽表存储压缩比高。所以我们可以把列存格式看成是一种针对读取优化的存储格式,我们称之为ReadOptimizedStore(ROS)。但是,列存储格式也有一个缺点:这种格式的数据一旦生成,就很难修改,也很难向已有的数据文件中插入新的数据,只能添加新的数据文件。对于像MySQL这样的传统数据库,使用的行存储文件格式是一种适合修改和插入的存储格式。我们可以把这种行存储格式看作是一种为写入而优化的存储格式,称为WriteOptimizedStore(WOS)。综上所述,要实现一个秒级导入查询的分析型数据库,如果只使用ROS,很难支持秒级导入大量数据。如果只使用WOS,很难实现任何维度的秒级查询,所以需要读写分离。读写分离的实现原理数据仓库需要同时拥有WOS和ROS,所以我们为所有的写操作生成WOS类型的文件;同时,所有的读操作主要依赖于ROS文件,也会查询少量的WOS文件。整体示意图如下:图1读写分离示意图。如图所示,需要定期将WOS文件转换为ROS文件。同时,由于ROS在数据仓库中一般分为多个Partition,一个WOS可能会转换成多个ROS文件。.转换过程需要是一个原子操作,因为对于上层的查询引擎来说,同一时刻同一数据只能有一份。开源方案的操作已经简单介绍了读写分离方案的原理。在具体的工程实践中,神策数据的工程师们在方案的选择和实践中仍然面临着诸多困难。下面简单介绍神策数据在数据仓库建设实践中啃过的“硬骨头”。ROS的选择比较简单。我们的工程师选择了Parquet+Impala的查询方案,结合我们的业务特点,做了很多代码层面的优化。WOS可能会有更多的选择。我们可以选择常见的HDFS行存储文件格式,如TextFile、SequenceFile、Avro等。以SequenceFile为例,我们在定义自己的Impala表时,可以指定一个特殊的Partition文件的存储格式为SequenceFile,并在同时,其他Partition作为普通的基于日期的Partition数据,指定格式为Parquet。优点是永远只有一张桌子。后来基于查询效率和未来架构升级的考虑,最终选择了Kudu作为WOS。该表充当WOS,Parquet表充当ROS。所有的写操作都会在Ingesting状态下写入到Kudu表中。当Ingesting表写入到一定大小时,会自动转入Staging状态。这个时候我们一方面生成一个新的Kudu表作为Ingesting表,另一方面我们开始从WOS到ROS的转换,通过一个叫做Mover的任务来完成这个操作。将Staging状态下的Kudu表中的所有数据转换为Partition对应的Parquet表。当Staging状态的表转换完成,Ingesting状态的表已满时,会触发切表操作,需要更新元数据,告诉Impala使用新的数据进行查询。整个切表操作是原子的。而且,转换后的暂存表需要保留一段时间,以避免切表前发起的查询操作没有及时完成。对于查询请求,我们会创建一个包含Staging表、Ingesting表和ROS表的虚拟表,即View。一个用户的查询总是指向一个View,但是底层的物理表经常变化。这样既兼顾了查询数据的持续更新,又兼顾了查询性能的优化。实现过程中还有很多具体的工作要做,比如如何给表增加列,保证每张表的结构一致;Parquet表中有很多碎片文件影响查询效率,如何定时合并。限于篇幅,这里不再详细介绍。神策数据最终的技术架构图如下:图3神策数据技术架构图综上所述,神策数据为了实现数据驱动,在数据的读写效率上做了更深入的探索仓库,也参考了很多优秀的开源项目,针对产品进行了优化适配,代码总量超过10万行。大数据产业的技术是企业的核心竞争力。也希望大家能够在技术和业务层面进行公开讨论。本文作者为神策数据高级研发工程师张光强,版权归神策数据所有。欢迎来到神策数据(ID:SensorsDataCrop)。