**王北南,**Alluxio软件工程师,也是PrestoDB的committer。参加Alluxio之前,北南博士是Twitter Presto团队的技术担任人,并为Twitter的数据平台构建了大规模分布式SQL系统。他在性能优化、分布式缓存和大数据方面有12年的作业经验。王北南博士结业于雪城大学计算机工程专业,专业方向是对分布式系统进行信号模型检测和运转验证。
**陈寿纬,**Alluxio软件工程师,在Alluxio主要担任数据湖方案结合、结构化数据与高可用性优化等相关作业。陈寿纬博士结业于罗格斯大学电子与计算机工程系,专业方向是大规模分布式系统的性能与稳定性优化。
查询Iceberg表
Create Table
或许很多人用Presto只用 Hive Connector,其实Iceberg connector跟Hive差不多,不论从完成,仍是从功用上都有互相的参照,尤其是在完成方面运用了非常多的Hive connector底层的代码。它创建table也是相同,咱们能够从一个 TPC-DS数据的 customer表里抽几列再创建一个table,你能够指定这个数据的格局,能够是Parquet也能够是ORC格局。也能够一起指定分区(partition),这儿用出生的月份这样会容易些,由于月份只要12个,也便是12个分区。咱们创建了这个表之后,跟Hive表相同,你能够select这个表,select* from Iceberg.test,test1是表名,你能够用一个美元符号$加上partitions,这样你能够把这个表的一切分区给列出来。每个分区都会有一个计算,比如说下面榜首行8月,能看到它有多少行有多少个文件,大小总共有多大,一起关于customer_sk这一列,能看到最小值多少最大值多少。后边的birth date便是日期,关于8月最小值是1,最大值是31,空值有若干。由于8月是大月,后边的9月是小月最大值是30,每一个partition都会有自己的计算,后边咱们会再讲, predicate pushdown会用到这个,能够让咱们跳过很多的分区,其实Hive也有这个功用,只不过或许有些数据在Hive metastore上,元数据这儿没有的话,用不上这个功用,但在Iceberg上它内嵌在table里了,就会比较好用一些。
Insert
前面提到Iceberg会有一些业务(transaction)支撑。咱们试着往这个表里参加一行, SK是1000,日期是40,我特意刺进了一个不或许存在的日期月份是13,这样等于说我新创建了一个partition。其实不论是不是新建partition都会发生一个新的快照(snapshot),在Presto里,经过select * from 表, 表的名字上面加一个美元$符号,然后再加一个snapshots,就能够列出这个 table一切的snapshots。咱们能够看到有两个snapshots,由于新建table时出一个,刺进一行之后又出一个,manifest list就有两个avro文件,第二个snapshot根据榜首个,第二个snapshot 的parent ID便是榜首个snapshot的parent ID,待会咱们会用snapshot ID来做time travel。
关于这样一个文件,咱们加了一个partition进去之后会怎么样,看一下这个目录,其实Iceberg的目录非常简略,咱们指定一个目录,它在这下面就创建一个test1,里面有两个文件夹,一个是data (数据),一个是metadata(元数据)。数据里面是按照月份来分区的,这儿面是 14个分区,由于12个月份,还有个空值,再加上咱们新加的月份13,等于现在总共14个分区,这个文件便是这么组织的,而每个目录下面便是parquet文件。
Query
那么咱们在query的时分会发生什么呢?
这个其实咱们都会——写个SQL,从这个select*from Test1的时分,指定一个条件,我这个月份是13,那就把我方才新刺进的那一条记载给调出来了。我后边会介绍一下怎么做时刻穿梭(Time travel),咱们能够看到在这个表名test1这有个@符,后边我能够加一个 snapshot ID,假如我用第二个(快照)snapshot,就能查到这个记载,假如我用榜首个snapshot就没有这个记载,为什么?由于榜首个query发生在刺进这条记载之前。这还挺有用的,由于有的时分就想查一下我这个表昨天是什么样的。但这也有问题,假如你频频刺进数据的话,就会发生很多的snapshot,avro里面就会有很多的数据。那咱们是不是要丢掉一些过期的快照?这也是个优化点,现在presto还没有,但以后我觉得咱们会把它做进去。
别的有些朋友会问,已然Iceberg connector有这个功用了,能不能用它来替代MySQL,做OLTP来处理一些在线的transaction数据? ——能够,可是不能像MySQL那么用,频频的刺进数据还会带来一些问题,需求做更深化的优化,直接这么用的话会发生很多的小文件和快照,但这些都有方法处理,咱们后边会把它渐渐迭代进去。
Schema Evolution
这个是我的前同事Chunxu做 Schema Evolution的时分截的一张图。能够看到这也是Iceberg的一个亮点,便是说这个表本来有几列,我能够加一列或许改一列,当然这也不难,由于本来 Hive table也能够这样做,可是做完之后,你的table还能不能查?Iceberg给咱们的答案是 table改完了还能查,当然这儿边也有tricky的当地,里面的数据也不是这么完好,可是不论怎么样它没犯错,你先改好table,用老的query还能够查到。这个功用我觉得仍是挺实用的,由于各个公司 table总在改,改完之后 table在presto这边仍是能够查的。
Iceberg连接器更新
接下来会讲一下咱们社区最近这一两个月的一些贡献,希望能够对咱们有帮助,我主要讲是Presto DB,Trino那儿是别的一套故事,尽量统筹来讲。
New Features
最近这两三个月,有几个功用进来之后给咱们的一些东西解锁了。
1.榜首份credit要要点给亚马逊公司AWS 的Jack Ye,他做了一个 native folder的支撑,这个在Iceberg叫做Hadoop catalog,盘活了咱们的很多功用,处理了咱们非常多的痛点。
2.别的便是腾讯的Baolong,他把local cache这个功用给加上去了,现在Iceberg connector能够和 RaptorX那一套,便是Hive connector里的cache,同样享用local cache,得到提速。当然这个不是那么简略,那么开箱即用,或许会需求一些配置,后边我会再具体地讲。
3.接下来便是Uber的Xinli Shang,咱们俩给parquet做了升级。Xinli Shang是Parquet社区的chair,他给parquet做了升级后,咱们拿过来放在presto里,咱们的升级作业历时大约半年,升级到新的parquet之后,咱们也解锁了Iceberg 1.12,有更多新的功用,包含对v2 的Iceberg table的支撑。
4.还有一个predicate pushdown,在后边Beinan(Alluxio)也会具体地讲一下,这是能够优化查询的一个功用。
Iceberg Native Catalog
这便是我方才提到的 Jack做的 native catalog——本来在Iceberg叫Hadoop catalog,其实Iceberg数据也是存在 S3、HDFS、GCS里的。它的每一个table下面既有元数据,又有数据,那为什么还需求Hive metastore,还要去Hive metastore里取元数据呢?这是由于最开始的Hive catalog仍是要依靠Hive的元数据的,咱们需求找到 table的途径,到这个table里把Iceberg自己的元数据加载出来,然后用 presto进行查询。有了 Jack这个很好的修改,咱们能够支撑Hadoop catalog,你直接给它一个途径,table都放在这个途径下面,它到这个途径上去扫一下,就能够录入一切的table,像table1,table2,table3, 每个table多少元数据,咱们就不再需求Hive metastore了。有了这个native catalog之后, presto和Iceberg的结合就完好了。本来咱们还依靠于一个额定的元数据存储,现在咱们能够直接运用native catalog,这处理了非常多的痛点。
Iceberg Loca Cache
这个是之前有朋友问的 local cache,这个功用或许两个礼拜以前才merge的,腾讯的Baolong特别厉害几天就把这功用给做好了。那么为什么这个东西这么快就做好了,这个得从Iceberg connector的完成说起,是由于Iceberg connector和 Hive connector用的是一套东西,都是同一个Parquet reader或许是ORC reader。所以说咱们当时在 RaptorX这个项目里,便是在 Hive下面做local cache,这个项目里用的很好的 local cache,在 Facebook、头条、还有Uber都获得很好作用,咱们就把这个local cache直接搬到Iceberg里来用,直接能获得一个很好的作用。
这个里面有要害点得跟咱们说一下,这个 local cache像是每个worker自己的私有缓存,它不像Alluxio cache那样,是一个分布式的、弹性的,能够部署比如说100个节点或200个节点,能够水平扩展的。可是这儿不相同,这儿边给你一个就近的小容量的local缓存,给每个worker或许500g或许1TB的一个本地磁盘,用来当作缓存运用。
这儿就有一个问题, Presto在做plan的时分是随机分的,比如说每一个大的table下面有1万个partition,上面或许有100万个文件,随便拿一个文件,它不一定去哪个worker,每个worker cache不了那么多数据。于是咱们就有一个soft affinity scheduling,有点像做负载均衡的时分会有一个affinity的功用相同,也便是粘连,比如说这个文件去work1,以后就一直去work1,这样的话work1只要把它cache了,你再拜访这个文件它的cache命中率就提高了,所以这个affinity的功用是一定要翻开的。
假如你发现local cache命中率很低,你就要看是不是affinity做的不对,是不是你的节点频频添加或许减少,即使你什么都不调,你只要把 soft affinity翻开,用一个比如说500g或许1TB的 local cache,它的命中率应该是不会低的,应该是有百分之六七十的命中率,这个是数据量很大的情况,数据量小的话或许有100%的命中率。
事实上便是Presto交给Iceberg来做一个plan。在收到SQL请求后,Presto解析,把 SQL拆一拆,告诉Iceberg要查什么,Iceberg就会生成一个plan,说要扫哪些文件,然后presto经过 soft affinity把这些文件分发给特定的worker,这些worker就会去扫这些文件,假如命中了本地cache扫本地文件,假如没命中本地cache就扫远程文件。其实Alluxio便是一个二级的存储,本地没命中去Alluxio,Alluxio还没命中去三级存储。
当然咱们后续会有semantic cache,这个主要是给Hive做的,可是就像我前面提的,由于Iceberg和Hive底层的完成是同源的,因此成果咱们都能够用。这儿跟咱们通报一个最新的发展,是AWS的Iceberg 团队Jack刚跟咱们讲的,咱们或许会不再运用presto的Hive 完成,当然这是可选的,你能够持续运用presto的 Hive完成,也能够运用Iceberg的native完成。这样以后Iceberg有什么新的功用,咱们就不依靠Hive,这也是好事,而且咱们能够引入更多向量化的东西,这是个长时间的 plan,或许下一年咱们才会见到。
Iceberg Native Catalog
关于一个presto的查询来说,咱们就说select* from table,比如说 city=‘Beijing’,profile age>18岁,这样一个查询,它其实就生成了左面这三个块的plan,先scan,scan完了给filter,filter完了给输出,其实便是扫完表之后,看哪些符合条件就输出但这个没有必要。比如说咱们这个表是按照城市做的分区,没有必要扫整个表,而且每一个文件都有计算的,或许这个文件里年纪都是小于18岁的,就不用扫能够直接跳过了。
在 presto里有个connector optimizer,这个是prestoDB特有的一个东西,能够针对不同的connector来做优化,为什么要针对不同的connector做优化?由于很多人或许是一个Iceberg table去照映一个Hive table,这两个table底下 scan数据源是不相同的,所以你要决定到底把什么条件下推下去。其实有一个最简略的规矩,便是Iceberg目前不支撑profile.age这种有嵌套的字段的下推,那我就把 city下推,就把city的 filter下推到table scan,和table scan合并成一个plan节点,便是这个当地既做filter又做scan,然后下推给Iceberg,这儿我把age>18岁留着,scan好了之后再filter,这个不是最优的方案,但这是最基本的规矩。
Predicate Pushdown Resource Usage
咱们来看看作用,这不是一个正规的Benchmark,便是方才我建的 table,新加了一条记载,月份等于13的那个,假如我不开下推的话,是左面这种情况,它扫了200万条记载,input数据是200多KB;开了下推之后,它只扫描一条记载,时刻和数据都有非常大的提升,它只扫特定的分区。这种查询在实际中遇不到,由于实际中肯定是有更多的组合,每个partition下面或许还有更多的文件,这儿比较极点一些,只要这一个文件。其实这样作用不明显,文件越多作用越好,推荐咱们试一试。
之前提到了 Native Iceberg IO,咱们会运用Iceberg reader和writer来替代Hive完成,让它完全的分隔,也或许两个都支撑,这个便是咱们即将进行的作业,敬请期待。
Ongoing Work
别的一个是物化视图(materialized view),是我的前同事Chunxu在做的,这也是重要的一个功用,让暂时表能够把数据存到一起,这个也没有那么简略, Facebook也有同事在做这个。咱们这儿不再多说了,Facebook很快会有一个关于物化视图的新的博客出来。
我会持续把v2 table完成一下删本来只能是按照分区来删,不能删去某一行或某几行,由于删去操作和insert是相同的,会再发生一些新的文件,标示说你这几行要被删掉了,然后真正出成果的时分,会把它合并到一起。现在是不支撑这个功用的,那么咱们要想支撑这个功用,有两个做法,一个是运用 native Iceberg IO,别的一个便是在 Parquet的 reader上把要删的这些行标示出来,表示这些行不再显现。以上便是今年年底或下一年年初的一些作业和想象,谢谢咱们。
想要获取更多有趣有料的【活动信息】【技术文章】【大咖观念】,请重视[Alluxio智库]: