Delta Lake 数据湖简单介绍

Delta Lake 介绍一

Delta Lake概念

Delta Lake 是一个存储层,为 Apache Spark 和大数据 workloads 提供 ACID 事务能力,其通过写和快照隔离之间的乐观并发控制(optimistic concurrency control),在写入数据期间提供一致性的读取,从而为构建在 HDFS 和云存储上的数据湖(data lakes)带来可靠性。Delta Lake 还提供内置数据版本控制,以便轻松回滚。

支持ACID事务

Delta Lake 在多并发写入之间提供 ACID 事务保证。每次写入都是一个事务,并且在事务日志中记录了写入的序列顺序。

事务日志跟踪文件级别的写入并使用乐观并发控制,这非常适合数据湖,因为多次写入/修改相同的文件很少发生。在存在冲突的情况下,Delta Lake 会抛出并发修改异常以便用户能够处理它们并重试其作业。

Delta Lake 还提供强大的可序列化隔离级别,允许工程师持续写入目录或表,并允许消费者继续从同一目录或表中读取。读者将看到阅读开始时存在的最新快照。

Schema管理

Delta Lake 自动验证正在被写的 DataFrame 模式是否与表的模式兼容。

  • 表中存在但 DataFrame 中不存在的列会被设置为 null
  • 如果 DataFrame 中有额外的列在表中不存在,那么该操作将抛出异常
  • Delta Lake 具有可以显式添加新列的 DDL 和自动更新Schema 的能力
  • Delta Lake 会保留大小写,但是存储文件Parquet会区分大小写,(意味着你不能再同一张表中定义“Foo”和“foo”之类的列)
  • Delta Lake 数据类型必须与目标表中的列数据类型匹配,如果不匹配,也会发生异常

可伸缩的元数据处理

Delta Lake 将表或目录的元数据信息存储在事务日志中,而不是存储在元存储(metastore)中。这使得 Delta Lake 能够在固定的时间内列出大型目录中的文件,并且在读取数据时非常高效。

数据版本

Delta Lake 允许用户读取表或目录之前的快照。当文件被修改文件时,Delta Lake 会创建较新版本的文件并保留旧版本的文件。当用户想要读取旧版本的表或目录时,他们可以在 Apache Spark 的读取 API 中提供时间戳或版本号,Delta Lake 根据事务日志中的信息构建该时间戳或版本的完整快照。这允许用户重现之前的数据,并在需要时将表还原为旧版本的数据。

eg:(版本如下)

统一的批处理和流 sink

除了批处理写之外,Delta Lake 还可以使用作为 Apache Spark structured streaming 高效的流 sink。再结合 ACID 事务和可伸缩的元数据处理,高效的流 sink 现在支持许多接近实时的分析用例,而且无需维护复杂的流和批处理管道。

数据存储格式采用开源 Apache Parquet

Delta Lake 中的所有数据都是使用 Apache Parquet 格式存储,使 Delta Lake 能够利用 Parquet 原生的高效压缩和编码方案。

查询表的旧快照

Delta Lake 时间旅行允许您查询 Delta Lake 表的旧快照。时间旅行有很多用例,包括:

  • 重新创建分析,报告或输出(例如,机器学习模型的输出)。这对于调试或审计非常有用,尤其是在受监管的行业中
  • 编写复杂的临时查询
  • 修复数据中的错误
  • 为快速更改的表的一组查询提供快照隔离

DataFrameReader options 允许从 Delta Lake 表创建一个DataFrame 关联到表的特定版本,可以使用如下两种方式:

df1 = spark.read.format("delta").option("timestampAsOf", timestamp_string).load("/delta/events")
df2 = spark.read.format("delta").option("versionAsOf", version).load("/delta/events")

对应方式也如下图所示,version和timetamp做版本的切换

增加列

当以下任意情况为 true 时,DataFrame 中存在但表中缺少的列将自动添加为写入事务的一部分:

  • write 或 writeStream 具有 .option("mergeSchema", "true")
    添加的列将附加到它们所在的结构的末尾。附加新列时将保留大小写。

NullType 列

写入 Delta 时,会从 DataFrame 中删除 NullType 列(因为 Parquet 不支持 NullType)。当收到该列的不同数据类型时,Delta Lake 会将 schema 合并到新数据类型

默认情况下,覆盖表中的数据不会覆盖 schema。 使用模式 overwrite 覆盖表而不使用 replaceWhere 时,可能仍希望覆盖正在写入的数据的 schema。 可以通过设置以下内容来选择替换表的 schema :

df.write.option("overwriteSchema", "true")

视图

Transactional meta 实现

在文件上增加一个日志结构化存储(transaction log ),该日志有序(ordered)且保持原子性(atomic)。

增加或者删除数据时,都会产生一个描述文件,采用乐观并发控制 (optimistic concurrency control) 保证用户并发操作时数据的一致性。

并发控制

Delta Lake 在读写中提供了 ACID 事务保证。这意味着:

  • 跨多集群的并发写入,也可以同时修改数据集并查看表的一致性快照,这些写入操作将按照串行执行
  • 在作业执行期间修改了数据,读取时也能看到一致性快照。

乐观并发控制

Delta Lake 使用 optimistic concurrency control 机制提供写数据时的事务保证,在这种机制下,写过程包含三个步骤:

  1. Write: 通过编写新数据文件来进行所有更改
  2. Validate and commit: 调用 commit 方法,生成 commit 信息,生成一个新的递增1的文件,如果相同的文件名已经存在,则报 ConcurrentModificationException。

 

(额外补充:名词解释)

MetaData

这里是指 Delta Table 的元数据,包括 id,name,format,创建时间,schema 信息等等。

事务日志

事务日志的相关代码主要在 org.apache.spark.sql.delta.DeltaLog 中。这个是 Delta Lake 把对数据/表的操作的记录日志。

CheckSum

可以说 CheckSum 是一个对象,里面包含了,当前 SNAPSHOT 下的表的物理大小,文件数,MetaData 的数量,协议以及事务的数量。这些信息会转成 Json 格式,存放在 CheckSumFile 中。

校验文件是在 Snapshot 的基础上计算的,会和各自的事务生死存亡。



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



 

 

你可能感兴趣的:(spark,Delta,Lake,spark,streaming,更新)