跳到主要内容

常见问题

根因

  1. checkpoint.interval 设得太短(比如 10s),每次 Checkpoint 都写一批小 SST;
  2. Bucket 数设得太大(表总共 1GB 你搞了 64 个 bucket);
  3. Compaction 线程数设成 0,或者被手动关了。

快速解法

-- ① 先查小文件有多少
SELECT bucket, count(*) AS file_cnt, avg(file_size_in_bytes)/1024/1024 AS avg_mb
FROM ods.ods_order_info$files
WHERE dt = '2026-09-05'
GROUP BY bucket
HAVING file_cnt > 50;

-- ② 立刻手动 compact 一个分区缓一下
CALL sys.compact('ods.ods_order_info', 'dt=2026-09-05');

-- ③ 长期改表参数(后续 checkpoint 后就会少很多小文件)
ALTER TABLE ods.ods_order_info SET (
'compaction.min.file-num' = '8', -- 文件太少不值得合并时提高阈值
'target-file-size' = '128 MB',
'num-sorted-run.compaction-trigger' = '20'
);

最根本的原则Checkpoint 间隔 ≥ 2 分钟。你如果是秒级延迟的场景,Paimon 不是消息队列,还是用 Kafka 接秒级,Paimon 管分钟级/批量就够了。


Q2. 主键表写入报错:Primary key constraint violation on table

根因

  1. 上游同一个 Checkpoint 里,同一个主键出现了 2 次不同的数据(比如 Binlog 乱序 + 你又开了 scan.incremental.snapshot.enabled=false);
  2. 多条流同时写同一张 Paimon 表,没在 Flink 里在 shuffle 到同 key 之前 keyBy。

解法

-- ① 建表时加 sequence.field,Binlog 里 update_time 大的覆盖小的(最稳)
ALTER TABLE ods.ods_order_info SET ('sequence.field' = 'update_time');

-- ② 多条 INSERT 流进同一张 Paimon 表时,先 UNION ALL + 按主键 shuffle,再写
INSERT INTO ods.ods_order_info
SELECT * FROM (
SELECT * FROM cdc_a
UNION ALL
SELECT * FROM cdc_b
);

Q3. Hive 3.1 上 SELECT * FROM paimon_tbl 报错:StorageHandler not found

根因:Hive Server2 里没放 paimon-hive-3.1-*.jar,或者 hive.aux.jars.path 没配。

解法

# 所有 HiveServer2 / HiveMetaStore 节点都放 jar
cp paimon-hive-3.1-0.9.0.jar /usr/hdp/current/hive-client/auxlib/
# 没有 auxlib 就建一个,然后 Ambari → Hive → Configs → Advanced hive-env
# 找到 hive_aux_jars_path 填 /usr/hdp/current/hive-client/auxlib
# 重启 HiveServer2 + HiveMetaStore

然后在 Hive 里查 Paimon 表:

SHOW CREATE TABLE paimon.ods.ods_order_info;  -- 应该显示 STORED BY 'org.apache.paimon.hive.PaimonStorageHandler'
SELECT dt, count(*) FROM ods_order_info WHERE dt='2026-09-05' GROUP BY dt;

根因:表的 changelog-producer 设错了(none 就不产出完整 changelog)。

解法

-- 先确认表现在是什么值
DESC EXTENDED dwd.dwd_order_detail;

-- 改表:上游是 Flink CDC 或 Flink 聚合的表全改成 input(你 99% 是这个场景)
ALTER TABLE dwd.dwd_order_detail SET ('changelog-producer' = 'input');

-- 如果上游可能有 Spark 写的 UPDATE/DELETE(混合写入),改成 full-compaction 最通用
ALTER TABLE dwd.dwd_order_detail SET (
'changelog-producer' = 'full-compaction',
'full-compaction.delta-commits' = '3'
);

Q5. HDP 3.3.2 Hive Metastore 连 Paimon 时,Kerberos 打开后报:GSS initiate failed

根因:Paimon Catalog 里没带上 Kerberos principal / keytab,Hive 的 JAAS 配置没传过去。

解法(在 Flink / Spark 里都加对应配置):

-- Flink SQL 建 Catalog 时加
CREATE CATALOG paimon WITH (
'type' = 'paimon',
'metastore' = 'hive',
'uri' = 'thrift://master1:9083',
'warehouse' = 'hdfs:///user/hive/warehouse/paimon',
'hive-conf-dir' = '/etc/hive/conf',
'kerberos.principal' = 'hive/master1@HADOOP.COM',
'kerberos.keytab' = '/etc/security/keytabs/hive.service.keytab'
);

