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}}

六、类图

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容