我们身处一个大数据时代,企业的数据量爆炸式增长。如何应对海量数据存储和处理的挑战,建设好数据平台,对一个企业来说是很关键的问题。从数据仓库、数据湖,到现在的湖仓一体,业界建设数据平台的新方法和新技术层出不穷。
理解这些方法和技术背后隐藏的演进脉路、关键问题、核心技术原理,可以帮助企业更好地建设数据平台。这也是百度智能云推出数据湖系列内容的初衷。
本系列文章将包含几个部分:
本篇将作为数据湖整个系列的开篇,为大家介绍数据平台技术的历史和发展过程中遇到的一些关键技术问题。
后续内容将分为两大主题,从存储和计算的两个角度出发介绍数据平台中的核心技术原理和最佳实践,以及百度智能云对这些问题的思考。
"Data is the new oil." — Clive Humby, 2006
Clive Humby在 2006 年说出这句 “数据是新的石油” 后,迅速成为大家的共识。这哥们一生的轨迹是大数据时代最好的注脚,他最早是一位数学家,后来和妻子联合创建了一家数据公司,再后来成立了专注于数据领域的投资基金。说这句话的时候,Clive Humby 正在向资本市场卖力地推销他和妻子创建的公司。资本市场喜欢这样简单有力的金句,他的公司在 5 年后卖出了好价钱。
对于数据的所有者、数据行业的从业者而言,这句话只说出了一半真相。Michael Palmer 对这句话进行了补充:
"Data is just like crude. It's valuable, but if unrefined it cannot really be used. It has to be changed into gas, plastic, chemicals, etc to create a valuable entity that drives profitable activity; so must data be broken down, analysed for it to have value." — Michael Palmer
简单来讲,就是 “数据需要提炼才能释放真正的价值”。
对于一个企业来说,最容易理解和最容易做的是 “大数据” 3 个字的 “大” 字,在意识到经营各个环节的数据中可能蕴含着营收、用户数增长的奥秘之后,往往积累了大量的原始数据。这些原始数据就是原油,尽管珍贵,但包含了很多的噪音、杂质,甚至错误,不同数据间的内在关系也不是显而易见的。这距离需要挖掘的奥秘还有很长的路。要洞悉这些奥秘就需要继续 “提炼”,就是使用恰当的方法对原始数据进行整理、提纯、组合、分析,去芜存菁、抽丝剥茧,揭示数据中真正有价值的部分,最终转化为业务增长的驱动力。
支撑这一 “提炼” 全流程的基础设施就是一个企业的数据平台。数据平台之于数据,就好比炼油厂之于原油。
随着企业数据量的爆炸式增长,以及越来越多的企业上云,数据平台面临的数据存储、数据处理的挑战越来越大,采用什么样的技术来构建和迭代这个平台一直是业界研究的热点,新技术和新思路不断涌现。这些技术归纳下来以数据仓库 (Data Warehouse) 和数据湖 (Data Lake) 为两类典型的路线。近年来这两个路线在演进过程中边界日趋模糊,逐渐走向融合,开始形成所谓的现代数据架构 (Modern Data Architecture),又称湖仓一体 (Data Lakehouse)。
在讨论具体的技术问题之前,我们先看下业界的数据平台长什么样:
数据平台 = 存储系统 + 计算引擎 + 接口
这几部分的作用可以概括如下。
数据存储解决将原料存进来的问题,具有时间跨度长、来源分散、集中存储的特点。
计算引擎的目标是从数据存储中提炼有效信息。遗憾的是,目前业界并不存在一个大一统的计算引擎,根据模型、实效性、数据量的要求,往往采用不同的解决方案。典型的,对于深度学习任务使用 TensorFlow、PyTorch、PaddlePaddle 等框架,数据挖掘等离线计算采用 Hadoop MapReduce、Spark 等引擎,商业智能分析使用 Apache Doris 等 MPP 数据仓库。
不同的计算引擎对数据存储的格式的要求也不尽相同:
计算引擎在计算过程中生产的一些有价值的数据,一般也会存回数据存储中,以方便其他业务使用。
接口决定了数据平台的用户如何使用计算引擎。最为流行的是 SQL 语言接口。一些计算引擎还提供了封装层次不一的编程接口。对于一个企业来说,提供的接口种类越少越通用,对用户来说越友好。
数据仓库出现的时间要远比数据湖要早。最初的场景是商业智能 (Business Intelligence),简单说就是企业的管理层希望有一个方便看各类经营数据的仪表盘,展示一些统计、趋势数据,数据来源是 ERP、CRM、业务数据库等。为了把这个需求做得好用,最佳的方法是将企业内部各个数据源的数据统一收集到单个站点上归档,并维护历史数据,让相关的查询需求在这一个站点解决。这个统一的站点就是数据仓库。
主流的数据仓库实现基于“联机分析处理 (Online Analytical Processing, OLAP)”技术。在数据仓库诞生之前,业务已经广泛在使用 MySQL、Orcale 等关系型数据库,这类数据库基于“在线交易处理 (On-Line Transactional Processing, OLTP)”技术。OLTP 数据库中的数据有固定的格式,组织清晰,支持的 SQL 查询语言好用易懂。同时,其自身又是数据仓库最重要的数据来源之一。因此,直接使用 OLTP 数据库来建设数据仓库是一个很自然的想法。但很快,大家就发现数据仓库有自己的业务特点,基于 OLTP 遇到了瓶颈,OLAP 获得独立发展的契机:
因此,现代数据仓库架构的特点是分布式、列式存储、MPP 计算引擎。用户发起计算任务后,数据仓库的MPP 计算引擎将计算进行分拆,每个节点负责处理一部分,节点间并行计算,最终汇总结果输出给用户。
数据仓库是典型的 “Schema-on-Write” 模式,要求存储的数据在写入的时候处理成预先定义的格式,即schema。这就好比数据仓库的管理员提前确定了一个包装盒的样式,所有的货物 (数据) 必须用包装盒装好,整整齐齐才能进入仓库。
数据源的原始数据往往和定义好的 schema 存在差异,因此导入的数据需要经过 ETL 过程,ETL 是抽取(Extract)、转换 (Transform)、加载 (Load) 这三个步骤的缩写。Extract 阶段从原始数据源读取进行数据清理(data cleansing) 纠正其中存在的错误、重复。然后进入 Transform 阶段,做必要的处理将数据转化成指定的schema。最后,数据入库 Load 到数据仓库中。
内蒙古自治区白云鄂博矿,全球唯一一个同时包含 17 种稀土元素的矿。在长达 60 多年的时间里,这个矿一直被当成铁矿开采,后来随着稀土战略价值的提升,以及开采技术的进步,才转型为中国最大的稀土矿藏。
讲这个故事是想说明原始数据的重要性,原始数据就像白云鄂博矿,除了已经被发现的铁,还可能蕴藏着储量丰富的稀土。数据仓库的 “Schema-on-Write” 模式要求我们在处理数据之前就确切的知道我们挖的是什么,当时间流逝,历史数据只剩下数据仓库中保存的那些时,我们可能连丢弃掉了哪些稀土都不会知道。
更好更多地保留原始数据,避免丢失重要的未知信息,这是数据湖概念的初衷。数据湖提倡所有的数据,不管是数据库的结构化数据,还是视频、图片、日志这类非结构化的数据,都以它们原始的格式存储到一个统一的存储底座中。各个数据源,仿佛一条条河流,汇聚到这个统一的 “湖” 中融为一体,所有的数据使用方由这个“湖” 统一供水。
由于缺乏明确的结构信息,数据湖使用 “Schema-on-Read” 模式,用户在读取数据后再将其转化为对应的结构进行处理。和数据仓库的 “Schema-on-Write” 相比,对数据的处理流程变成了 ELT,即 Transform 阶段在Load 之后发生。
“Schema-on-Read”由于结构非常松散,对计算引擎的约束较少,业界事实上根据不同的场景发展出多种计算引擎。
传统的数据湖,是大数据体系的等价词,主要经历了 “存算一体” 和 “存算分离” 两个阶段:
阶段 1:存算一体数据湖
这一阶段企业基于 Hadoop 生态开展数据湖,使用 HDFS 作为数据存储,使用Hadoop MapReduce、Spark 等计算引擎,计算和存储资源在同一批机器上,扩容集群会同时扩容算力和容量。云计算发展起来之后,这套架构被从线下 IDC 机房原封不动地搬到云上。
阶段 2:存算分离数据湖
在经历一段时间的实践之后,存算一体架构遭遇到了瓶颈,主要体现在几个方面:
人们在解决这些问题的过程中注意到云厂商的对象存储服务。这种服务提供了一个性能和容量近乎无限扩展、成本低廉、serverless 的存储系统。除了在部分文件系统接口 POSIX 兼容性方面 (如原子 rename、边写边读等) 存在不足,这个服务解决了上述的痛点问题,是 HDFS 的一个合适替代品。实际上,下一代 HDFS 系统OZone 系统也借鉴了对象存储的思路来解决上述问题。
以对象存储为基础的数据湖诞生了“存算分离“架构。存算分离的特点是计算资源和存储资源独立扩展。
存算分离架构中的存储是云厂商提供的对象存储服务。和自建 HDFS、OZone 相比,云厂商最大的一个优势来自规模。云厂商需要足够大的集群来存储海量的用户数据,数据量越大,集群的规模就越大,节点、设备就越多,能够提供的整体性能就越高。对于单个用户来说,就能“借用”到比同等规模自建 HDFS 更高的性能。足够大的存储资源池,是存算分离架构能够工作的前提和底气。
在对象存储解决了扩展性、性能、成本的基础上,serverless 的产品形态让存算分离数据湖的计算引擎很容易独立伸缩其算力,甚至可以做到需要计算的时候才去分配计算资源,计算完成就立刻销毁资源,仅为使用的资源付费,在成本和效率方面做到最优。这一点是存算分离架构和云计算之前的时代是不可能做到的。
对于云厂商来说,这种架构的转变让对象存储服务一下子成为舞台的焦点,让云厂商甜蜜的同时也考验着他们的技术实力,吹过的牛逼必须不打折扣地一一兑现。这里的主要挑战包括:
数据仓库和数据湖套用前文的公式归纳为:
数据仓库 = 结构化数据存储系统 + 内置计算引擎 + SQL 接口
数据湖 = 原始数据存储系统 + 多种计算引擎 + 包含 SQL 在内的多种接口
数据仓库和数据湖就好比是手机届的 iOS 和 Andriod:
数据湖将 “存储什么数据、如何使用数据” 的决定权还给了用户,约束非常宽松。但用户如果在数据入湖的时候没有做好数据的管理工作,有用无用、高质量低质量的数据被一股脑丢进来了,使用的时候很容易找不到需要的数据。长期下来,数据湖变成了一个巨大的垃圾场,规范的叫法是 “数据沼泽”。
为了避免数据湖最后变成数据沼泽,需要解决几个重要的问题:
问题 1:数据质量问题
仅靠 “Schema-on-Read” 在计算时直接处理原始格式的数据,过滤掉其中的无用信息,这个工作每次计算都需要重复做,既降低了计算的速度又既浪费了算力。
一个可行的方式,是在数据湖借鉴数据仓库的做法,通过一轮或多轮 ETL 对原始数据进行一些前置处理,将数据转化成对计算引擎更友好、数据质量更高的数据。原始数据不删除,而 ETL 产生的数据同样存储在数据湖中,这样既保留了原始数据,又保证了计算的效率。
问题 2:元数据 (metadata) 管理问题
元数据是描述数据的数据,它对数据的重要性在于它负责回答那几个重要的哲学问题 “我是谁?我在哪里?我从哪里来?”。数据的格式信息 (例如一个数据库表文件的字段定义) 、数据的位置信息 (例如数据存储在哪个路径)、数据的血缘关系 (例如数据是从哪些上游数据处理得到的) 等等都需要依赖元数据来解释。
为数据湖建立完善的元数据可以帮助用户更好地使用数据。一般元数据分为两部分,都很重要。一个是集中的数据目录 (Data Catalog) 服务,一般这类服务具备一些自动分析和模糊搜索的能力,用于管理和发现数据湖中都有哪些数据。另外就是数据自己内置的元数据,这些元数据可以保证即使数据挪了位置也能准确的解释数据。打个比方,数据目录好比图书馆里的书架,通过对书籍分门别类整理归档,能够快速地定位书籍所在的位置;数据内置的元数据好比一本书的目录部分,通过目录可以快速了解这本书大概包含哪些内容,都位于哪一页;当一本书从一个书架挪动到另外一个书架上,改变的只是书的位置,书的目录没有变化。
元数据管理还需要解决数据权限的问题。数据湖底层依赖的存储系统,无论是HDFS,还是对象存储,提供的数据权限是以目录和文件为单位的,粒度和上层业务的需求并不一致。举个例子,一个图片识别 AI 任务的数据集有很多的小文件,这些小文件的应当被视作一个整体,不存在“一个用户有权限访问其中部分文件,没权限访问另外一部分文件”的现象。另外一个例子是,一个文件存储了业务订单的数据,对于销售人员、公司高管,能够查看的数据范围是不一样的。这些都要求更精细的权限控制。
问题 3:数据版本问题
数据入湖通常不是一锤子买卖,导入一次从此就不更新了。例如,从线上用户订单数据库采集数据到数据湖用于后续分析,需要源源不断的同步新的订单。解决多次导入问题最简单的方法就是每次都全量导入一遍,但这种方式显然过于粗糙,会增加资源消耗,数据导入的耗时也较高。
因此,支持对数据增量更新是数据湖的一个重要能力。这其中存在一些棘手的难题,包括:1) 正在更新的时候如何处理读请求;2) 更新操作中断后如何恢复;3)如何识别不完整的更新操作;4) 数据被一次错误的操作污染之后如何复原。后面的这些棘手问题在数据库和数据仓库中的答案是 ACID。数据湖领域近年来出现的表格格式 (Table Format),如 Apache Iceberg、Apache Hudi、Delta Lake 致力于为对象存储补齐这些能力,已经成为数据湖的重要组成部分。
问题 4:数据流通问题
现实场景复杂多变,对数据处理的实时性、准确性要求不尽相同,业界也因此发展出来诸多的计算引擎。如果这些计算引擎各讲各话,只认自己定义的存储格式时,那么同样的一份数据在被不同计算引擎处理时,需要反复的做 Schema-on-Read 或者 ETL,白白浪费大量的资源。这显然不合理。
不需要经过翻译,大家都能讲普通话是最理想的。在大数据的发展过程中,逐渐形成了一些常用的数据格式(Apache Parquet、Apache ORC 等) 和表格格式(Apache Iceberg、Apache Hudi、Delta Lake 等),这些技术逐渐被越来越多的计算引擎支持,某种意义上充当了数据湖领域普通话的作用,改善了数据流通问题。
数据湖在迭代过程中,和数据仓库的界限越来越模糊,逐渐呈现出融合的趋势:
除了数据仓库、大数据外,企业内还存在其它重要的计算类型,最常见的就是AI、HPC 等高性能计算。数据湖的性能优势的体现是吞吐高,元数据性能和延时一般,而高性能计算对元数据性能、延时有比较苛刻的要求。因此,企业还需要在数据湖外为这类业务额外维护一套或多套高速文件存储系统 (Lustre、BeeGFS 等)。本质上看,高性能计算使用的框架也是某种计算引擎,数据的来源和产出也是企业数字资产的一部分,如何将这部分业务纳入到数据湖体系中是一个重要的问题。这个问题的答案和数据仓库存算分离是类似的,解决思路也是相通的,同样是两个路线:
湖仓一体这个说法最早是 Databricks 提出的,在业界尚有分歧,其它一些竞争公司会尽力避免使用这个术语,AWS 采用的是现代数据架构 (Modern Data Architecture) 的说法。但不管怎么命名,湖仓一体都代表着数据湖的下一阶段的形态,其本质是企业的终极一站式数据平台。
这个数据平台首先是一个 all-in-one 的存储基础设施,满足了企业所有的数据存储需求,不光能满足低成本的存储需求,也能满足高性能的需求。其次,数据平台超越了数据仓库、大数据的范畴,之上运行着数据仓库、大数据、AI、HPC 等各种各样的计算引擎,这些不同的计算引擎都能消费和产出互相能理解的数据结构,数据在业务之间的流转无障碍。
根据前面的讨论,我们可以使用数据平台公式对湖仓一体进行简单的归纳:
湖仓一体 = 配备元数据层和加速层的对象存储 + 数据仓库、大数据、AI、HPC 等各个领域的计算引擎 + 包含SQL 在内的多种接口
存储系统部分,对象存储已经成为事实上的数据湖标准存储,其生态繁荣程度远超其它种类的云存储产品。对于对象存储无法很好解决的存储问题,需要搭配合适的元数据层和加速层。
计算引擎部分,存在数据仓库、大数据、AI、HPC 等各类引擎。数据流转是最基本的问题。此外,还有一个重要的问题是这些计算引擎本身的调度和管理问题。从资源的角度看,这些计算引擎主要消耗 CPU、GPU 等种类的计算资源,具备资源共享的基础,提高资源的整体利用率对用户来说意味着节省成本。解决这个问题有两个手段。
接口部分,其实取决于具体的计算引擎,能用 SQL 表示的场景 SQL 是最好的选择,其它场景需要用户熟悉引擎的编程接口。
企业数据量爆炸式增长,业务场景日趋复杂,推动着数据平台技术不断变革。数据仓库、数据湖,这两种数据平台的技术路线在过去的实践中充分展现了各自的优点和缺陷,近年来开始融合,取长补短,向所谓的湖仓一体或现代数据架构迭代。
不断地涌现的新技术、新方法,是无数从业者集体智慧的结晶,而开放的基调则是促成这一切的催化剂。这一领域的开放体现在很多方面:
在这开放的基调下,整个行业,无论是用户还是平台,都对数据平台有自己的思考和看法。我们也希望借此表达我们的一些观点,一方面是希望能给业界提供一些浅薄的见解,另一方面未来回看时对自己而言也是雪泥鸿爪。
接下来本系列的文章,将围绕存储和计算的两大主题,介绍数据平台中的核心技术原理和最佳实践,以及百度智能云对这些问题的思考。帮助读者能对数据湖形成系统性认识,在做数据平台建设时更有思路。