mysql ignore_dup_key,Kylin -- Dup key found 問題

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.(LookupTable.java:57)

at org.apache.kylin.dict.lookup.LookupStringTable.(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 的錯誤,維度表並沒有重復主鍵。

后續:悲催地發現,第二天又出現了這個錯誤。由於業務的原因,每天晚上都會把 mysql 中的記錄用 sqoop 重新導入到 hive 中, 導入的時候,我是加了 --hive-overwrite 這個參數的,用 beeline 連接 hive 后,查詢出來的記錄也是沒問題的。用 kylin 重新構建  cube 時,就出現了 Dup key found 的錯誤,這次 key 是一個確定的值了,我查了一下 xxx 表,確定這個 key 只有一條記錄。我在 hive 客戶端,直接  drop table XXX 后,再次用 sqoop 導入,再次構建 cube 竟然成功了。有點迷茫了,再用 sqoop 導一次,再構建 cube 的時候又報這個問題了。

看了一下 HDFS 上目錄,發現表 xxx 原來的數據目錄並沒有刪除,而是直接新建了一個目錄,hive 客戶端會使用最新的目錄,不知道為什么 kylin 讀的卻是所有的目錄下的數據,這就導致肯定會出現重復的數據了。

d172ddf772fda2b2bc99c003fd0c5ca1.png

這個的 hadoop 環境是用 HDP 搭建的,我用原始的 hadoop 等包,搭建了一個 hadoop 環境,做重復 sqoop 導入的操作,發現跟上面的不一樣,真的是刪掉原來的目錄,再創建一個的,表對應的目錄下永遠只有一個數據文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值