专栏首页牛肉圆粉不加葱Databricks Delta Lake 介绍

Databricks Delta Lake 介绍

Delta Lake is an open-source storage layer that brings ACID transactions to Apache Spark and big data workloads.

一、Delta Lake 特性

  • ACID 事务:Delta Lake 提供多个写操作之间的 ACID 事务。每个写操作都是一个事务,事务日志中记录的写操作有一个串行顺序
    • 事务日志会跟踪文件级的写操作,并使用 乐观并发控制 ,这非常适合数据湖,因为尝试修改相同文件的多个写操作并不经常发生。在存在冲突的场景中,Delta Lake 会抛出一个并发修改异常,以便用户处理它们并重试它们的作业
    • Delta Lake 还提供了强大的序列化隔离级别,允许工程师不断地对目录或表进行写操作,而用户可以不断地从相同的目录或表中读取数据。读取者将看到读操作开始时存在的最新快照
  • Schema 管理:Delta Lake 会自动验证正在写入的 DataFrame Schema 是否与表的 Schema 兼容
    • 表中存在但 DataFrame 中不存在的列会被设置为 null
    • 如果 DataFrame 中有额外的列在表中不存在,那么该操作将抛出异常
    • Delta Lake 具有可以显式添加新列的 DDL 和自动更新Schema 的能力
  • 可伸缩的元数据处理:Delta Lake 将表或目录的元数据信息存储在事务日志中,而不是存储在元存储(metastore)中。这使得 Delta Lake 能够在固定的时间内列出大型目录中的文件,并且在读取数据时非常高效
  • 数据版本控制和时间旅行:Delta Lake 允许用户读取表或目录先前的快照。当文件在写期间被修改时,Delta Lake 将创建文件的新版本并保存旧版本。当用户希望读取表或目录的旧版本时,他们可以向 Apache Spark 的读操作 API 提供一个时间戳或版本号,Delta Lake 根据事务日志中的信息构建该时间戳或版本的完整快照。如果需要,还可以将表还原为旧版本
  • 统一的批处理和流 sink:除了批处理写之外,Delta Lake 还可以使用 Apache Spark 的结构化流 作为高效的流 sink。再结合 ACID 事务和可伸缩的元数据处理,高效的流 sink 现在支持许多接近实时的分析用例,而且无需维护复杂的流和批处理管道
  • 记录更新和删除(即将到来):Delta Lake 将支持合并、更新和删除 DML 命令。这使得工程师可以轻松地维护和删除数据湖中的记录。由于 Delta Lake 在文件粒度上跟踪和修改数据,因此,比读取和覆写整个分区或表要高效得多
  • 数据期望(即将到来):Delta Lake 还将支持一个新的 API,用于设置表或目录的数据期望。工程师将能够通过指定布尔条件及调整严重程度来处理数据期望。当 Apache Spark 作业写入表或目录时,Delta Lake 将自动验证记录,当出现违规时,它将根据所预置的严重程度处理记录

二、批量读取和写入

2.1、简单示例

create a table

df.write.format("delta").save("/delta/events")

Partition data

df.write.format("delta").partitionBy("date").save("/delta/events")

Read a table

spark.read.format("delta").load("/delta/events")

2.2、查询表的旧快照(时间旅行)

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")

对于timestamp_string,仅接受日期或时间戳字符串。例如,2019-01-012019-01-01 00:00:00.000Z

2.3、写入一个表

使用 Append 模式,可以自动将新数据追加到现有 Delta Lake 表:

df.write.format("delta").mode("append").save("/delta/events")

要以原子方式替换表中的所有数据,可以使用 overwrite 模式:

df.write.format("delta").mode("overwrite").save("/delta/events")

您可以选择性地仅覆盖与分区列上的谓词匹配的数据。如下以原子方式将1月份替换为df中的数据:

df.write
  .format("delta")
  .mode("overwrite")
  .option("replaceWhere", "date >= '2017-01-01' AND date <= '2017-01-31'")
  .save("/delta/events")

2.4、Schema 自动更新

Delta Lake 可以自动更新表的 schema,作为 DML 事务的一部分,并使 schema 与正在写入的数据兼容

2.4.1、增加列

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

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

2.4.2、NullType 列

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

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

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

2.5、视图

Delta Lake 支持在 Delta Lake 表上创建视图,就像使用 data source 表一样。

使用视图操作时的核心挑战是解析 schema。 如果更改 Delta Lake 表 schema。 例如,如果向 Delta Lake表添加新列,则必须确保此列在该基表之上构建的相应视图中可用。

三、流式读取和写入

四、并发控制

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

  • 多个 writer,即使它们跨多个集群,也可以同时修改表并查看表的一致快照视图,并且这些写入将有一个顺序
  • reader 将继续看到 Spark 作业开始的表的一致快照视图,即使在作业期间修改了表也是如此

4.1、乐观的并发控制

Delta Lake 使用乐观并发控制在写入之间提供事务保证。在这种机制下,写操作分三个阶段进行:

  1. read:读取表的最新可用版本以识别需要修改哪些文件
  2. write:通过编写新数据文件来进行所有更改
  3. validate and commit:调用 commit 方法,生成 commit 信息,生成一个新的递增1的文件,如果相同的文件名已经存在,则报 ConcurrentModificationException

