kylin 构建 cube 时,抛出了如下的错误:
org.apache.kylin.engine.mr.exception.HadoopShellException: java.lang.RuntimeException: Checking snapshot of TableRef[xxx] failed. at org.apache.kylin.cube.cli.DictionaryGeneratorCLI.processSegment(DictionaryGeneratorCLI.java:111) at org.apache.kylin.cube.cli.DictionaryGeneratorCLI.processSegment(DictionaryGeneratorCLI.java:55) at org.apache.kylin.engine.mr.steps.CreateDictionaryJob.run(CreateDictionaryJob.java:73) at org.apache.kylin.engine.mr.MRUtil.runMRJob(MRUtil.java:93) at org.apache.kylin.engine.mr.common.HadoopShellExecutable.doWork(HadoopShellExecutable.java:63) at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:165) at org.apache.kylin.job.execution.DefaultChainedExecutable.doWork(DefaultChainedExecutable.java:70) at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:165) at org.apache.kylin.job.impl.threadpool.DistributedScheduler$JobRunner.run(DistributedScheduler.java:110) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.IllegalStateException: The table: xxx Dup key found, key=[null], value1=[null,null,null,null,null], value2=[null,null,null,null,null] at org.apache.kylin.dict.lookup.LookupTable.initRow(LookupTable.java:86) at org.apache.kylin.dict.lookup.LookupTable.init(LookupTable.java:69) at org.apache.kylin.dict.lookup.LookupStringTable.init(LookupStringTable.java:80) at org.apache.kylin.dict.lookup.LookupTable.<init>(LookupTable.java:57) at org.apache.kylin.dict.lookup.LookupStringTable.<init>(LookupStringTable.java:66) at org.apache.kylin.dict.lookup.LookupProviderFactory.getInMemLookupTable(LookupProviderFactory.java:63) at org.apache.kylin.cube.CubeManager.getInMemLookupTable(CubeManager.java:523) at org.apache.kylin.cube.CubeManager.getLookupTable(CubeManager.java:509) at org.apache.kylin.cube.cli.DictionaryGeneratorCLI.processSegment(DictionaryGeneratorCLI.java:106) ... 11 more
其中 xxx 表是维度表,它跟事实表是一对多的关系。抛出的错误很令人费解,怎么会全是 null 的值呢? xxx 表里没有这样的记录啊。key 是 id,在 Mysql 里是自增长的主键,也不可能是空,所以导入 hive 后,也不可能为空。日志显示是在生成 xxx 表的 snapshot 时产生的,在网上搜了一下,https://juejin.im/post/5bcf370d6fb9a05cff3255dd 这篇文章中有关于此过程的描述,摘录如下:
(1)从原始的hive维度表中顺序得读取每一行每一列的值;
(2)使用 TrieDictionary 方式对这些所有的值进行编码(一个值对应一个 Id);
(3)再次读取原始表中每一行的值,将每一列的值使用编码之后的 Id 进行替换,得到了一个只有 Id 的新表;
(4)同时保存这个新表和 Dictionary 对象(Id 和值的映射关系)就能够保存整个维度表;
(5)Kylin 将这个数据存储到元数据库中
从中也没看出会出现重复主键的情况。后来又看到说是事实表关联此维度表时,如果对应多个,则会出现此问题。本来就是一对多的关系,肯定会出现多个的啊。也不知道是他没表达清楚,还是我没理解。找了很久,也没发现问题所在,后来一个不经意的发现,才使这一问题得到解决。我在 hive 中查看事实表的记录数时,发现有 6500 多条,但是我的 mysql 里只有 6300 条。不知道为什么,sqoop 导入 hive 后,会多出几百条记录。经过查找才知道,如果原始 mysql 里的字段里的值有换行符的话,导入 hive 后,因为hive中存的是文本,换行符是一条记录,所以会多出记录来。并且这些值并不在真正对应的列了。所以会出现事实表的一些记录关联不到维度表的记录,此时就会出现 key=[null], value1=[null,null,null,null,null] 的情况。
解决办法: 在用 sqoop 导入时,多加一个参数: --hive-delims-replacement ‘ ‘ ,这会把换行符替换为空格。因为无法确定原始表中会不会有换行符,所以强烈建议不管什么情况都加此参数。
重新导入后,cube 构建成功。问题虽然解决了,但是还是有一处不明白,为什么报的是 Dup key found 的错误,维度表并没有重复主键。
原文:https://www.cnblogs.com/langfanyun/p/10551774.html