在说 Delta Lake 之前,不得不说下 Data Lake ,Data Lake 的主要思想是将企业中的所有数据进行统一管理。例如基于 Hadoop 的 Data Lake 方案可以非常低成本的存储所有类型的数据。
显而易见的,它只支持批量插入,用户读取时无法获取当前更新的数据,多用户写还可能会发生异常,带来脏数据的问题,并不是非常可靠。又比如在 hadoop 生态中,困难的更新/删除操作 (需要整块重写),无法保证数据一致性 (例如 spark 读取时缓存了 parquet 元数据,若元数据变化需要进行 refresh)
Delta Lake 不仅能解决上述问题,还能对数据进行各种增强,例如 time travel, index 等。
Delta Lake 在近期开源 项目地址,发布了其第一个 release 版本,使用 parquet 文件格式,在其上通过 transaction log
记录更新操作从而提供了 ACID 事务等能力,通过与 spark 集成,得以处理大量的元数据。
Delta Lake 可以更简单的理解为构建在 Data Lake 上的一层数据库。巧妙的地方在于,它不是一种 file format
而是 table format
,这意味着你不需要修改底层的存储文件,他解放了用户花费在数据一致性上的大量时间,分析时也无需关心表中的数据是来自流数据还是历史数据。此外,通过时间旅行的功能,可能解决很多非常麻烦的事情,例如事件回放。
Delta lake 相关特性在官网上已经说的非常详细,不再赘述,根据笔者自己的理解简单描述一下五个比较重要的特性:
在文件上增加一个日志结构化存储(transaction log ),该日志有序(ordered)且保持原子性(atomic)
增加或者删除数据时,都会产生一条描述文件,采用乐观并发控制 (optimistic concurrency control) 保证用户并发操作时数据的一致性
Delta Lake 在读写中提供了 ACID 事务保证。这意味着:
Delta Lake 使用 optimistic concurrency control 机制提供写数据时的事务保证,在这种机制下,写过程包含三个步骤:
在 spark 中,为了提高查询性能会缓存 parquet 的元数据,如果此时表的 schema 被更新必须要手动刷新元数据才能保证数据的一致性,例如 spark.sql(refresh table xxx)
因为 delta Lake 的特性,数据更新后也无需调用 refresh
,目前仅支持 HDFS 作为底层存储
// 将已有 parquet 数据转化为 delta table
val df = spark.read.parquet("/path/to/your/data")
df.write.format("delta").save("/delta/delta_table")
spark.sql("CREATE TABLE delta_table USING DELTA LOCATION '/delta/delta_table'")
delta 表根目录 _delta_log
下会生成 json 格式的事务文件
hdfs dfs -cat /delta/delta_table/_delta_log/00000000000000000000.json
{"commitInfo":{"timestamp":1555989622032,"operation":"WRITE","operationParameters":{"mode":"ErrorIfExists","partitionBy":"[]"}}}
{"protocol":{"minReaderVersion":1,"minWriterVersion":2}}
{"metaData":{"id":"f33f4754-7c0c-43b8-87a2-ddc21e1311ea","format":{"provider":"parquet","options":{}},"schemaString":"{\"type\":\"struct\",\"fields\":[{\"name\":\"id\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{\"comment\":\"\"}}]}","partitionColumns":[],"configuration":{},"createdTime":1555989621467}}
Delta Lake 的理念给了大数据处理太多的想象空间。
目前大数据处理现在都朝着流批一体,ACID 事务,HTAP,AI,API易用性前进,得益于 databricks 优秀的商业策略,spark 无疑是其中走的最稳最好的。