五、Delta 目录结构

adminMacBook-Pro:spark-2.1.1-bin-2.7.3 admin$ hadoop fs -ls /tmp/delta-table/
Found 34 items
drwx------   - admin supergroup          0 2019-04-30 14:22 /tmp/delta-table/_delta_log
-rw-------   2 admin supergroup        263 2019-04-30 14:21 /tmp/delta-table/part-00000-174ce4e0-9dde-4704-9d79-b41e1cb51eda-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:13 /tmp/delta-table/part-00000-19ed1ad3-45b6-4527-8acc-2137f256165b-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:22 /tmp/delta-table/part-00000-2ec77809-f928-4717-bc66-c61f5fa4e690-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:13 /tmp/delta-table/part-00000-381f68e5-f027-4304-a9a9-a0d63b33f95c-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:22 /tmp/delta-table/part-00000-4f7a5e99-8a2d-4661-85a2-3adb796e6014-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:21 /tmp/delta-table/part-00000-6739de6e-61d2-4083-84a6-127362012290-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:13 /tmp/delta-table/part-00000-687847fc-4196-40a8-87aa-cb288ce41d3a-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:22 /tmp/delta-table/part-00000-717ac816-0195-4581-9c26-8249e94b6cf6-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:12 /tmp/delta-table/part-00000-8520f2ed-5a81-4caa-bd24-ca16ae96fcfc-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:13 /tmp/delta-table/part-00000-b538fde3-6fe2-454a-b505-4f388807866f-c000.snappy.parquet
-rw-------   2 admin supergroup        263 2019-04-30 14:22 /tmp/delta-table/part-00000-e7ce533e-2a52-4f16-b356-1627f4d0b986-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00003-2272ef42-30f6-461a-a3df-1d643d36fe57-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:21 /tmp/delta-table/part-00003-5f13f30e-0412-4013-8887-ef36a813b7b3-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00003-6d7f0bfd-9dce-4dcc-9ed8-6a8bb9fd3f43-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00003-9905ed46-2906-4626-8ceb-7a1b33d0fba9-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:12 /tmp/delta-table/part-00003-a4841920-25b7-4822-85c8-c946605227f9-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00003-bbf64370-749e-4b05-a1aa-83edd474f4dd-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00003-c38c8546-adca-4580-884c-f0814d8a9b86-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00003-cda3cb71-6bba-478a-9623-5c5a3483517e-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00003-ced20325-7840-441e-b1ee-4b5781ec92df-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00003-d6ce4ea8-103e-4dc5-9b28-e53b321b0b86-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:21 /tmp/delta-table/part-00003-ee71b4f1-6153-42fd-bfec-3e4478c23a22-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00007-37233cb9-bd0b-41b9-b935-25592e57bcbb-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00007-3851b027-acca-445f-8208-408bafe6ecaf-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00007-405cf78e-229b-4045-891d-582433962093-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00007-44be9b91-a94f-41d0-af47-b867e052b92b-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00007-48155c68-e17c-4773-8711-03da5aba86b3-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:21 /tmp/delta-table/part-00007-57aeb2af-3785-400a-94d7-c257e4ce6ba0-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:21 /tmp/delta-table/part-00007-616923f9-615b-4977-9b8b-15a155baf9b4-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:12 /tmp/delta-table/part-00007-c23e1896-47dd-4076-a189-174bb45f6384-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:13 /tmp/delta-table/part-00007-c34873a2-9077-4ed0-9104-3f08059be4c9-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00007-ca13411e-88ad-4d5a-8a6d-dfd1808824bb-c000.snappy.parquet
-rw-------   2 admin supergroup        423 2019-04-30 14:22 /tmp/delta-table/part-00007-f0912369-add4-444b-9bdb-677a1d688db6-c000.snappy.parquet

adminMacBook-Pro:spark-2.1.1-bin-2.7.3 admin$ hadoop fs -ls /tmp/delta-table/_delta_log
Found 13 items
-rw-------   2 admin supergroup       1076 2019-04-30 14:12 /tmp/delta-table/_delta_log/00000000000000000000.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:13 /tmp/delta-table/_delta_log/00000000000000000001.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:13 /tmp/delta-table/_delta_log/00000000000000000002.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:13 /tmp/delta-table/_delta_log/00000000000000000003.json
-rw-------   2 admin supergroup        718 2019-04-30 14:13 /tmp/delta-table/_delta_log/00000000000000000004.json
-rw-------   2 admin supergroup       1573 2019-04-30 14:21 /tmp/delta-table/_delta_log/00000000000000000005.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:21 /tmp/delta-table/_delta_log/00000000000000000006.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:22 /tmp/delta-table/_delta_log/00000000000000000007.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:22 /tmp/delta-table/_delta_log/00000000000000000008.json
-rw-------   2 admin supergroup       1147 2019-04-30 14:22 /tmp/delta-table/_delta_log/00000000000000000009.json
-rw-------   2 admin supergroup      13308 2019-04-30 14:22 /tmp/delta-table/_delta_log/00000000000000000010.checkpoint.parquet
-rw-------   2 admin supergroup       1147 2019-04-30 14:22 /tmp/delta-table/_delta_log/00000000000000000010.json
-rw-------   2 admin supergroup         38 2019-04-30 14:22 /tmp/delta-table/_delta_log/_last_checkpoint

