怎么建立一个小说网站,网站设计 推广,矿泉水瓶手工制作大全,浏览器无法打开住房和建设网站Iceberg 与 Hive 用法区别一、建表的区别二、分区的区别1. 分区字段的存储2. 分区与文件的关系3. 分区的类型4. 分区模式的变更5. 分区管理的区别三、Schema 变更的区别四、Spark3 写入的区别1. 事务性2. Insert into3. Insert overwrite4. 行级更新5. 写入优化五、Spark3 读取…Iceberg 与 Hive 用法区别一、建表的区别二、分区的区别1. 分区字段的存储2. 分区与文件的关系3. 分区的类型4. 分区模式的变更5. 分区管理的区别三、Schema 变更的区别四、Spark3 写入的区别1. 事务性2. Insert into3. Insert overwrite4. 行级更新5. 写入优化五、Spark3 读取的区别本文档介绍 Iceberg 和 Hive 在使用上的区别和注意事项便于对 Hive 用户熟悉的用户快速上手 iceberg。以下主要介绍 spark 使用 iceberg v1 表和 hive 表的区别。一、建表的区别hive 和 iceberg 使用 ddl 建表语法基本类似iceberg 需要指定 using iceberg。Iceberg 建表createtableiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_test(idint,datastring,dateint)usingiceberg partitionedby(date);Hive 建表createtablehive_zjyprc_hadoop.tmp.iceberg_table_test(idint,datastring,dateint)partitionedby(date);二、分区的区别Iceberg 的分区比 hive 的分区更加强大但使用方式类似。区别主要在以下方面1. 分区字段的存储Hive 表的分区字段是个虚拟字段如设置 partitioned by (date) date 字段不会实际在底层文件中存储并且分区字段总是在字段顺序的最后面。Iceberg 表的分区字段是实际字段底层文件中也包含该字段分区字段的位置不固定。2. 分区与文件的关系Hive 的分区和目录一批文件是一一映射的。hive 读取时必须 list 目录以获取分区下的所有文件。如果分区下的文件被手动删除读取时不会出现任何异常。Iceberg 的分区和文件是一一映射的映射关系被记录在元数据文件中。在读取时通过扫描元数据文件获取分区对应的文件由于元数据还记录了文件中字段的 min/max 因此在读取时可以过滤一部分文件达到文件裁剪的效果。由于文件记录在元数据中如果该文件丢失或损坏在读取时会报异常。元数据示例如下3. 分区的类型Hive 只有一种分区类型。如通常使用 date 或 day、hour 等字段做时间分区。Iceberg 支持多种分区类型。其中第一章节示例语法中的为 identity 分区和 hive 的分区完全相同。此外还支持 bucket、truncate、day、hour 等分区类型。例如使用 bucket 分区可以将数据进行分桶存储以加快速度。4. 分区模式的变更Hive 表的分区模式在建表时确定后续无法再增加、变更分区。当有新需求需要增加一个分区字段来加快查询时在 hive 上需要重写历史数据。Iceberg 表的分区模式是可以变更的修改分区模式不需要重写历史数据该特性称为 Partition Evolution。你可以使用如下语法增加和删除某个字段是否作为分区字段。注意该操作不是增加或删除一个分区的数据。ALTERTABLEiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testADDPARTITIONFIELDhour;ALTERTABLEiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testDROPPARTITIONFIELDdate;分区模式变更的原理是在元数据文件中维护了分区的不同模式当分区模式发生变更后新数据会以新的目录结构写入并被记录在元数据文件中历史数据对应关系保持不变。5. 分区管理的区别查看分区列表Hive 中可以使用 show partitions xxx 来查看分区iceberg 中可以使用 如下语法来实现同样的功能。select*fromiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_test.partitionslimit10删除分区数据Hive 中可以使用 alter table xxx drop partition(date20230201) 来删除一个分区的数据。iceberg 中可以使用 delete from 指定删除某个符合条件的数据。当 where 条件匹配到某些分区时只会修改元数据信息将匹配的文件删除因此速度非常快。deletefromxxxwheredate20230201三、Schema 变更的区别Hive 和 Iceberg 都可以增加和删除字段并调整字段顺序。主要区别有以下两个Hive 不支持 rename 字段名 iceberg 支持 rename 字段名并且重命名后不影响读取历史数据。ALTERTABLEiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testRENAMECOLUMNdateTOdt;ALTERTABLEiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testADDCOLUMNhourint;2. Iceberg 字段类型变更受限制。目前只允许以下变更int to bigintfloat to doubledecimal(P,S) to decimal(P2,S) when P2 P (scale cannot change)四、Spark3 写入的区别1. 事务性当前的 Hive 版本写入不支持事务性因此如果使用 overwrite 覆盖一个分区则可能导致下游消费该分区的任务失败报错 FileNotFound 。当使用 Spark 写入 Iceberg 时每次写入都会生成一个新的快照通过多快照的方式进行读写分离。可以在引擎的 driver 日志中查找如下日志了解本次查询基于哪个快照执行的。Scanningtableiceberg_zjyprc_hadoop.db_name.table_namesnapshot8893192237667870777created at2023-03-0902:10:04.718withfiltertrue也可以在日志spark driver 日志flink commit 节点日志中查询本次写入的事务对应的快照是哪个。2023-03-0911:11:27.917INFO org.apache.iceberg.BaseMetastoreTableOperations Successfullycommittedtotableiceberg_zjyprc_hadoop.db.table_namein2541ms2023-03-0911:11:27.917INFO org.apache.iceberg.SnapshotProducer-Committedsnapshot1523286428440820440(MergeAppend)由于 iceberg 多快照机制一个分区目录下可能存在多个快照的文件因此当使用 iceberg 时不要直接读取目录而应该通过表的方式dataframe、sql 等通过 catalog.db.table 三级结构进行访问。2. Insert into写 Hive 默认为静态分区必须指定分区写入insertintohive_zjyprc_hadoop.tmp.iceberg_table_testpartition(date20221210)values(1,a),(2,b)如果想实现动态分区写入则需要配置参数sethive.exec.dynamic.partition.modenonstrict;insertintohive_zjyprc_hadoop.tmp.iceberg_table_testvalues(1,a,20221210),(2,b,20221211)写 Iceberg 默认为动态分区数据会写到对应的分区中insertintoiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testvalues(1,a,20230101,1),(2,b,20230102,2)同时也支持静态分区的写入方式insertintoiceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testpartition(date20230103,hour1)values(1,a),(2,b)3. Insert overwriteSpark 覆盖写入Hive 默认为 static overwrite必须指定分区insertoverwrite hive_zjyprc_hadoop.tmp.iceberg_table_testpartition(date20220101)select1asid,aasdataSpark 覆盖写入Iceberg 默认为 dynamic overwrite覆盖的分区将会在运行阶段计算得到– 覆盖 date20230101/hour1 和 date20230101/hour2 分区– 但不会覆盖 date20230101/hour3 的分区insertoverwrite iceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testvalues(1,a,20230101,1),(2,b,20230101,2)下面两个写法和上述写法结果相同– All DP columnsinsertoverwrite iceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testpartition(date,hour)values(1,c,20230101,1),(2,d,20230101,2)-- Mixed SP (static partition) DP (dynamic partition) columnsinsertoverwrite iceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testpartition(date20230101,hour)values(1,b,1),(2,c,2)-- All SP columnsinsertoverwrite iceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testpartition(date20230101)values(1,c,1),(2,d,2)上面 dynamic overwrite 的行为如果有两级分区当指定一级分区覆盖时被覆盖的二级分区取决于运行阶段查询出的数据因此有可能有部分二级分区不会被删除。Dynamic overwrite 是按照当前的分区模式进行判断的。比如历史分区模式是一级分区当前分区模式是二级分区那么 overwrite 时是按照二级分区的模式进行覆盖写一级分区的历史数据不会被删除。使用 static overwrite 和 写入 hive 默认行为表现一致。可以通过配置 --conf set spark.sql.sources.partitionOverwriteModestatic 来设置为 static overwrite。– 覆盖 date20230101 下所有的分区的数据– 如果没有指定 partition那么所有的分区都会被覆盖删除insertoverwrite iceberg_zjyprc_hadoop.iceberg_dev.iceberg_table_testpartition(date20230101)values(1,c,1),(2,d,2)4. 行级更新当前的 hive 版本不支持行级更新即不支持修改表中的某一行只能使用 overwrite 覆盖整个分区。Iceberg 支持使用 delete from、update、merge into 进行更新操作。参考行级更新5. 写入优化Iceberg 会更多的优化以进行降低存储和计算成本。建表策略Iceberg 针对不同场景的表提供了三种建表策略以应对存储节约优先和查询性能优先参考建表策略排序写入由于 iceberg 存在 min\max 的索引信息将常用的查询字段在写入时进行排序可以获得更好的压缩效果和查询提速。参考z-order 和 cluster by。小文件自动合并写入 iceberg 后台会自动完成小文件合并减少存储并提高查询性能。参考Binpack Compaction文件合并五、Spark3 读取的区别在使用 Spark 查询时用法上基本相同。由于 Iceberg 是文件级别的过滤当使用某个字段进行过滤时即使该字段没有设置为分区在查询时也会根据该字段的 min/max 进行过滤配合 z-order 或 cluster by 等可以获得更好的过滤效果。读取 iceberg 要以表的方式访问不要直接读取目录文件。由于 iceberg 读写都是基于元数据文件因此需要通过表的方式来读而不应该绕过元数据层直接读取数据文件否则会出现数据重复的问题。