关键字太多, 知识点太多, 转帖, 学习, 读了很长时间
OLAP 是一个很卷的赛道,创业公司也众多。在本文中,笔者基于 10 年的大数据与数据仓库的工作经验,就目前的主流趋势:离在线一体化、引擎一体化、云原生化等写一些思考,抛砖引玉,希望能与各位共同探讨。
主流趋势一:离在线一体化
数字经济时代,越来越多的企业通过数据驱动业务增长、优化流程及更多的业务创新。企业数据朝着海量、实时化、多样化的趋势演进,这也对企业数据仓库提出了新的挑战与演进诉求。同时,数据正在发生质的变化,数据体量爆炸性增长,实时数据比例大幅增长,数据类型也越来越丰富。数据业务也在面临转型,从传统的 T 1 到全实时,从离线到离在线一体化。随着基础设施的上云,以 Snowflake 为代表的云原生数仓也快速发展,其弹性、按需计费等特点一方面满足了企业降本增效的需求,另一方面也满足企业快速发展的数字业务的需求。
过去数年,离线数据仓库与在线数据仓库正处在融合之中,我们称之为离在线一体化。数据仓库从存储与计算独享节点并行处理以在线查询为主的模式发展为支持离线 ETL、机器学习、在线查询的云原生离在线一体化数据仓库,可以一体化解决数据仓库 ODS、DWD、ADS 等各层的清洗、查询需求,做到从业务数据库与埋点数据同步到离在线数据仓库后,一体化满足客户数据业务需求。离在线层面具体技术点有以下四大方面:
计算引擎:MPP 与 BSP 模式融合,做到一条 SQL 可以在一个引擎内部毫秒级查询到小时批处理,如 BubbleExecution;执行层以向量化、算子结合新硬件指令集优化为主要方向;为了更好发挥性能及内存控制的优势,一般会用 C 重写引擎(如 Velox),还有类似 Gluten 项目帮忙融合 C 执行引擎 (如 Velox&CK) 到现有 Java 分布式框架 (Presto&Spark) 中;云原生架构下,需要 Shuffle 服务解决本地无盘,Shuffle 服务同时也可以解决 Shuffle 过程小文件及网络连接等问题,业内实践较多,如 Magnet。
存储引擎:为了支持实时写、离线批量写入、在线秒级查询、离线高吞吐查询等需求,多数数仓存储引擎会舍弃 StrongConsistency(单副本如 HBase,多副本 RaftTiDB),选择 EventualConsistency。为了支持在线实时写,实时写是行存,compact 后转列,大吞吐 BulkLoad 直接列存。最终数据是存放在大吞吐的对象存储或者分布式文件系统。在线实时写一般会依赖 Server 的支持(一般内存为行,落盘为列),也可以是一个写入服务,如 Rockset(云产品居多),或者读写在一个进程,如 ClickHouse(开源引擎,简单内聚)。数仓格式最终为列存,一般不会采取 BTree 原地索引更新的模式,多数是基于 LSM,做增量数据与历史数据的合并。由于离线数据会写在远端的分布式文件系统中,为了弥补远程的带宽瓶颈,会有 Cache 服务。在加速上,有构建稀疏索引,也有构建融合索引,比如 RowIndex 为了基于行的点查、ColumnarIndex 为了聚合分析,SearchIndex 为了模糊查询。
元数据:离线与在线元数据统一,除了存储引擎提供的内表视图外,由于一部分数据是以外表存放在对象存储或者其他的存储系统中,因此构建一个统一的数据视图。在在线读写场景下,对元数据的访问频率较高,则需要引入不同层次的元数据缓存以缓解系统的压力。另外,不同业务之间存在互相访问数据的需求,这就需要元数据本身是全局的,多租户的,基于关系型数据库无法存放较大的元数据,则需要基于 NoSQL 的系统构建,比如 Snowflake 使用 FoundationDB。
资源多租户共享:在线业务一般 CPU 使用量不高,但是延迟要求高;离线延迟要求不高,但是 CPU 使用量高,且往往业务有每日的波峰。平台为了降低资源成本,应对弹性的挑战,往往需要离线业务与在线业务混部在一起,离在线不能互相影响。这需要做好资源管理,离线与在线混合部署在一起,需要做更加精细化的资源控制,提高售卖率的同时,需要做好离线 Job 的压制或者资源腾挪的处理。
主流趋势二:引擎一体化
通常我们将数据库的使用场景分为 OLTP(在线事务处理)和 OLAP(在线分析处理)。OLTP 场景的特点是大量简单的、数据量较小的查询,但是并发量极高,并且对响应时间(latency)有严格的要求。而 OLAP 场景的特点是查询结构复杂、涉及数据量较大,需要消耗较多的计算资源。
2014 年 Gartner 在报告中第一次提出混合事务分析处理(HTAP),以打破 OLTP 和 OLAP 之间的隔阂,既可以应用于事务型数据库场景,亦可以应用于分析型数据库场景,实现实时业务决策。随着互联网、大数据的飞速发展,爆炸式的业务增速促使分布式成为未来的重要方向,结合分布式的扩展性可以突破单机数据库对于 OLAP 能力上的短板。近年来,各大主流云服务和数据库厂商都在努力满足用户的需求,结合分布式和 HTAP 使其具备同时进行事务处理和在线分析混合负载的能力。比如除了传统数据库厂商 Oracle、SQL Server,以及 Google Cloud Spanner、CockroachDB、TiDB 都是其中的典型代表。HTAP 最近技术的发展趋势是混合存储以及资源的调度和隔离,比如引入面向行式和列式的不同混合存储来支撑 OLTP 和 OLAP 的查询,混合格式的数据存储可以通过一致性共识协议 Paxos/Raft 达到多副本间一致的状态,最后结合优化器的智能调度和 MPP 并行计算能力最大化满足流量隔离、发挥存储等特性。SQL Server 在数据库行式数据基础上引入 In Memory Column Store Index 功能,提升了在线数据库上的 OLAP 性能,而 TiDB 则是在分布式多副本技术基础上,将数据的不同副本采用不同行式和列式进行组织,并结合智能优化器和副本一致性读能力满足混合负载的诉求。
除了业界通用的 HTAP 的方案外,阿里云 TP/NoSQL 与 AP 之间也形成了多个产品组合的引擎一体化方案。不同于一个引擎内部的 HTAP 一体化方案,阿里云以 PolarDB 及 RDS 为代表的 TP 数据库与 OLAP 引擎之间采取直读、或者 CDC 数据同步,再通过 OLAP 引擎进行查询。具体联合的产品组合有:ClickHouse RDS MySQL、PolarDB MySQL ADB MySQL、PolarDB-X ADB MySQL、Lindorm ADB MySQL 等产品联合,做到购买一体化,管控体验一体化,甚至财务一体化。具体如 ClickHouse RDS MySQL,为了强化实时数仓的能力,基于 ClickHouse 的 MaterializeMySQL 组件,云数据库 ClickHouse 作为 RDS MySQL 副本,读取 Binlog 并执行 DDL 和 DML 请求,实现了基于 MySQL Binlog 机制的业务数据库实时同步功能。在使用上,进一步做到了体验一体化,财务一体化:ClickHouse 引擎作为 RDS MySQL 一个分析引擎,客户在控制台可以直接创建实例,计费项目可以显示为 RDS MySQL。在 PolarDB-X ADB MySQL 方案中, PolarDB-X 会把数据 CDC 写到 OSS 中,以列的形式保存,与 ADB MySQL 的元数据关联后,最后通过 ADB MySQL 的引擎完成查询与分析。
主流趋势三:AP 云原生化
从业务侧,就是客户按需计费,按照实际的、甚至按照财务模型倒推的付费模型。从平台侧,就是提升整体资源的使用效率,如 CPU 利用率从 10% 提升到 60~80%,一部分红利来提升自身产品的毛利,一部分红利释放给客户或者说保持相对于竞对的竞争力。另外池化后,不同层次需要引入不同的硬件以达到整体最优的效率;分析类需求比事务类由于在延迟要求不高,数据类也渐渐成为第四产业,其市场规模也不断扩展,分析类的 Serverless 是更加迫切且更加具备可行性的;具体有如下 10 点技术发展点:
存储计算分离、资源归一化是 Serverless 的基础。当前存算分离后,存储一般是基于对象存储或者分布式文件系统设计的。存算分离也有存算架构分离与存算部署分离两部分的含义。存算架构分离就是把存储与计算往往在一个机器上,当前也有不少创业公司把一体化的 Greenplum on 本地磁盘改造为 Greenplum on 对象存储的形态;存算部署分离:以 HBase 为代表的类 NoSQL 存储系统一开始就是存算架构分离,目前也演化为部署形态的分离,比如 HBase 的冷数据放在对象存储。在资源侧,计算资源之前资源是按照实际的 x cpu 与 y memory 分配给客户,客户能直接感知到实际的物理资源;Serverless 后,客户是接触不到实际的物理资源,比如计算是按照归一化的 ACU 给客户的,至于底层 1ACU 对应 1cpu4g,还是 0.9cpu3g,每个引擎会不一致。存储资源一般则是是按照实际存的逻辑空间,实际的压缩算法等并不会直接暴露给客户。
模块拆开,尽可能的线程池化,在保障稳定性情况下提升单模块的 CPU 利用率,降低资源持有成本。一般 Serverless 后,会拓展大量的小客户,数据仓库需要提供非常低的获客成本。此数仓相关的组件,Meta、Proxy、Optimizer、BuildService,Ingestor、ShuffleServer、Cache 、Accelerator 等服务全部线程池化,尽可能降低成本;
计算算子(Shuffle、Scan、Filter 等)进一步分离。算子分离后,一些算子采取特别的硬件处理。如 Shuffle,在 BSP 场景下需要在本地有磁盘存储 Shuffle 数据,磁盘大小也很难确定大小。针对 Shuffle 会有类似 ShuffleService 的服务出现,以解决本地磁盘,也可以降低小文件及网络链接的开销。针对 Scan 算子,计算引擎会尽量把 Scan 算子推送到 Cache 端或者远程的存储之上,降低实际计算的数据量。针对 Like 等函数,可以引入 FPGA 等特殊的硬件,提升计算的效率。
读写会分离以适配读写不同的负载。一般会把写做单独的服务,来承接大吞吐量写或者实时的服务,再通过 Build 服务把实时数据与存量的数据合并,典型的如 HBase LSM 架构。查询的时候,可以仅仅查离线数据或者把离线数据与实时数据 merge 后再处理。在此架构下,往往查询与实时写之间有一定的数据延迟,数据分析的场景下,延迟只要是可预期可控的,是可以接受的。在此 ALT 的架构下,可以带来极大的扩展性,如 Rockset,把 Write、Merge、Query 分离。
引入分布式或者单机 Cache 解决带宽瓶颈问题。存储跟计算一般在两个部署单元,之间的带宽有限,其解决方案会引入 2 层 Cache 解决带宽问题,提升吞吐量,如 LocalcacheGlobalcache。比如 Snowflake 在每个节点会引起 localcache 本地缓存一部分数据,在计算与存储之间引入 Globalcache 提升在多个节点共享数据或者多个 SQL 查询时对远端存储的带宽压力。
离在资源混部与超卖提升资源的售卖率,秒级启停降低调度的开销。云原生的一大竞争力就是按需计费,且能秒级别启动,在客户体量需求下对客资源几乎无限。这就需要平台本身维护一个池子来满足临时的资源需求,会拉低平台资源的售卖率。虽高的定价可以拉升毛利率,但是会提高客户的成本,降低产品的竞争力。此时,需要在资源管理 及 混部超卖上做出竞争力,比如 Google BigQuery 是使用 Blog 作为资源调度,在资源超卖上有大量的实践,可以提升 CPU 利用率到 50~70%,资管管理模块可以根据客户资源的情况提前购买资源或者释放资源,进一步提升资源的售卖率。
引入安全容器、安全的网络架构、数据链路加密及硬件以解决安全的多租户问题。首选,在多用户多租场景下,一般客户会跑 UDF,这就意味着客户可以自定义 Code 攻击平台服务。通过虚拟机的隔离机制太重,通过 RunC 隔离又不能保障安全,这就需要类似 Kata 的安全容器,支持快速启动又兼顾安全;其次,多组场景下,计算需要访问全局的 Meta,访问调度接口 (如 K8S APIServer),这就需要平台提供 Token 认证机制;再次,在多租户下,数据天然是放在一起的,尤其是明文存在对象存储之上,即使在存储时是加密的,但是在计算过程中是解密的,在计算过程中也可以 core dump 看实际的数据;除了常见的 SSL/TLS 链路加密、TDE 落盘加密等措施外,也可以引入如 Intel SGX 构建 TEEs,在硬件中解密并计算,即使 core dump 也看不到数据。
引入新的硬件解决性能瓶颈,单位硬件的投入可以带来数量级性能的提升。引入如 FPGA、P-Memory、来解决 Shuffle、Scan 等池化后带来的链路损耗,进一步提升性能,提升性价比。新的芯片,如阿里云倚天、Intel QAT,指令可以下沉到硬件以进一步提升性能;如果存储不基于对象存储,则需要厂商自己提供机型,采取通用的机型性价比是比较低的,可以需要定制新的存储机型来满足存储需求,降低单 GB 的存储成本。
分析天然不跟具体云强绑定的,数仓多云部署在未来越来越常见。TP 数据库天然跟具体业务绑定在一起,因跨云访问的延迟较高。数据类业务往往是每个企业的增值业务,一般会存在多个 Region 汇总到一个中心处理,本身就是在跨地域。在企业内部业务部门、DBA 部门、数据部门是三个不同的部门,天然就是隔离性的。一般情况下 数据部门的数据,是把业务埋点及 DBA 数据归在一起,这就要求不一定在同一个云,数据部门可以寻求在其它云更加低成本且更加竞争力的分析解决方案。当解决不同云之间带宽瓶颈及性价比问题后,数仓的多云部署会在未来越来越常见。
智能化优化也会考虑到每个时刻的成本。假设资源模型是 Min~Max,理论是需要 2 个资源的 SLA,跟需要 10 个资源的 SLA 是不一样的,如果转嫁到成本,就是 100%SLA 保障 1s 内需要更多的资源定价就会相对贵一些。如果平台基于历史数据拉通,在不同时刻不同规模的资源定价就不一样,这还是相当复杂的,不利用客户理解。基于虚机类似的思考,把平台闲置的资源卖出,可以有一个类似 SpotInstance 的实例在售卖,定价跟标准的实例也不一样,SLA 也会更低一些。非云原生执行往往是在给定的资源情况下跑出来。云原生场景下,由于不同时段的资源的价格不一样,针对类似 SpotInstance 资源更加便宜,为了获得更好的财务成本,就不一定是尽快跑出来更加合适,可能延迟 1 小时,可以获得更低的财务成本。