adminMacBook-Pro:spark-2.1.1-bin-2.7.3 admin$ hadoop fs -cat /tmp/delta-table/_delta_log/00000000000000000000.json
{"commitInfo":{"userId":null,"userName":null,"operation":"WRITE","operationParameters":{"mode":"Overwrite","partitionBy":"[]"},"job":null,"notebook":null,"clusterId":null,"readVersion":null,"isolationLevel":null}}
{"protocol":{"minReaderVersion":1,"minWriterVersion":2}}
{"metaData":{"id":"7a880cd4-0061-42ae-a998-965b6cfc3198","format":{"provider":"parquet","options":{}},"schemaString":"{\"type\":\"struct\",\"fields\":[{\"name\":\"id\",\"type\":\"long\",\"nullable\":true,\"metadata\":{}}]}","partitionColumns":[],"configuration":{},"createdTime":1556604759993}}
{"add":{"path":"part-00000-8520f2ed-5a81-4caa-bd24-ca16ae96fcfc-c000.snappy.parquet","partitionValues":{},"size":263,"modificationTime":1556604760157,"dataChange":true}}
{"add":{"path":"part-00003-a4841920-25b7-4822-85c8-c946605227f9-c000.snappy.parquet","partitionValues":{},"size":423,"modificationTime":1556604760193,"dataChange":true}}
{"add":{"path":"part-00007-c23e1896-47dd-4076-a189-174bb45f6384-c000.snappy.parquet","partitionValues":{},"size":423,"modificationTime":1556604760216,"dataChange":true}}

adminMacBook-Pro:spark-2.1.1-bin-2.7.3 admin$ hadoop fs -cat /tmp/delta-table/_delta_log/00000000000000000001.json
{"commitInfo":{"userId":null,"userName":null,"operation":"WRITE","operationParameters":{"mode":"Overwrite","partitionBy":"[]"},"job":null,"notebook":null,"clusterId":null,"readVersion":0,"isolationLevel":null}}
{"add":{"path":"part-00000-687847fc-4196-40a8-87aa-cb288ce41d3a-c000.snappy.parquet","partitionValues":{},"size":263,"modificationTime":1556604781695,"dataChange":true}}
{"add":{"path":"part-00003-bbf64370-749e-4b05-a1aa-83edd474f4dd-c000.snappy.parquet","partitionValues":{},"size":423,"modificationTime":1556604781707,"dataChange":true}}
{"add":{"path":"part-00007-c34873a2-9077-4ed0-9104-3f08059be4c9-c000.snappy.parquet","partitionValues":{},"size":423,"modificationTime":1556604781708,"dataChange":true}}
{"remove":{"path":"part-00000-8520f2ed-5a81-4caa-bd24-ca16ae96fcfc-c000.snappy.parquet","deletionTimestamp":1556604781912,"dataChange":true}}
{"remove":{"path":"part-00003-a4841920-25b7-4822-85c8-c946605227f9-c000.snappy.parquet","deletionTimestamp":1556604781913,"dataChange":true}}
{"remove":{"path":"part-00007-c23e1896-47dd-4076-a189-174bb45f6384-c000.snappy.parquet","deletionTimestamp":1556604781913,"dataChange":true}}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【源码剖析】- Spark 新旧内存管理方案(下)

    上一篇文章【源码剖析】- Spark 新旧内存管理方案(上)介绍了旧的内存管理方案以及其实现类 StaticMemoryManager 是如何工作的,本文将通过...

    codingforfun
  • Spark 内存管理的前世今生(上)

    作为打着 “内存计算” 旗号出道的 Spark,内存管理是其非常重要的模块。作为使用者,搞清楚 Spark 是如何管理内存的,对我们编码、调试及优化过程会有很大...

    codingforfun
  • 配置hadoop集群namenode的hostname千万不要包含下划线

    在部署hadoop集群时,core-site.xml中的fs.defaultFS项的value不可包含下划线,否则会报以下错误

    codingforfun
  • android 圆角图片的实现和封装

    下面为主要源码,实现了 Picasso 中的 Transformation 接口。

    夏洛克的猫
  • Java基础-封装

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    cwl_java
  • html5页面头部

    deepcc
  • 论文阅读: FPN

    基于深度网络的检测算法出来之前,检测算法基本都是基于这种scale handling;后来出现的SNIP、SNIPER也是基于Image Pyramid。 ...

    JNingWei
  • html5页面头部

    deepcc
  • JS中什么是函数,什么又是方法???

    用户7873631
  • Android快速开发框架 roboguice

    我记得推过一篇文章也是快速开发框架的,今天再来一篇! 1、roboguice 效果 ---- ? 图文无关 2、roboguice 说明 ---- robo...

    非著名程序员

扫码关注云+社区

领取腾讯云代金券