Spark Sql 设置 IDENTIFIER FIELDS
在使用 Spark SQL 设置 IDENTIFIER FIELDS,被设置的字段必须是 NOT NULL 的。
// 建表
CREATE TABLE sample (
id bigint NOT NULL,
data string NOT NULL,
category string,
ts timestamp)
USING iceberg;
// 使用 SET IDENTIFIER FIELDS 语法
// 只有 id 和 data 才能被设置成为 IDENTIFIER FIELDS 因为它们是 NOT NULL
alter table sample SET IDENTIFIER FIELDS id;
alter table sample SET IDENTIFIER FIELDS data;
设置 engine.hive.enabled
任何非 hive 引擎创建表后,如果需要该表对 hive 可见,需要使用 spark 设置表属性 engine.hive.enabled'='true'。
源表-目标表 schema 非空字段对齐
在使用 Spark SQL 对源表和目标表之间进行insert into… insert overwrite… merge into…操作时,要注意源表和目标表的非空字段是对齐的。如果源表的字段允许非空,而目标表的字段不允许非空,那么 spark 将会校验不通过。在源表是 hive,目标表是 iceberg 时尤其需要注意。
spark-shell 操作 Iceberg API
iceberg 提供了 Java API,可以直接操作 iceberg 表。其核心接口为:org.apache.iceberg.Table (Table)。在 spark-shell 环境中使用可以参考以下脚本:
import org.apache.iceberg.relocated.com.google.common.collect.Maps;
import org.apache.iceberg.hive.HiveCatalog;
import org.apache.iceberg.catalog.TableIdentifier
import org.apache.iceberg.Table
var catalog = new HiveCatalog();
catalog.initialize("hive_prod", Maps.newHashMap());
catalog.setConf(spark.sparkContext.hadoopConfiguration);
var name = TableIdentifier.of("iceberg_db", "iceberg_table");
var table = catalog.loadTable(name);
主键约束
flink 建表中使用的主键,只对 flink 引擎生效。其他的引擎依然可以使用相同的主键插入数据,形成相同主键的多条数据。在这样的场景下,flink 依然可以正常查询,但是在做 upsert 操作时,会删除其他主键相同的数据,只留下一条记录。
spark-iceberg timestamp timezone 不一致
iceberg 支持不带 timezone 的 timestamp 但是 spark 不支持不带 timezone 的 timestamp。所以如果其他引擎创建的 iceberg 表中带有 timestamp without timezone 字段,那么使用 spark 读会存在潜在的时区转换问题。在 spark 引擎下需要增加相关配置来规避:
# Controls whether reading/writing timestamps without timezones is allowed
set spark.sql.iceberg.handle-timestamp-without-timezone=true
# Controls whether timestamp types for new tables should be stored with timezone info
set spark.sql.iceberg.use-timestamp-without-timezone-in-new-tables=true
# 以上用法不推荐,建议在建表时就对齐字段类型!
Trino查询Iceberg表速度慢
trino查询iceberg耗时14秒,分析是由于数据源比较小(37MB),扫描数据和预汇聚都是单并发,可以通过调整参数set session prefer_partial_aggregation=false;取消预汇聚,后续步骤可以并发提升性能,和配置测试最新耗时在5-6秒。