Merge-On-Read Merge-On-Read,顾名思义,就是在读取的时候进行合并,是与Copy-On-Write相反的一种模式在Iceberg中,Merge-On-Read同样用于行级更新,整体过程如下当更新数据时,Iceberg不再Copy一份旧数据,而是直接将更新数据写入独立的一个文件用来标识需要删除的数据这种模式减少了写入时的合并操作,但是加重了读取数据时的合并操作,因此适合写多读少的场景。
Iceberg Copy-On-Write Copy-On-Write:顾名思义,就是在写入的时候进行复制,最初是计算机领域用来解决读多写少场景下的并发访问控制问题的如下,在Copy-On-Write模式下,用户写数据时,会先将原始数据Copy出一份副本,此时其他用户读数据时仍然读取的是原始的数据;之后进行写的用户对副本进行修改,修改完成以后,将访问指向的原始数据替换为修改后的数据;替换完成后,用户访问都会访问这个被修改过的数据Copy-On-Write在读多写少的场景下可以提供有效的性能,因为读操作不受影响,可以一直正常访问资源数据。
FlinkSQL ChangeLog 登录sql-client,创建一个upsert-kafka的sql作业(注意,这里发送给kafka的消息必须带key,普通只有value的消息无法解析,这里的key即是主键的值)发送消息带key和消费消息显示key方式如下作业的DAG图如下。
Flink分区相关 真正有用的信息是在table表的信息当中,核心在tables.put(tablePath, table.copy());这一句当中,table.copy()存储了表信息,最终调用到实现类CatalogTableImpl,其父类的构造函数有分区信息。表中存储了相应的分区信息,SQL最终操作的都是表,所以都是从这取的分区信息,注意这是一个StringList。
Range-Encoded Bit-Slice Index 算法使用Bit-Sliced Range-Encoded BitMap算法,在基础bitmap的基础上,添加了范围查询和Bit-Sliced范围查询用来弥补bitmap范围查询能力弱的问题;Bit-Sliced用来降低索引Key值的存储数量,进而降低整体索引的空间占用BSI就是Bit-Sliced,即将数值按位切分表示,用更少的内容代表更多的数据,通常有十进制方式和二进制方式,二进制方式更佳。
Spark Bloom Filter Join Bloom Filter Join,或者说Row-level Runtime Filtering(还额外有一条Semi-Join分支),是Spark 3.3对运行时过滤的一个最新补充之前运行时过滤主要有两个:动态分区裁剪DPP(开源实现)、动态文件裁剪DFP(Databricks实现),两者都能有效减少数据源层面的Scan IOBloom Filter Join的主要优化点是在shuffle层,通过在join shuffle前对表进行过滤从而提高运行效率。
Iceberg Flink FLIP-27实现 前面步骤完成后是把所有的分片全部放在了assigner当中,没有进行分配。分配在AbstractIcebergEnumerator接口当中定义,这是Iceberg当中enumerator的最上层父类,直接实现Flink的SplitEnumeratorSplitEnumerator定义了handleSourceEvent接口,负责处理来自读取器的自定义消息,有SourceCoordinator调用LOG.debug(subtask,
Flink动态分区裁剪 静态分区裁剪的原理跟谓词下推是一致的,只是适用的是分区表,通过将where条件中的分区条件下推到数据源达到减少分区扫描的目的动态分区裁剪应用于Join场景,这种场景下,分区条件在join的一侧,另一侧无法应用条件进行裁剪静态分区裁剪是静态的规则优化下推,动态分区裁剪是运行时过滤,通过对有条件一侧的表进行过滤,提取结果中的分区数据,然后传递到另一侧的表中进行数据过滤。
Iceberg小文件合并 Iceberg提供了Actions来进行小文件合并,需要手动调用执行这个任务目前仅仅将小文件进行了合并生成大文件,但旧的文件并没有删除,也就是文件反而变多了功能一路调用,到RowDataRewriter类中的rewriteDataForTasks这里构建Flink任务,核心是RewriteMap的算子,其map方法如下,本质是读取并写入数据注意,这边小文件合并任务是多并发的,目前flink的并发度这里不提供配置,所以用的是flink的parallelism.default的值。