简介: 本文将会首次对外公开介绍Hologres的存储引擎,深度分析其实现原理和核心技术劣势。
概要:刚刚完结的2020天猫双11中,MaxCompute交互式剖析(Hologres)+实时计算Flink搭建的云原生实时数仓首次在外围数据场景落地,为大数据平台创下一项新纪录。借此之际,咱们将陆续推出云原生实时数仓双11实战系列内容。本文将会首次对外公开介绍Hologres的存储引擎,深度分析其实现原理和核心技术劣势。
一、背景介绍
MaxCompute 交互式剖析(Hologres)是阿里云自研开发的HSAP(Hybrid Serving/Analytical Processing)服务/剖析一体化零碎 ,交融了实时服务和剖析大数据的场景,全面兼容PostgreSQL协定并与大数据生态无缝买通。它的呈现简化了业务的架构,与此同时为业务提供实时做出决策的能力,让大数据施展出更大的商业价值。对于架构更具体的介绍,请看文末VLDB论文 。
跟传统的大数据和OLAP零碎相比,HSAP零碎面临上面的挑战:
- 高并发的混合工作负载:HSAP零碎须要面对远远超出传统的OLAP零碎的并发查问。在实践中,数据服务的并发远远超出OLAP的查问。比如说,咱们在事实的利用中见到数据服务须要解决高达每秒钟数千万个查问,这比OLAP查问的并发高出了5个数量级。同时,和OLAP查问相比,数据服务型查问对提早有着更加刻薄的要求。简单的混合查问负载对系统的提早和吞吐有着十分不同的取舍。如何在高效地利用零碎的资源同时解决好这些十分不一样的查问,并且保障每个查问的SLO是个微小的挑战。
- 高吞吐实时数据导入:在解决高并发的查问负载的同时,HSAP零碎还须要解决海量的实时数据导入。从传统的OLTP同步过去的数据只是这其中的一小部分,其余还有大量的数据来自日志等没有强事务语意的零碎。实时导入的数据量远远超过了传统的HTAP或者OLAP零碎。和传统的OLAP零碎的另外一个区别是对数据的实时性有着很高的要求,导入的数据须要在秒级甚至亚秒级可见,这样能力保障咱们服务和剖析后果的时效性。
- 弹性和可扩展性:数据导入和查问负载可能会有突发的顶峰,这对HSAP零碎提出了很高的弹性和可扩展性的要求。在事实的利用中,咱们留神到数据导入峰值能达到是均匀的2.5倍,查问的峰值可能达到均匀的3倍。数据导入和查问的峰值可能不肯定同时呈现,这也须要零碎有依据不同的峰值做迅速调整的能力。
基于上诉背景,咱们自研了一款存储引擎(Storage Engine),次要负责管理和解决数据, 包含创立,查问,更新,和删除(简称 CRUD)数据的办法。存储引擎的设计和实现提供了HSAP场景所须要的高吞吐,高并发,低提早,弹性化,可扩展性的能力。依据阿里团体业务和云上客户的需要,咱们不断创新和打磨,倒退到明天,能反对单表PB级存储,并完满撑持2020年天猫双11外围场景千亿个级别的点查问和千万个级别的实时简单查问 。
上面,咱们将会对Hologres底层的存储引擎做具体的介绍,并介绍存储引擎落地Hologres的具体实现原理和技术亮点。
二、数据模型
Hologres存储引擎的根本形象是分布式的表,为了让零碎可扩大,咱们须要把表切分为分片(Shard)。 为了更高效地反对JOIN以及多表更新等场景,用户可能须要把几个相干的表寄存在一起,为此Hologres引入了表组(Table Group)的概念。分片策略齐全一样的一组表就形成了一个表组,同一个表组的所有表有同样数量的分片。用户能够通过“shard_count"来指定表的分片数,通过“distribution_key"来指定分片列。目前咱们只反对Hash的分片形式。
表的数据存储格局分为两类,一类是行存表,一类是列存表,格局能够通过“orientation"来指定。
每张表里的记录都有肯定的存储程序,用户能够通过“clustering_key"来指定。如果没有指定排序列,存储引擎会依照插入的程序主动排序。抉择适合的排序列可能大大优化一些查问的性能。
表还能够反对多种索引,目前咱们反对了字典索引和位图索引。用户能够通过“dictionary_encoding_columns"和“bitmap_columns"来指定须要索引的列。
上面是一个示例:
这个例子建了LINEITEM 和 ORDERS两个表,因为LINEITEM表还指定了主键(PRIMARY KEY),存储引擎会主动建设索引来保障主键的惟一。用户通过指定“colocate_with“把这两个表放到了同一个表组。这个表组被分成24个分片(由shard_count指定)。 LINEITEM将依据L_ORDERKEY的数据值来分片,而ORDERS将依据O_ORDERKEY的数据值来分片。LINEITEM的L_SHIPINSTRUCT以及ORDERS的O_ORDERSTATUS字段将会创立字典。LINEITEM的L_ORDERKEY, L_LINENUMBER, L_SHIPINSTRUCT字段以及ORDERS的O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS字段将会建设位图索引。
三、存储引擎架构
1)总体架构
每个分片(Table Group Shard, 简称Shard)形成了一个存储管理和复原的单元 (Recovery Unit)。上图显示了一个分片的根本架构。一个分片由多个tablet组成,这些tablet会共享一个日志(Write-Ahead Log,WAL)。存储引擎用了Log-Structured Merge (LSM)的技术,所有的新数据都是以append-only的模式插入的。 数据先写到tablet所在的内存表 (MemTable),积攒到肯定规模后写入到文件中。当一个数据文件敞开后,外面的内容就不会变了。新的数据以及后续的更新都会写到新的文件。 与传统数据库的B+-tree数据结构相比,LSM缩小了随机IO,大幅的进步了写的性能。
当写操作一直进来,每个tablet里会积攒出很多文件。当一个tablet里小文件积攒到肯定数量时,存储引擎会在后盾把小文件合并起来 (Compaction),这样零碎就不须要同时关上很多文件,能缩小应用系统资源,更重要的是合并后, 文件缩小了,进步了读的性能。
在DML的性能上,存储引擎提供了单条或者批量的创立,查问,更新,和删除(CRUD操作)拜访办法的接口,查问引擎能够通过这些接口拜访存储的数据。
2)存储引擎组件
上面是存储引擎几个重要的的组件:
- WAL 和 WAL Manager
WAL Manager是来治理日志文件的。存储引擎用预写式日志(WAL) 来保证数据的原子性和持久性。当CUD操作产生时,存储引擎先写WAL,再写到对应tablet的MemTable中,等到MemTable积攒到肯定的规模或者到了肯定的工夫,就会把这个MemTable切换为不可更改的flushing MemTable, 并新开一个 MemTable接管新的写入申请。 而这个不可更改的flushing MemTable就能够刷磁盘,变成不可更改的文件; 当不可更改的文件生成后,数据就能够算长久化。 当零碎产生谬误解体后,零碎重启时会去WAL读日志,复原还没有长久化的数据。 只有当一个日志文件对应的数据都长久化后,WAL Manager才会把这个日志文件删除。
- 文件存储
每个tablet会把数据存在一组文件中,这些文件是存在DFS里 (阿里巴巴盘古或者Apache HDFS )。 行存文件的存储形式是Sorted String Table(SST) 格局。 列存文件反对两种存储格局: 一种是相似PAX的自研格局, 另外一种是改进版的Apache ORC格局 (在AliORC的根底上针对Hologres的场景做了很多优化)。 这两种列存格局都针对文件扫描的场景做了优化。
- Block Cache (Read Cache)
为了防止每次读数据都用IO到文件中取,存储引擎通过BlockCache把罕用和最近用的数据放在内存中,缩小不必要的IO,放慢读的性能。在同一个节点内,所有的Shard共享一个Block Cache。 Block Cache有两种淘汰策略: LRU (Least Recently Used,最近起码应用) 和 LFU (Least Frequently Used, 最近不罕用)。 顾名思义,LRU算法是首先淘汰最长工夫未被应用的Block,而LFU是先淘汰肯定工夫内被拜访次数起码的Block。
3)读写原理
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的。
四. Hologres存储引擎技术亮点
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住; 当有新的写操作进来的时候,因为写操作是append-only,所有写操作也不会被读操作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)。
在数据文件外部,存储引擎反对了字典和位图索引。字典能够用来进步解决字符串的效率和进步数据的压缩比,位图索引能够帮忙高效地过滤掉不须要的记录。
五. 结语
存储引擎的设计思路和研发方向是为了更好的反对HSAP的场景,能高效的反对高吞吐的实时写入和交互式查问,而且对离线的批量写入做了优化。在写入量和存储量每年都成倍的增长下,Hologres禁受住了严苛的考验,完满地度过了多个双11。 “Hologres顶住了5.96亿每秒的实时数据洪峰,单表存储高达2.5PB。基于万亿级数据对外提供多维分析和服务,99.99%的查问能够在80ms以内返回后果”。这组数据充沛显示了存储引擎的技术能力, 同时也印证了咱们技术架构和实现的劣势。
当然,Hologres还是一个新产品,HSAP是个新理念, “明天的最好只是今天的开始”, 咱们还在一直地精益求精,凝听客户的反馈,今后会在稳定性,易用性,以及性能和性能上继续晋升。
原文链接
本文为阿里云原创内容,未经容许不得转载。