这是我参与「第四届青训营 」笔记创作活动的第1天
前置知识:
- HDFS - 分布式存储系统:
- HDFS通过将文件分块来存储大文件,HDFS的组件有NameNode和DataNode,分别负责提供元数据和数据服务。在读/写数据时,HDFS客户端需要先从 NameNode上获取数据读取/写入的DataNode地址,然后和DataNode交互来完成数据读/写。
- Parquet - 高性能列式存储:
- 过滤下推到存储侧,更好地压缩性能。
发展历史:
- 数据湖发展阶段1 - Hadoop:
- 好处:
- 同一公司/组织可以使用共享存储
- 数据访问方便,灵活性高
- 坏处:
- 没有记录文件的schema(包括列名、列类型),经常使用Schema on Query的方式
- 难以得知数据集包含了那些文件,是通过什么样的分区组织的
- 如果多个程序都在修改这个数据集(修改数据、修改表结构),其他程序难以配合做修改
- 好处:
- 数据湖发展阶段2 - Hive:
- 数据湖发展阶段3 - 湖仓一体:
- 现状:
- 结合了数据湖和数据仓库的优势
- 将数据仓库中对于数据的严格管理直接实现到了低成本的分布式存储之上
- 现状:
核心技术:
文件结构
写入数据湖时:
- 按照每条数据的date进行分区
- 额外使用metadata文件记录表信息,如右图所示
Time Travel
要点:
- 每次写入都生成一个新的元数据文件,记录变更
- 分区数据在Update时,不要删除旧数据,保证新旧共存
- 元数据中存储具体的文件路径,而不仅仅是分区文件夹
Transaction
数据湖中的ACID:
- Atomicity:原子性–本次写入要么对用户可见,要么不可见(需要设计)
- Consistency:一致性–输入是什么,落盘的就是什么(由计算引擎保证)
- Isolation:事务隔离–正确解决读写冲突和写写冲突(需要设计)
- Durability:持久性–落完数据后,即便服务器重启结果不变((由存储引擎保证)
Schema Evolution
重要:
- 用户并不直接读取parquet文件本身,而是通过数据湖接口读取,如 Dataset<Row> ds = simpleDataLake.read(mytable).option(date=2020-01-01)
- 数据湖内部会读取应该读的parquet,并在schema上做进一步处理
各有所长:
Iceberg工作重点
- 用户体验
- Schema evolution
- Partition evolution
- Hidden partition
- Time Travel
- Version Rollback
- 性能:
- 快速file plan
- 2.更多的filter方式
- 可靠性
- ACID Transaction
- 完全开源,由Apache孵化开发
Hudi
Hudi工作重点:
- Timeline service: Hudi管理transaction的方式
- HudiTable Type: Copy on Write /Merge on Read
- 高效的Upserts: update or insert
- 索引表:快速定位一条数据的位置
- Streaming Ingestion Service6.完全开源,由Apache孵化
Delta Lake 工作重点
- ACID Transaction
- Schema校验(不是evolution)
- 流批一体
- Time Travel
- Upsert/Delete
- Z-Order 优化
- 只开源了一部分,由Databricks自己主导开发,Z-order等优化的实现未开源
总结:
异同比较:
短期来看:每个项目都有一些属于自己的功能:
- 如果强需求Upserts,也许Hudi是最好的选择
- 如果希望可扩展性强,那么设计优良的Iceberg是最好的选择
- 如果希望用上Z-Order等优化,那么掏钱买Databricks的企业版 Delta是不二之选
长期来看:数据湖取代Hive,成为HDFS上的表格式标准是必然的,在选择之前问自己四个问题:
- 我需要的feature在哪个数据湖上是最稳定的
- 哪一个数据湖能够用最简单的接入方式(SQL)用上最完善的功能
- 哪—一个数据湖有计算引擎侧的支持和社区的支持
- 哪一个数据湖的版本管理做的最好,最鲁棒