0767-Hive ACID vs. Delta Lake( 三 )
- 在云存储中重命名目录不具备原子性(atomic) - 由于目录重命名不是原子操作 , 因此在目标目录中可以看到部分数据 。 这不是Hive中的事务更新的问题 。 但是 , Hive 3.1中的Hive ACID compaction不是作为事务运行的 。 导致的结果就是 , compaction(执行rename操作)与读取操作同时运行是不安全的 。 此问题在Hive的更高版本中通过HIVE-20823已修复 。 Qubole使用的Hive3.1中已包含该补丁 。
3.4 Spark实现
如之前提到的 , 我们正在开发使用Spark读取Hive ACID事务表功能 , 并将这块功能开源 , 我们想选择一种易于开源的设计方法 。 考虑到这一点 , 我们倾向于基于Spark DataSource的实现 , 该实现可以作为第三方库开源 , 并可以由用户通过Spark包的方式引入 。 参考:
https://spark-packages.org/
我们选择DataSource v1 , 因为它是目前较为稳定的DataSource API 。 这种实现方式的关键点如下:
1.它使用Hive readers(InputFormat)读取Hive事务表 , 然后它会使用Hive writers(OutputFormat)来进行insert , update和delete;
2.与Hive Metastore通信以获取可以读取的事务表的当前快照 , 并在RDD的整个生命周期中使用相同的快照;
3.不获取Hive表上的读取锁(read locks) , 因此依赖管理员不删除可能正在读取的数据 。 管理员需要禁用自动清除(automatic cleanup) , 以便Hive Metastore不会删除数据;
4.在数据摄取和更新期间将采取写锁定(write locks) 。
参考:
https://github.com/qubole/spark-acid
3.5 Presto实现
在添加对读取Hive事务表的支持时 , Presto面临两个主要挑战:
- 协调Hive事务和Presto事务 - Presto拥有自己的事务管理 , 我们扩展了该事务管理 , 以便为Presto事务中的每个查询设置Hive事务 。 多个Hive事务(一次仅一个活动的)可以成为Presto事务的一部分 。 它们在查询开始时打开 , 并在查询结束时关闭;Hive事务中的任何失败都会使整个Presto事务失败 。
- Hive事务表的高性能reader - 我们为此评估了多种设计选择 , 并决定扩展Presto原生的ORC reader 。 与其它方法相比 , 此方法涉及的改动会较大 , 但从性能角度来看 , 这是最佳选择 。 在此实现中 , 们确保事务表继续使用流拆分生成(streaming split generation) , 利用读数据的延迟物化(lazy materialization) , 并且不会受到Presto原生的ORC reader对STRUCT数据类型的性能影响 。 这在我们的基准测试中带来了不错的效果 , 与读取普通表相比 , 在读取Hive事务表方面几乎没有表现出任何损失 。
下一步
我们目前正在努力增强Spark的功能 , 以提供从Spark到Hive ACID表的插入 , 更新和删除事务的功能 。 我们希望它能够很快开源并可用 , 大家可以关注Spark-ACID github存储仓库以获取更新:
https://github.com/qubole/spark-acid
Presto的更改正在被合并到开源中 , 您可以按照Presto Pull Request#1257的要求获取最新的详细信息和补丁 。
https://github.com/prestosql/presto/pull/1257
最后我们还在评估Hive ACID支持Parquet文件格式的update/delete 。
原文参考:
https://www.qubole.com/blog/qubole-open-sources-multi-engine-support-for-updates-and-deletes-in-data-lakes/
推荐阅读
- 【农村小春】plus vs.吉利缤vs.SUV?,Cs35
- cnBeta:vs. Foundem案件新进展:让SEO专家介入或放弃提交算法文件,Google
- 「cnBeta」vs. Foundem案件新进展:让SEO专家介入或放弃提交算法文件,Google