Spark 对应在启动命令里加:

--conf spark.sql.catalog.paimon.kerberos.principal=hive/master1@HADOOP.COM
--conf spark.sql.catalog.paimon.kerberos.keytab=/etc/security/keytabs/hive.service.keytab

Q6. Paimon 表占用磁盘暴涨,GC 不回收怎么办?

根因:Snapshot 留的时间太长(默认 1h~1d,但如果你设了 30d,底层文件就一直不敢删);或者有孤儿文件(程序中断留下的)。

解法

-- ① 先把快照保留降下来(你做了每日 TAG,数据安全已有保障,快照不用留太久)
ALTER TABLE dwd.dwd_order_detail SET (
'snapshot.time-retained' = '24 h',
'snapshot.num-retained.min' = '10',
'snapshot.num-retained.max' = '100'
);

-- ② 先手动触发快照过期 + 文件清理
CALL sys.expire_snapshots('dwd.dwd_order_detail', '24 h', '10');

-- ③ 再清孤儿文件(HDFS 里存在但 Paimon 快照链已经不引用的文件)
CALL sys.remove_orphan_files(
'dwd.dwd_order_detail',
'older_than 1 d', -- 避免误删正在写入的文件,最少 older_than 1 小时
'/tmp/paimon-orphan/' -- 可选:先把要删的列到这里的文件列表里,检查无误再删
);

Q7. Paimon 主键表和 Doris/StarRocks 主键表同步,数据对不上

根因:Paimon 的 Changelog 产得不全,下游 OLAP 引擎收到的是 Partial Update,或者有重复消息。

解法(最稳的 3 步)

  1. 把 Paimon 表的 changelog-producer 设成 full-compaction(不要用 lookup / none,partial update 没法保证);
  2. 下游 StarRocks 同步用 Routine Load / Flink CDC 读 Paimon 的 changelog,目标表用 Unique Key 模型 + 部分列更新关闭
  3. 每天凌晨用 Spark 对 Paimon 当天的全分区做一次 SELECT count(*), sum(主键哈希) 和 StarRocks 比对,差了就对当天分区做一次全量 INSERT OVERWRITE 重新同步。

Q8. Append-only 表重复数据多(埋点场景)

根因:日志采集端 at-least-once 语义,同一个事件发了两次。

解法

-- Append-only 表指定 sequence.field + dedup
ALTER TABLE dwd_user_behavior_log SET (
'sequence.field' = 'ts',
'append-deduplicate' = 'true' -- 自动按主键/主键之外全列去重,或用 dedup 策略
);
-- 更好:埋点日志本身有 event_id,改成主键表(只多一点 merge 开销)

根因

  1. 没带分区过滤,全表扫所有分区;
  2. Bucket 数太少,Flink Reader 并行度上不去;
  3. 分区裁剪被关掉(scan.plan-sort-partition = false 会按分区数起很多 Task,OOM)。

解法

SET 'table.exec.resource.default-parallelism' = '32';
SELECT cate_id, sum(pay_amount)
FROM dwd.dwd_order_detail
WHERE dt BETWEEN '2026-09-01' AND '2026-09-05' -- 必须带分区条件!
GROUP BY cate_id;

长期:对大表建 Clustering,或者 Z-Order 按常用 Join/过滤字段排序,单查询快 10~50 倍:

CALL sys.cluster('dwd.dwd_order_detail', 'cate_id, user_id');

Q10. HiDataPlus HDP 里 Paimon 用 hdfs:///warehouse/... 报错 No FileSystem for scheme: hdfs

根因:Paimon 的 classloader 没加载 HDP 的 Hadoop conf(HDP 的配置不在默认 classpath,常见坑)。

解法

# Flink 启动前 source HDP 的 env,确保 HADOOP_CONF_DIR / HADOOP_CLASSPATH 进来
source /etc/hadoop/conf/hadoop-env.sh
export HADOOP_CONF_DIR=/etc/hadoop/conf
export HADOOP_CLASSPATH=$(hadoop classpath):/etc/hive/conf
ls $HADOOP_CONF_DIR/{core-site.xml,hdfs-site.xml,hive-site.xml} # 确认 3 个文件都在
# 再起 flink sql-client / spark-sql