2、Iceberg的分区查找优化:Iceberg数据表每一次的修改后的状态都会生成一个snapshot(s0,s1)文件,snapshot文件中包含了一个manifest文件的list,list中存储了当前的snapshot状态是由哪些manifest文件组成的。每一个manifest的文件中会指向到真实数据的存储文件 data file(一般是parquet格式)。在这种结构中,每一个快照读取所需要的数据文件都已经清晰的定义在了manifest list 和 manifest的文件中,并且manifest文件中还存储了相关的partition信息,那么在读取数据的时候如果需要删选partition,通过manifest的中存储的信息以K&V映射方式在O1复杂度的计算中就能定位到需要读取的partition目录。当前常用的数据读取引擎,例如hive需要遍历整个数据目录下的文件索引来寻找必要的partition,是一个O(n)的复杂度查找过程。在大数据常见的海量分区下,采用partition映射的模式来选取目录的优化效果是非常明显的,可以在Ryan Blue的讲座中看到在NetFlix的应用场景中2600个分区只需要10S就列出了,而使用hive大概10分钟还没有完成 。
3、Iceberg谓词下推的三层过滤:①分区过滤:Iceberg支持查询中的谓词下推,前面已经说了Iceberg是支持隐式分区的,就是说在读取数据的时候不需要在SQL中指定分区。Iceberg会接收上层计算引擎下推过来的谓词表达式,根据谓词表达式中column分区列的信息进行分区转换的计算。例如 一个Iceberg表有一列 time,用户设定了在time列上按照小时分区,当查询条件为 time >= 2020-01-01 10:00 AND < 2020-01-01 13:00 的时候Iceberg会根据下推过来的谓词表达式和Schema中定义的分区转换表达式进行计算。直接算出数据分区是在 10点11点12点三个分区中,然后依据manifest中的分区字段直接定位到分区目录。②文件过滤:Iceberg会把谓词继续下推到更细的筛选粒度,根据谓词的表达式和manifest中column的min/max值Iceberg可以有效的过滤查询数据所覆盖的具体data file,对扫描集做进一步的筛选,如果筛选column是有序的那么下推效果将更加明显。③RowGroup过滤:经过分区过滤和文件过滤之后Iceberg还会继续把谓词表达式下推到data file文件内部的RowGroup级别,根据parquet文件的metadata信息对RowGroup做进一步的筛选。经过以上三层的筛选,Iceberg最终把数据的扫描集缩小到必须读取的RowGroup级别,然后把需要读取的RowGroup数据读入到内存之中。(同样在Ryan Blue的讲座中我们可以看到,通过层层筛选(命中 min/max)之后,iceberg使得数据计算任务从61小时降低到了22分钟)。