有什么需求需要Paimon来解决?
在它刚刚诞生的时候,被叫做Built-In Dynamic Table Storage,动态表是Flink实时处理的一个概念,简单的说就是不同时间点的表的内容是不一样的,也就是说这个表一直在变,并且你可以回放到过去任意时间的一个点,变化的内容也能作为changeLog输出给外部算子。
所以Paimon的定位是:流批统一的存储。简单的说就是既可以作为Hive一样支持批量查询、插入,也能像从Kafka接入Change Log一样接入实时数据的这么一个存储引擎。
具体可以看Flink提案:https://cwiki.apache.org/confluence/display/FLINK/FLIP-188%3A+Introduce+Built-in+Dynamic+Table+Storage
稍微理解记录一下
就是说这里的Kakfa既作为Source,还用作存储中间结果。正常我们是只关心图里最右面的聚合结果而不是中间结果的,这时候是没有问题的。但是一旦我们有需求需要查(ad hoc)一下中间结果,发现查Kafka太不方便了。
所以有些同学就想了个办法,就是中间结果同时存储在Kafka和Hudi、ClickHouse,这样想查(ad hoc)的话就去Olap引擎里面去查。但是这样也有个问题,就是存储大量数据的成本是很高的,所以就得对数据设置TTL把过期的数据删掉或者把过期数据存储到类似iceberg这种不那么费资源的存储中。
主要使用的技术架构。
为啥是LSM树而不是别的数据结构。
对于数据的性能方面,我们比较关注的主要是写入和查询。
存:磁盘和固态硬盘的顺序存储性能都大大强于随机存储,那么如果有一种架构能够尽可能利用顺序存储的性能,那岂不是可以实现高吞吐的数据写入了么。
查:它内部有很多文件,文件内部的数据内容是排序了的,所以每个文件都有一个边界,文件和文件之间也根据每个文件的边界再排序,而且每个文件之间都是不重合的,这样的话,根据排序规则来查找一个或一堆连续的数据也会非常的快。
LSM树就是这种数据结构。
LSM Tree
LSM Tree的在大数据集的存储引擎中使用还是非常广泛的,比如HBase、LevelDB、RocksDB都使用到了这块的技术。
总的来说,数据分别存储在内存和磁盘中,详细分的话一共有三个地方用来存储数据。
1、磁盘文件(File Store)。用于真正的持久化文件。我们先不用管里面具体的数据结构,先了解一下这个文件的主要思想,就是“尽可能的利用磁盘的顺序写性能(只插不更或删了重插),好找文件里面的内容(文件内容排序)”。虽然现实业务中的数据内容经常需要更新,但是我们先假设所有要写入的数据都是源源不断的、且一旦写入之后也不需要更新、变更的,那么我们就可以不断的向磁盘写入文件,尽可能的利用到磁盘的顺序写性能优势了。
2、内存(MemTable)。我们都知道数据都是先存在内存中,然后再写入到磁盘的。在写入的过程中先在内存中缓存起来,当内存中积攒到一定数量的数据之后,再一股脑的写到文件中去。为了方便数据的组织和查找,数据在写入内存之后是要按一定规则去排序的。这内存的数据结构就是memTable。
3、预写日志(WAL)。上面的两个文件存储的位置仿佛已经满足了实际的需求,但是我们知道存储在内存中的文件是不稳定的,一旦服务器宕机,内存中的数据就丢失了。为了解决这个问题,引入了预写日志(Write Ahead Log),就是当数据写入前,先将写入的数据信息写入到日志文件中去,这样宕机后重启也可以从这个日志中恢复内存中内容。另外,预写日志在Paimon里面还被称为Log Store,当批读的时候,可以直接读FileStore,而流读的时候,就可以先读FileStore来获取已经落盘好的数据,然后再从LogStore读取增量的Change Log。
LSM Tree总体的思路大概就是这样,当然上面的描述都是没有考虑数据更新和其他实际上很重要的场景,暂时先不介绍数据文件的合并(compact)了。
那如果有数据更新怎么办。
这部分就是LSM Tree(Log Structured Merge Tree)中merge的内容。LSM把上面数据存储的位置分了很多层,具体多少层不定,Paimon默认是4层。第一层就是内存中的MemTable,而后的层都是File Store,里面存储的文件格式是SstFile文件。当MemTable中的数据达到一定量级时,会触发Flush动作写入文件。这时候就可能会触发compact,这块后面再介绍。
快速问答:
Q:与时下流行的ClickHouse、Hudi对比,有什么优势。
Flink Table Store 与 Hudi、Lceberg 的差别在哪里?
A:本质差别在于数据定位。Flink Table Store使用 LSM 结构来更新和接受查询,相当于在写过程中不断地 Spill、 Compaction,其优点在于编写进来的数据已经排序好。并且通过 Append Spill 来更新,更新性能高。另外,LSM 结构可以在存储上有更大的扩展性,比如类似 Clickhouse 那样可以有各种场景的 MergeTree,加速查询。
Q:怎么实现分布式存储
A:LSM树是存在于某个机器中的数据结构,那么如果想实现分布式存储,那么就通过引入桶来解决。