Delta Lake架构

Delta Lake的架构如下图所示。

在Delta Lake中,将数据表分为三类:铜表(Bronze)、银表(Silver)和金表(Gold)。这三类表分别代表数据在处理的不同阶段,说明如下:

  • 铜表
    • ① 因为数据来自不同的数据源,这可能是脏的数据。因此,它是原始数据的垃圾场。
    • ② 通常保留时间很长(例如,保留一年以上)。
    • ③ 避免容易出错的解析。
  • 银表
    • ① 由中间数据组成,并应用了一些清理操作。
    • ② 是可查询的,便于调试。
  • 金表
    • ① 由准备使用的干净数据组成。
    • ② 可以使用Spark或Presto读取数据。

Delta Lake的真正优势是操作本身提供了ACID事务保护。要理解Delta Lake是如何提供这些保护的,读者需要首先解包并理解事务日志。

Delta Lake的核心是事务日志,这是一个中央存储库,用于跟踪用户所做的所有更改,它保证了客户端启动的事务的原子性、一致性、隔离性和持久性。事务日志以JSON文件的形式记录每一个变更,并按照更改的顺序进行记录。如果有人做了更改,但是删除了它,仍然会有一个记录来简化审计。它作为真实的单一来源,使用户能够访问Delta Table状态的最后一个版本。它提供了序列化能力,这是隔离级别的最强级别。

例如,_delta_log目录下就是存储事务日志的目录,如下图所示。

进入该事务日志目录,可以看到事务日志存储在json文件中,如下图所示。

因此,在Delta Lake中,读取一张表也会重放这张表的历史记录,比如表的重命名、修改Schema等等操作。

Delta Lake将客户端执行的每个活动分隔为原子提交,每个原子提交由actions组成。成功完成提交的所有actions可以确保Delta Log记录提交的操作。对于任何失败的作业,commit不会记录在Delta Log中。

更详细来说,在Delta Lake中的每个JSON文件都是一次commit,这个commit是原子性的,保存了事务相关的详细记录。另外,Delta Lake还可以保证多个用户同时commit而不会产生冲突,它用的是一种基于乐观锁处理的方式。这种解决冲突的方案适用于“写比较少、读取比较多”的场景。

假设用户要处理一个非常大的表,有百万级别的文件,那么如何高效的处理元数据呢?Delta Lake用Spark来读取事务日志,然后Delta Lake隔一段时间对commit做一次合并,之后可以从Checkpoint开始应用后续的commit。


《Spark原理深入与编程实战》