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:)
at org.apache.kylin.cube.cli.DictionaryGeneratorCLI.processSegment(DictionaryGeneratorCLI.java:)
at org.apache.kylin.engine.mr.steps.CreateDictionaryJob.run(CreateDictionaryJob.java:)
at org.apache.kylin.engine.mr.MRUtil.runMRJob(MRUtil.java:)
at org.apache.kylin.engine.mr.common.HadoopShellExecutable.doWork(HadoopShellExecutable.java:)
at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:)
at org.apache.kylin.job.execution.DefaultChainedExecutable.doWork(DefaultChainedExecutable.java:)
at org.apache.kylin.job.execution.AbstractExecutable.execute(AbstractExecutable.java:)
at org.apache.kylin.job.impl.threadpool.DistributedScheduler$JobRunner.run(DistributedScheduler.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:)
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:)
at org.apache.kylin.dict.lookup.LookupTable.init(LookupTable.java:)
at org.apache.kylin.dict.lookup.LookupStringTable.init(LookupStringTable.java:)
at org.apache.kylin.dict.lookup.LookupTable.<init>(LookupTable.java:)
at org.apache.kylin.dict.lookup.LookupStringTable.<init>(LookupStringTable.java:)
at org.apache.kylin.dict.lookup.LookupProviderFactory.getInMemLookupTable(LookupProviderFactory.java:)
at org.apache.kylin.cube.CubeManager.getInMemLookupTable(CubeManager.java:)
at org.apache.kylin.cube.CubeManager.getLookupTable(CubeManager.java:)
at org.apache.kylin.cube.cli.DictionaryGeneratorCLI.processSegment(DictionaryGeneratorCLI.java:)
... 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 读的却是所有的目录下的数据,这就导致肯定会出现重复的数据了。

这个的 hadoop 环境是用 HDP 搭建的,我用原始的 hadoop 等包,搭建了一个 hadoop 环境,做重复 sqoop 导入的操作,发现跟上面的不一样,真的是删掉原来的目录,再创建一个的,表对应的目录下永远只有一个数据文件。

最后,总结出来,出现这个问题的原因就是:事实表(列:id)与维度表(列:fact_id) 进行关联时,同一个事实表的 id,关联时出现了超过一次。

Kylin -- Dup key found 问题的更多相关文章

  1. mongodb E11000 duplicate key error collection: index: _id_ dup key

    今天在单测的时候,出现这个问题. 我代码只定义了一个变量 let body = {name: 'wu'} 然后连续2次插入这个body数据 await exam.insertExam(body); a ...

  2. E11000 duplicate key error index: test.collection.$a.b_1 dup key: { : null } 报错记录

    这个一般分为两种情况,第一新增数据出现约束.而你在orm里面写了唯一约束.这种情况就比较简单,添加数据时保证数据字段唯一性就好了. 第二种情况比较难找,因为你发现你在orm里面并没有写约束,但是还是插 ...

  3. MongoDB学习笔记三—增删改文档上

    插入insert 单条插入 > db.foo.insert({"bar":"baz"}) WriteResult({ }) 批量插入 > db.fo ...

  4. Python: Windows 7 64位 安装、使用 pymongo 3.2

    官网tutorial:  http://api.mongodb.com/python/current/tutorial.html 本教程将要告诉你如何使用pymongo模块来操作MongoDB数据库. ...

  5. MongoDB 3.X 用户权限控制

    摘要: MongoDB 3.0 安全权限访问控制,在添加用户上面3.0版本和之前的版本有很大的区别,这里就说明下3.0的添加用户的方法. 环境.测试: 在安装MongoDB之后,先关闭auth认证,进 ...

  6. CentOS7 安装MongoDB 3.0服务器

    1,下载&安装 MongoDB 3.0 正式版本发布!这标志着 MongoDB 数据库进入了一个全新的发展阶段,提供强大.灵活而且易于管理的数据库管理系统.MongoDB宣称,3.0新版本不只 ...

  7. MongoDB学习笔记(索引)

    一.索引基础:    MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令:    > db.test.ensureIndex({" ...

  8. MongoDB索引的使用

    Table of Contents 1. 基本索引 2. 联合索引 3. 索引类型 4. 索引管理 1 基本索引 在数据库开发中索引是非常重要的,对于检索速度,执行效率有很大的影响.本 文主要描述了M ...

  9. Mongodb Manual阅读笔记:CH8 复制集

    8 复制 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb Manual阅读笔 ...

随机推荐

  1. Android BindService中遇到的一个小问题

    今天在使用BindService的时候遇到个小问题,我希望通过Bindservice获取到这个服务,然后执行服务内的某个自定义方法,如下: if(bindService==null){ Intent ...

  2. VS2017自动添加头部注释

    让VS自动生成类的头部注释,只需修改两个文集即可,一下两个路径下个有一个 Class.cs文件 D:\Program Files (x86)\Microsoft Visual Studio\2017\ ...

  3. Python内置函数二 (递归函数,匿名函数,二分法)

    匿名函数 lambda() 语法: lambad  参数 : 返回值 def func(a,b): return a * b print(func(2,5)) a = lambda a ,b : a* ...

  4. TableView被Navigation bar挡住的解决办法

    在存在遮挡的ViewController的ViewDidload函数里添加以下两句即可解决 self.edgesForExtendedLayout = UIRectEdge.None self.aut ...

  5. leetcode669

    本题目是使用递归处理,根据当前的值来判断剪去的子树,保留剩下的子树. class Solution { public: TreeNode* trimBST(TreeNode* root, int L, ...

  6. WebRTC相关的基础知识点

    这里主要用来记录自己整理的和webRTC相关的一些基本的知识点,后续整理的一些基础和零碎的知识点都会更新在这里.内容大部分来自于webRTC官网.w3c以及一些前辈们的博客中的文章和相关书籍等. 20 ...

  7. fatal error C1083: 无法打开包括文件:“qedit.h”: No such file or directory

    VS2010编译 DirectShow一些项目时遇到 错误:fatal error C1083: 无法打开包括文件:“qedit.h”: No such file or directory 解决方法: ...

  8. python中shuffleSplit()函数

    参数: n : int 数据集中的元素总数. n_iter : int (default 10) 重新洗牌和分裂迭代次数. test_size : float (default 0.1), int, ...

  9. zookeeper介绍及集群的搭建(利用虚拟机)

    ZooKeeper ​ ZooKeeper是一个分布式的,开放源码(apache)的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase.dubbox.kaf ...

  10. MySql 获取服务提供的sakila数据库(Example Databases)

    关于这个数据库也就是样例数据库,数据库,数据库,最可怕的就是没有数据了,对吧?没有数据你学个什么呀. 可是,没有数据,咱会自己insert,那只能适用于初学者.对于数据库的优化方面的学习,还是有大数据 ...