简介: Hologres(原交互式剖析)是阿里云自研的一站式实时数仓,这个云原生零碎交融了实时服务和剖析大数据的场景,全面兼容PostgreSQL协定并与大数据生态无缝买通,能用同一套数据架构同时反对实时写入实时查问以及实时离线联邦剖析。它的呈现简化了业务的架构,为业务提供实时决策的能力,让大数据施展出更大的商业价值。在本文中,咱们将会介绍数据实时入仓所面临的挑战,以及Hologres为了应答这些挑战在技术原理上的翻新和演进,撑持实时数仓的高吞吐实时写入与更新,减速业务数据摸索。
image.png
作者 | 胡一博(上唐)
起源 | 阿里开发者公众号
导读:Hologres(原交互式剖析)是阿里云自研的一站式实时数仓,这个云原生零碎交融了实时服务和剖析大数据的场景,全面兼容PostgreSQL协定并与大数据生态无缝买通,能用同一套数据架构同时反对实时写入实时查问以及实时离线联邦剖析。它的呈现简化了业务的架构,为业务提供实时决策的能力,让大数据施展出更大的商业价值。在本文中,咱们将会介绍数据实时入仓所面临的挑战,以及Hologres为了应答这些挑战在技术原理上的翻新和演进,撑持实时数仓的高吞吐实时写入与更新,减速业务数据摸索。
作者:胡一博(上唐),阿里云实时数仓Hologres资深研发。
数据实时入仓所面临的挑战:高性能、可更新、大规模
大数据场景下,实时数据如何写入实时数仓永远是一个比拟大的话题,依据业务场景需要,常见的写入类型有:
1、Append only:传统日志类数据(日志、埋点等)中,记录(Record)和记录之间没有关联性,因而新来的记录只须要append到零碎中就好了。这是传统大数据系统最善于的一种类型。
2、Insert or Replace:依据设置的主键(Primary Key, PK)进行查看,如果零碎中不存在此PK,就把这行记录append进零碎; 如果存在,就把零碎中旧的记录用新的记录整行笼罩。典型的应用场景有:
a.上游数据库通过Binlog实时同步,这种写入就是Insert or Replace。
b.Flink的后果实时写出。Flink继续刷新后果,须要Insert or Replace的写指标表。
c.Lambda架构下的离线回刷。Lambda架构下离线链路T+1回刷实时后果表中昨天的记录。
3、Insert or Update:通常应用在多个利用更新同一行数据的不同字段,实现多个数据源的JOIN。如果这行记录存在,各个利用间接依据PK去update各自的字段;但如果这行记录不存在,那么第一个要写入这行记录的利用就须要INSERT这行记录。典型的应用场景:
a.画像类利用。这类利用在实时风控、实时广告投放等十分常见。上游多个Flink Job实时计算画像的不同维度,并实时写入到同一行记录的不同字段中。
b.实时离线数据整合。在须要同时用到实时和离线计算的场合,把同一个PK的实时和离线后果放在同一行记录的不同字段中,就能够不便的同时取到实时和离线的计算结果。
image.png
下文中,咱们把Insert or Replace和Insert or Update统称为Upsert。
而要放弃十分高效的写入性能,实时数仓技术都面临着十分大的挑战,典型的挑战有以下几个方面:
挑战一:Merge on Read还是Merge on Write?
Upsert模式下,新旧数据的合并产生在什么时候,如果心愿查问性能好,那么必定心愿合并产生在写入时(Merge on Write)。这样,在零碎中任何时刻任一主键都只有一条记录;而如果心愿写入性能好,那么就是写入不做合并,查问时再做合并(Merge on Read)。这对于查问是十分不敌对的,极大限度查问性能。
Merge on Read原理示例:
image.png
Merge on Write原理示例:
image.png
挑战二:是否反对主键(Primary Key)模型?
实时数仓在数据模型上是不是反对主键对于Upsert的实时写入是至关重要的。如果没有主键,在写入侧数据的更新就很容易进化成全表更新,性能十分差,在查问侧,Merge On Read也无从做起。
挑战三:是否保障写入的Exactly Once?
如果上游因为failover等因素导致写入反复执行,能不能保证系统中只有一条记录(Merge on Write)或者查问时等效只有一条数据(Merge on Read)且是最新的数据?大数据系统简单,上游零碎failover是常态,不能因为上游failover,就导致实时数仓数据反复。
问题四:数据是否写入即可见?
数据写入的时效性也是实时数仓的重要能力之一。对于BI类等提早不敏感的业务查问,如果写入时延几秒甚至几分钟可能是能够承受的。而对于很多生产零碎,如实时风控、实时大屏等场景,要求数据写入即可见。如果写入呈现提早,就会查问不到最新的数据,重大影响线上业务决策。
挑战五:如何反对超大的数据量和超高的RPS实时写入(每秒记录数,Record Per Second)?
如果数据量小,写入RPS要求低,一个传统的数据库就能很好的解决这个问题。然而在大数据场景下,当RPS达到几十万几百万时,如何更好反对数据的实时写入?同时,如果指标表中曾经有海量数量(十亿、百亿甚至更多)时,Upsert要求拜访和勘误已有数据,这时是否还能反对高性能的Upsert?
Hologres的实时写入模型与性能
Hologres是阿里自研的一站式大数据实时数仓,在设计之初就对实时写入场景进行了充沛的思考,次要有以下几个方面:
1、反对主键,能够高效利用主键更新、删除数据。
2、反对Upsert:残缺反对高性能的Append Only、Insert or Replace、Insert or Update 3种能力,可依据业务场景抉择写入模式。
3、对于列存表,主动应用Merge on Write计划。对于行存表,主动应用Merge on Read计划,起因如下:
a.对于列存表,次要是做简单的OLAP剖析,因而查问性能最重要。
b.对于行存表来说,查问次要是点查,此时Merge on Read单行的开销足够小,因而重点思考写入性能。在阿里很多点查场景,写入要求十分高的RPS。
4、反对Exactly Once。通过单行SQL事务和主键PK主动去重来实现。无论是批量数据写入(一次更新几亿条记录),还是逐条记录实时写入,Hologres都是保障单条SQL的原子性(ACID)。而对于上游Flink等failover造成的SQL重发,Hologres通过指标表的主键,实现主动笼罩或者疏忽(对于Upsert是主动笼罩;对于append,是主动疏忽Insert or Ignore)。因而,指标表是幂等的。
5、写入即可见。Hologres没有相似ElasticSearch的build过程,也没有相似ClickHouse或者Greenplum的攒批过程,数据通过SQL写入时,SQL返回即示意写入实现,数据即可查问。因而通过Flink等实时写入(背地也是SQL写入)能满足写入即可见,无提早。
这5个设计选取也是传统数据库的抉择。教训证实,这对于用户来说是最天然、最敌对的应用形式。Hologres的翻新在于把这个计划胜利的利用于大数据畛域(超高RPS写入和超大存储量)。
下图为Hologres 128C实例下,10个并发实时写入20列的列存表的测试后果。其中竖轴示意每秒写入记录数,4个场景别离为:
case1:写入无主键表;
case2:写入有主键表(Insert or Replace),并且每次INSERT的主键和表已有数据都不抵触;
case3:写入有主键表(Insert or Replace),并且每次INSERT的主键和表已有数据均抵触,表中数据量为2亿。
case4:写入有主键表(Insert or Replace),并且每次INSERT的主键和表已有数据均抵触,表中数据量为20亿。
image.png
后果解读:
比照case1和case2,能够看到Hologres判断主键是否存在性能损失较小;
比照case2,case3,case4,能够看到主键抵触时,hologres定位数据所在文件并标记DELETE根本不随数据规模上涨而上涨,能够应答海量数据下的高速Upsert。
与常见产品比照
image.png
Merge on Write模式下 实时写入与更新的常见原理
一个典型的Upsert(Insert or Replace)场景如下,一张用户表,通过INSERT INTO ON CONFLICT执行插入新用户/更新老用户操作:
CREATE TABLE users (
id int not null,name text not null,age int,primary key(id)
);
INSERT INTO users VALUES (?,?,?)
ON CONFLICT(id) DO UPDATE
SET name = EXCLUDED.name, sex = EXCLUDED.sex, age = EXCLUDED.age;
性能最高的实现形式是写入时APPEND ONLY一直写入新文件,在查问时进行数据逻辑合并(Merge on Read)。但这种对查问的性能打击是致命的,每次查问要多个版本的数据join过能力获取到一行最新的值。
实时数仓在写时合并(Merge on Write)计划下,Upsert的实现个别分为三步:
定位旧数据所在文件。
解决旧数据
写入新数据
要实现高RPS的实时Upsert,实质就是要把这3个步骤都做快。
1、定位旧数据所在文件
疾速定位旧数据文件,有如下几种做法:
1)bloom过滤器
bloom过滤器原理上是为每个key生成若干个hash值,通过hash碰撞来判断是否存在雷同的key。为每个文件生成一个bloom过滤器,能够明确排除不存在该key的文件。Bloom过滤器能够以很高的精度(99%甚至更高)确定一个Key不在一个文件中。
2)范畴过滤器
范畴过滤器就是记录文件内列的最大最小值,是一个代价十分小的过滤形式,当key根本处于一个递增态势是能够失去一个十分好的过滤成果。
3)内部索引
Hudi反对HBase索引,在HBase中保留PK->file_id的映射。HBase LSM-tree的存储构造对于key-value的查问十分高效,Hudi通过这种形式也不再须要去猜想哪些文件可能蕴含了这个PK。然而这里有两个问题:
HBase状态和Hudi表状态的一致性,因为HBase和Hudi是独立的两套零碎,一方如果产生故障可能导致索引生效。
性能下限是HBase的PK点查性能。要获得更好的写入性能是艰难的。
2、解决旧数据+写入新数据
常见的是两种解决办法:
1)刷新数据文件
定位到数据所在文件后,将文件和新数据合并后生成一个新的数据文件笼罩旧文件。(Copy on Write)。Iceberg反对这种模式。这会导致十分重大的写放大。
2)引入delta文件
定位到数据所在文件后:
在数据文件对应的delta文件中标记该行旧数据为删除状态。
在delta中追加新数据的信息。
这种形式没有写放大,然而在查问时须要将数据文件和对应的delta文件做join操作。
Hologres 基于Memtable的写入原理
Hologres的实时写入与更新根本遵循Merge on Write的原理。对于实时数仓场景下的record级别的更新/插入,Hologres采纳强主键的形式来让单行更新/插入足够轻量化,采纳memtable + wal log的形式,反对高频次的写入操作。
1、文件模型
Hologres每张列存表底层会保留三种文件:
第一种是主键索引文件,采纳行存构造存储,提供高速的key-value服务,索引文件的key为表的主键,value为unique_id和聚簇索引。unique_id每次Upsert主动生成,枯燥递增。主键索引文件实现高效的主键抵触断定并辅助数据文件定位;
第二种是数据文件,采纳列存构造存储,文件内依照聚簇索引+unique_id生成稠密索引,并对unique_id生成范畴过滤器;
第三种是delete bitmap文件,每个file id对应一个bitmap,bitmap中第N位为1示意file id中的第N行标记为删除。delete bitmap在列存模型下,相当于是表的一列数据。Update时只刷新bitmap信息既保留了Merge on Write对查问性能简直零毁坏的长处,又极大升高了IO的开销。
三类文件都是先写入memtable,memtable达到特定大小后转为不可变的memtable对象,并生成新的memtable供后续写入应用。不可变的memtable对象由异步的flush线程将其长久化为磁盘上的文件。
2、Upsert流程
通过这个流程图能够看到:
如果主键没有发生冲突,那么一次Upsert的的开销= 一次索引查问 + 两次内存写入操作;
如果主键产生了抵触,那么一次Upsert的开销=一次索引查问 + 一次文件及行号定位 +三次内存写入操作。
image.png
3、Upsert示例
上面通过示例来展现一次Upsert的过程。假如pk为id,cluserting key为name,数据列为age。(deleted信息物理上存储于delete bitmap中,但逻辑上等同与表的一列,下文将合并在数据文件中一起形容)
CREATE TABLE users (
id text not null,name text not null,age int,primary key(id)
);
表初始数据如下:
image.png
image.png
此时执行如下SQL:
INSERT INTO users VALUES ('u1','新李四',12)
ON CONFLICT(id) DO UPDATE
SET name = EXCLUDED.name
, age = EXCLUDED.age;
更新过程如下:
image.png
更新实现后表数据如下:
image.png
Hologres写入全链路优化,雕刻细节
Hologres在接口上齐全兼容PostgreSQL(包含语法、语义、协定等),所以能够间接应用PostgreSQL的JDBC Driver连贯Hologres进行数据读写。除了写入原理上的创新性外,Hologres也针对写入进行了全链路的优化,以达到更高性能的吞吐。
1、Fixed Plan:升高、防止SQL解析与优化器的开销
Query Optimizer进行shortcut
对于合乎pattern的Upsert sql,Hologres的Query Optimizer进行了相应的short cut,Upsert Query并不会进入Opimizer的残缺流程。Query进入FrontEnd后它会交由Fixed Planner进行解决,并由其生成对于的Fixed Plan(Upsert的物理Plan),Fixed Planner十分轻,无需通过任何的等价变换、逻辑优化、物理优化等步骤,仅仅是基于AST树进行了一些简略的剖析并构建出对应的Fixed Plan,从而尽量躲避掉优化器的开销。
Prepared Statement
只管Query Optimizer对Upsert Query进行了short cut,然而Query进入到FrontEnd后的解析开销仍然存在、Query Optimizer的开销也没有完全避免。
Hologres兼容Postgres,Postgres的前、后端通信协议有extended协定与simple协定两种:
1) simple协定:是一次性交互的协定,Client每次会间接发送待执行的SQL给Server,Server收到SQL后间接进行解析、执行,并将后果返回给Client。simple协定里Server无可避免的至多须要对收到的SQL进行解析能力了解其语义。
2)extended协定:Client与Server的交互分多阶段实现,整体大抵能够分成两大阶段。
第一阶段:Client在Server端定义了一个带名字的Statement,并且生成了该Statement所对应的generic plan(不与特定的参数绑定的通用plan)。
image.png
第二阶段:用户通过发送具体的参数来执行第一阶段中定义的Statement。第二阶段能够反复执行屡次,每次通过带上第一阶段中所定义的Statement名字,以及执行所须要的参数,应用第一阶段生成的generic plan进行执行。因为第二阶段能够通过Statement名字和附带的参数来重复执行第一个阶段所筹备好的generic plan,因而第二个段在Frontend的开销简直等同于0。
为此Hologres基于Postgres的extended协定,反对了Prepared Statement,做到了Upsert Query在Frontend上的开销靠近于0。
2、高性能的外部通信
Reactor模型、全程无锁的异步操作
外部通信原理相似reactor模型,每个指标shard对应一个eventloop,以“死循环”的形式解决该shard上的申请。因为HOS(Hologres Operation System)对调度执行单元的形象,即便是shard很多的状况下,这种工作形式的根底耗费也足够低。
高效的数据交换协定binary row
通过自定义一套外部的数据通信协定binary row来缩小整个交互链路上的内存的调配与拷贝。
反压与凑批
BHClient能够感知后端的压力,进行自适应的反压与凑批,在不影响原有Latency的状况下晋升零碎吞吐。
3、稳固牢靠的后端实现
基于C++纯异步的开发
Hologres采纳C++进行开发,相较于Java,native语言使得咱们可能谋求到更极致的性能。同时基于HOS提供的异步接口进行纯异步开发,HOS通过形象ExecutionContext来自我治理CPU的调度执行,可能最大化的利用硬件资源、达到吞吐最大化。
IO优化与丰盛的Cache机制
Hologres实现了十分丰盛的Cache机制row cache、block cache、iterator cache、meta cache等,来减速热数据的查找、缩小IO拜访、防止新内存调配。当无可避免的须要产生IO时,Hologres会对并发IO进行合并、通过wait/notice机制确保只拜访一次IO,缩小IO处理量。通过生成文件级别的词典及压缩,缩小文件物理存储老本及IO拜访。
总结
Hologres是阿里巴巴自主研发的一站式实时数仓引擎,反对海量数据实时写入、实时更新、实时剖析,反对规范SQL(兼容PostgreSQL协定),反对PB级数据多维分析(OLAP)与即席剖析(Ad Hoc),反对高并发低提早的在线数据服务(Serving),并在阿里巴巴双11等大促外围场景上,Hologres写入峰值达11亿条+/秒,通过大规模数据生产验证。
常见的数据仓库产品,大多都会就义读性能或者就义写性能,并且它们往往文件作为拜访介质,这人造束缚了数据更新的频率。Hologres 通过memtable使数据能够高频更新,通过delete map让读操作防止了join操作放弃了良好的读性能,通过主键模型解决了写操作时的效率问题,做到了读写性能的兼顾。同时Hologres同Flink、Spark等计算框架原生集成,通过内置Connector,反对高通量数据实时写入与更新,反对源表、后果表、维度表多种场景,反对多流合并等简单操作。
从阿里团体诞生到云上商业化,随着业务的倒退和技术的演进,Hologres也在继续一直优化核心技术竞争力,为了让大家更加理解Hologres,咱们打算继续推出Hologres底层技术原理揭秘系列,从高性能存储引擎到高效率查问引擎,高吞吐写入到高QPS查问等,全方位解读Hologres,请大家继续关注!
往期精彩内容:
2020年VLDB的论文《Alibaba Hologres: A cloud-Native Service for Hybrid Serving/Analytical Processing》:http://www.vldb.org/pvldb/vol...
Hologres揭秘:首次公开!阿里巴巴云原生实时数仓核心技术揭秘:https://developer.aliyun.com/...
Hologres揭秘:首次揭秘云原生Hologres存储引擎:https://developer.aliyun.com/...
Hologres揭秘:Hologres高效率分布式查问引擎:https://developer.aliyun.com/...
Hologres揭秘:高性能原生减速MaxCompute外围原理:https://developer.aliyun.com/...
Hologres揭秘:优化COPY,批量导入性能晋升5倍+:https://developer.aliyun.com/...
Hologres揭秘:如何反对超高QPS在线服务(点查)场景:https://developer.aliyun.com/...
Hologres揭秘:从双11看实时数仓Hologres高可用设计与实际:https://developer.aliyun.com/...
Hadoop 分布式资源管理框架 YARN
点击这里,查看详情。
原文链接:http://click.aliyun.com/m/100...
本文为阿里云原创内容,未经容许不得转载。