本文是向大家介绍Hologres是一款实时HSAP产品,隶属阿里自研大数据品牌MaxCompute,兼容 PostgreSQL 生态、支持MaxCompute数据直接查询,支持实时写入实时查询,实时离线联邦分析,低成本、高时效、快速构筑企业实时数据仓库(Real-Time Data Warehouse)。
首先介绍下大数据相关实时业务场景,一般有实时大屏、实时BI报表、用户画像和监控预警等。
针对上述大数据业务场景,业界在很早之前就开始通过数据仓库的建设来满足这些场景的需求。
传统上,我们是如何做数据加工以及数据服务的呢?最常见的方式就是下图所示,数据链路也左向右发展,有加工平台负责加工,结果数据导出到服务平台对外提供服务。离线数据仓库数据流程如下:
这个架构在最开始应用的时候还是比较顺利的,大部分公司里面 90%的场景下是这个架构。但是随着业务越来越多,越来越复杂,每天都有新的报表,每天都有新的业务场景,就会发现每一个业务调整的时候,都要从源头一步步调整,包括表结构,加工脚本,历史数据重刷等等,最后造成整个数据加工的链路会变得数据冗余、成本高、开发周期长、甚至数据不一致。痛点整理如下:
为了满足大数据实时化需求,从传统数仓上演进出Lambda架构,其思路,在传统离线数仓的基础上再加上一个处理实时数据的层,然后将离线数仓和实时链路产生的数据在Serving层进行Merge,以此实现对离线产生的数据和实时产生的数据进行查询。
典型架构如下:
Lambda架构的问题:
总结:传统大数据开发链路,数据冗余、成本高、开发周期长。
参考:《基于Hologres和Flink的实时数据分析方案》
基于上述背景,阿里提出了HSAP(Hybrid Serving and Analytical Processing)理念,目标做到服务分析一体化,它既能支持很高QPS场景的查询写入,又能将复杂的分析场景在一套体系里面完成。
1、统一存储:同时存储实时数据和离线数据
2、统一接口:在统一个接口下(比如SQL),支持高QPS的查询、支持复杂的分析以及联邦查询和分析
3、统一数据服务:系统能够直接对接前端应用,例如报表和在线服务等,不需要再额外的导入导出就能即席分析
基于HSAP的设计理念,诞生了Hologres。
Hologres:Better OLAP+ Better Serving +Cost Reduced
Hologres是一款实时HSAP产品,隶属阿里自研大数据品牌MaxCompute,兼容 PostgreSQL 生态、支持MaxCompute数据直接查询,支持实时写入实时查询,实时离线联邦分析,低成本、高时效、快速构筑企业实时数据仓库(Real-Time Data Warehouse)。具备如下优势:
说明 |
|
分析服务一体化 |
|
以实时为中心设计 |
|
计算存储分离 |
|
丰富生态 |
|
根据对传统数仓的痛点,阿里对精细化运营平台提出了如下诉求:架构简化、成本优化、数据统一、学习门槛低、适应业务敏捷、自助式分析趋势,如下:
即将原有复杂的架构简化为以HSAP核心思想的数仓架构。
到目前为止,相信大家已经了解到 Hologres 是一款兼容 PostgreSQL 协议的实时交互式 分析产品。在生态的兼容性上,Hologres 有着非常庞大的生态家族。
Hologres兼容PostgreSQL生态,是新一代的阿里云实时数仓产品,与大数据生态无缝连接,支持实时与离线数据,对接第三方BI工具,实现可视化分析业务。
Flink流批一体计算,Hologres实时离线统一存储、分析服务统一数据服务
MaxCompute+Hologres+Flink,实时离线联合分析,冷热温三大维度数据全洞察
MaxCompute+Hologres,外表:成本优化、吞吐量大;内表:索引优化、低延迟查询
实时推荐依赖特征查询、实时指标计算、向量检索召回,提高广告留存率,Flink+PAl+Hologres with Proxima
Hologres架构简单,是存储计算分离的架构,数据全部存在一个分布式文件系统里面,在阿里内部指的是盘古分布式文件系统;服务节点叫做 Backend,也叫Worker Node,真正去接收数据,存储和查询,并且能够支持数据的计算;Frontend 接收路由分发过来的SQL,然后生成真正的物理执行计划,发布到 Backend 做分布式的执行;在接入端由LBS 来做相应的负载均衡任务。
下图中黄色部分均部署在容器中,整个分布式系统可以做到高度容错。同时,因为兼容 PostgreSQL 生态,所以一些开源或者商业化的 BI 工具可以直接跟Hologres 进行对接。
详细组件图如下:
组件介绍:
组件 |
用途 |
说明 |
|
计算层 |
接入节点(Frontend,FE) |
用于SQL的认证、解析、优化 |
兼容Postgres 11(语法、连接工具、BI) |
计算HoloWorker |
分为执行引擎、存储引擎、调度等组件,主要负责用户任务的计算、调度。 |
Hologres揭秘:深度解析高效率分布式查询引擎 |
|
Meta Service |
主要用于管理元数据Meta信息 |
||
Holo Master |
负责每个组件的可用性,故障时快速重新拉起组件 |
技术揭秘:从双11看实时数仓Hologres高可用设计与实践 |
|
存储层 |
Pangu File System |
数据存储 |
1、与MaxCompute在存储层打通,可快速访问 2、支持直接访问OSS、DLF数据 |
在传统的分布式系统中,常用的存储计算架构有如下三种:
Hologres采用的是第三种存储计算分离架构,Hologres的存储使用的是阿里自研的Pangu分布式文件系统(类似HDFS)。
Hologres 定位是能够做离线数据和实时数据的存储。
优点:Hologres解决了数据的一致性问题,也不需要去区分离线表和实时表,降低了复杂度,也大大降低了使用者的学习成本。
每个分片(Table Group Shard, 简称 shard)构成了一个存储管理和恢复的单元 (Recovery Unit)。上图显示了一个分片的基本架构。
下面是存储引擎几个重要的的组件:
1、WAL和WAL Manager
WAL Manager是来管理日志文件的。存储引擎用预写式日志(WAL) 来保证数据的原子性 和持久性。
2、文件存储
每个tablet会把数据存在一组文件中,这些文件是存在DFS里 (阿里巴巴盘古或者 Apache HDFS )。
这两种列存格式都针对文件扫描的场景做了优化。
3、Block Cache (Read Cache)
为了避免每次读数据都用IO到文件中取,存储引擎通过BlockCache把常用和最近用的数据放在内存中,减少不必要的IO,加快读的性能。
顾名思义,LRU算法是首先淘汰最 长时间未被使用的block,而LFU是先淘汰一定时间内被访问次数最少的block。
第一节提到 Hologres 既能支持分析,又能支持服务。这是因为 Hologres 底层会有两种不同的存储模式:行存和列存,这也就意味着我们既能支持查询的量大,又能支持查的快。
下图是 Hologres 行存和列存两种模式下的对比:
Hologres 底层支持行存储和列存储两种文件格式,新版本也支持了行列共存格式,对于两者的处理也有略微不同,具体如下图所示。
数据写入过程:
而对于行存储和列存储的区别就在Flash 到文件的这个过程中,这个过程会将行存表 flush 成行存储的文件,列存表会 Flash 成列存文件。在 Flash 的过程中会产生很多小文件,后台会将这些小文件合并成一个大文件(Compaction)。
Hologres支持两种类型的写入:单分片写入和分布式批量写入。
两种类型的写入都是原子的(Atomic Write),即写入或回滚。单分片写入一次更新一个shard,但是需要支持极高的写入频率。另一方面,分布式批写用于将大量数据作为单个事务写到多个shard中的场景, 并且通常以低得多的频率执行。
单分片写入 :
如上图所示,WAL管理器在接收到单分片写请求后,
(1)为写请求分配一条Log Sequence Number (LSN),这个LSN是由时间戳和递增的序号组成,并且
(2)创建一条新的日志,并在文件系统中的持久化这条日志。这条日志包含了恢复写操作所需的信息。在完全保留这条日志后,才向tablet提交写入。之后,
(3)我们会在相应tablet的内存表 (MemTable) 中执行这个写操作,并使其对新的读请求可见。值得注意的是,不同tablet上 的更新可以并行化。当一个MemTable满了以后,
(4)将其刷新到文件系统中,并初始化一 个新的MemTable。
(5)最后,将多个分片文件在后台异步合并(compaction)。在合并或MemTable刷新结束时,管理tablet的元数据文件将相应更新。
分布式批量写入
接收到写入请求的前台节点会将写请求分发到所有相关的分片。这些分片通过两阶段提 交机制(Two Phase Commit) 来保证分布式批量写入的写入原子性。
多版本读
Hologres支持在tablet中多版本读取数据。读请求的一致性是read-your-writes,即客户端始终能看到自己最新提交的写操作。每个读取请求都包含一个读取时间戳,用于构造读的snapshot LSN。如果有一行数据的LSN大于snapshot LSN的记录, 这行数据就会被过滤掉, 因为它是在读的snapshot产生后才被插入到这个tablet的。
1. 存储计算分离
存储引擎采用存储计算分离的架构,所有的数据文件存在一个分布式文件系统(DFS, 例如阿里巴巴盘古或者Apache HDFS)的里面。当查询负载变大需要更多的计算资源的时 候可以单独扩展计算资源; 当数据量快速增长的时候可以快速单独扩展存储资源。计算节点 和存储节点可以独立扩展的架构保证了不需要等待数据的拷贝或者移动就能快速扩展资源; 而且,可以利用DFS存多副本的机制保证数据的高可用性。 这种架构不但极大地简化了运 维,而且为系统的稳定性提供了很大的保障。
2. 异步执行流程
存储引擎采用了基于事件触发, 非阻塞的纯异步执行架构, 这样能够充分发挥现代CPU多 core的处理能力,提高了吞吐量, 支持高并发的写入和查询。这种架构得益于HOS (HoloOS) 框架,HOS在提供高效的异步执行和并发能力的同时,还能自动地做CPU的负载 均衡提升系统的利用率。
3. 统一的存储
在HSAP场景下,有两类查询模式,一类是简单的点查询(数据服务Serving类场景), 另一类是扫描大量数据的复杂查询(分析Analytical类场景)。 当然,也有很多查询是介于两者之间的。这两种查询模式对数据存储提出了不同的要求。行存能够比较高效地支持点查询,而列存在支持大量扫描的查询上有明显的优势。
为了能够支持各种查询模式,统一的实时存储是非常重要的。存储引擎支持行存和列存 的存储格式。根据用户的需求,一个tablet可以是行存的存储格式 (适用于Serving的场景); 也可以是列存的存储格式(适用于Analytical的场景)。 比如,在一个典型HSAP的 场景,很多用户会把数据存在列存的存储格式下,便于大规模扫描做分析;与此同时,数据的索引存在行存的存储格式下,便于点查。并通过定义primary key constraint (我们是用 行存来实现的)用来防止数据重复。不管底层用的是行存还是列存,读写的接口是一样的, 用户没有感知,只在建表的时候指定即可。
4. 读写隔离
存储引擎采用了snapshot read的语意,读数据时采用读开始时的数据状态,不需要数据锁,读操作不会被写操作block住; 当有新的写操作进来的时候,因为写操作是appendonly,所有写操作也不会被读操作block住。这样可以很好的支持HSAP的高并发混合工作负 载场景。
5. 丰富的索引
存储引擎提供了多种索引类型,用于提升查询的效率。一个表可以支持clustered index 和 non-clustered index这两类索引。一个表只能有一个clustered index, 它包含表里所有的列。一个表可以有多个non-clustered indices。在non-clustered indexes里,除了排序用的non-clustered index key外,还有用来找到全行数据的Row Identifier ( RID)。 如果 clustered index存在, 而且是独特的,clustered index key就是RID; 否则存储引擎会产生一个独特的RID。 为了提高查询的效率,在non-clustered index中还可以有其他的列, 这样在某些查询时,扫一个索引就可以拿到所有的列的值了 (covering index)。
在数据文件内部,存储引擎支持了字典和位图索引。字典可以用来提高处理字符串的效率和提高数据的压缩比,位图索引可以帮助高效地过滤掉不需要的记录。
Hologres的执行引擎(主要以HQE为主)是自研的执行引擎,具备分布式执行、全异步执行、向量化和列处理、自适应增量处理等优势。
Query执行过程
当客户端发起一个SQL后,Frontend(FE)节点对SQL进行解析和认证,并分发至执行引擎(Query Engine)的不同执行模块。
1、如果是点查/点写的场景,会跳过优化器(Query Optimizer,QO),直接分发至后端获取数据,减少数据传送链路,从而实现更优的性能。整个执行链路也叫Fixed Plan,点查(与HBase的KV查询)、点写场景会直接走Fixed Plan。
2、如果是OLAP查询和写入场景:首先会由优化器(Query Optimizer,QO)对SQL进行解析,生成执行计划,在执行计划中会预估出算子执行Cost、统计信息、空间裁剪等。QO会通过生成的执行计划,决定使用HQE、PQE、SQE或者Hive QE对算子进行真正的计算。
3、执行引擎决定正确的执行计划,然后会通过存储引擎(Storage Engine,SE)进行数据获取,最后对每个Shard上的数据进行合并,返回至客户端。
1、分片与表组
Hologres存储引擎的基本抽象是分布式的表,为了让系统可扩展,我们需要把表切分为分片(shard)。
为了更高效地支持Join以及多表更新等场景,用户可能需要把几个相关的表存放在一起,为此Hologres引入了表组(Table Group)的概念。
分片策略完全一样的一组表就构成了一个表组,同一个表组的所有表有同样数量的分片。用户可以通过 “shard_count”来指定表的分片数,通过“distribution_key”来指定分片列。目前我们只支持Hash的分片方式。
2、表的数据存储格式
表的数据存储格式分为两类,一类是行存表,一类是列存表,格式可以通过 “orientation”来指定。
3、记录存储顺序
每张表里的记录都有一定的存储顺序,用户可以通过“clustering_key”来指定。如果没有指定排序列,存储引擎会按照插入的顺序自动排序。选择合适的排序列能够大大优化一些查询的性能。
4、索引
表还可以支持多种索引,如字典索引和位图索引。通过 “dictionary_encoding_columns”和“bitmap_columns”来指定需要索引的列。
在Hologres V2.0版本推出了全新的弹性高可用实例形态,将计算资源分解为不同的计算组(Virtual Warehouse),更好的服务于高可用部署。具备优点如下:
使用限制:
计算组实例的核心组件主要有分为三个层面:
举例:一个Hologres弹性高可用实例如下:
通过如下架构可以做到:
1、读写分离:使用init_warehouse写入计算组用于写入数据;使用read_warehouse_1查询计算组用于服务查询
2、计算组流量切换:若发现计算组read_warehouse_1有故障,可以将ram_test的流量切换到init_warehouse计算组
Hologres提供了2种高可用方式,即使在单实例的情况下,也能保障服务可靠:
Hologres计算节点均为容器调度(即下图中的Worker Node),资源管理器(Resource Manager)负责周期性健康检查。
当出现1分钟容器响应超时(可能是内存溢出、硬件故障、软件Bug等原因导致),Resource Manager会自动拉起新的计算节点,并迁移Shard职责到新的节点上(例如Worker Node3响应超时,Resource Manager拉起Worker Node4取代Worker Node3),实现系统状态的快速恢复。
该方案为当前每个实例内部默认启用,当系统发生故障时,无需手工运维介入,系统可以自动恢复。在恢复期间,如果查询算子需要访问恢复中的节点,则查询会立即失败。
缺陷:在单实例方案中,采用的是故障实时监测、节点替换的方案,在节点恢复时存在一定的服务不可用周期
对于关键业务场景,需要更高级别的高可用方案,支持故障隔离、负载隔离,可以采用共享存储的多实例方案。该方案主实例具备完整能力,数据可读可写,权限、系统参数可配置,而只读从实例处于只读状态,所有的变更都通过主实例完成,如下图所示。
主从实例之间计算资源不共享,负载隔离,故障隔离。所有实例共享同一份数据和访问控制,仅有一份存储费用。
建议将主实例作为数据写入和数据加工实例,只读从实例作为数据分析实例,保障读写分离。
具体参考:单实例Shard级多副本
我们可以通过设置Table Group副本数的方式来提高某个Table Group查询并发能力和可用性。
说明:
使用说明:
1、数据是按Shard分布的,不同Shard管理不同的数据,不同Shard之间的数据没有重复,所有的Shard在一起是一份完整的数据。
2、默认情况下每一个Shard只有一个副本,即replica count = 1,其对应的属性为leader。您可以通过调整replica count的值,使相同的数据有多个副本,其他副本的属性为follower。
3、写请求由Leader Shard负责,读请求会均衡由多个Follower Shard(也包含leader Shard)共同服务。当使用Follower Shard查询时,数据可能会出现10~20ms级别延迟。
参考资料:产品概述_实时数仓Hologres-阿里云帮助中心