为啥 hive 在 Join 操作期间不选择 SerDe JAR?

Posted

技术标签:

【中文标题】为啥 hive 在 Join 操作期间不选择 SerDe JAR?【英文标题】:Why does hive not pick SerDe JAR during Join operations?为什么 hive 在 Join 操作期间不选择 SerDe JAR? 【发布时间】:2018-10-11 04:46:15 【问题描述】:

hadoop 版本:Hadoop 2.6.0-cdh5.12.2 hive 版本:Hive 1.1.0-cdh5.12.2

考虑两个表: products - 存储产品 ID 和有关产品的其他详细信息 活动 - 存储 user_id、product_id 告诉哪个用户购买了哪个产品和其他交易细节。

在创建这些表之前,我使用以下命令添加了 SerDe JAR: 添加jar /home/ManojKumarM_R/json-serde-1.3-jar-with-dependencies.jar;

CREATE EXTERNAL TABLE IF NOT EXISTS products (id string,name string,reseller 
string,category string,price Double,discount Double,profit_percent Double) 
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' location 
"/user/ManojKumarM_R/ProductsMergeEnrichOut";

/user/ManojKumarM_R/ProductsMergeEnrichOut 中的样本数据

"Id":"P101", "Name":"Round Tee", "Reseller":"Nike", "Category":"Top Wear", "Price":2195.03, "Discount":21.09, “利润百分比”:23.47

"Id":"P102", "Name":"Half Shift", "Reseller":"Nike", "Category":"Top Wear", "Price":1563.84, "Discount":23.83, “利润百分比”:17.12

CREATE EXTERNAL TABLE IF NOT EXISTS activity (product_id string,user_id 
string,cancellation boolean ,return boolean,cancellation_reason 
string,return_reason string, order_date timestamp, shipment_date timestamp, 
delivery_date timestamp , cancellation_date timestamp,  return_date 
timestamp) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' location 
"/user/ManojKumarM_R/ActivityMergeEnrichOut/";

/user/ManojKumarM_R/ActivityMergeEnrichOut/ 中的样本数据

"Product_id":"P117", "User_id":"U148", "Cancellation":"TRUE", "Return":"NA", "Cancellation_reason":"重复产品", "Return_reason":" NA"、"Order_date":"2016-02-12"、"Shipment_date":"NA"、"Delivery_date":"NA"、"Cancellation_date":"2018-05-20"、"Return_date":"NA"

"Product_id":null, "User_id":"U189", "Cancellation":"FALSE", "Return":"FALSE", "Cancellation_reason":"NA", "Return_reason":"NA", "Order_date":"2017-04-22", "Shipment_date":"2017-05-05", "Delivery_date":"2017-09-09", "Cancellation_date":"NA", "Return_date":"NA "

建表成功,

select * from products; 

&

select * from activity; 

查询工作得很好,因此表示在选择查询期间选择了 SerDe JAR。

但是,当我运行以下连接查询时:我想将这两个表连接到一个公共列上,即 Product Id

SELECT a.user_id, p.category FROM activity a JOIN products p  
ON(a.product_id = p.Id);

失败并显示以下消息

执行日志位于:/tmp/ManojKumarM_R/ManojKumarM_R_20181010124747_690490ae-e59f-4e9d-9159-5c6a6e28b951.log 2018-10-10 12:47:43 开始启动本地任务来处理map join;最大内存 = 2058354688 执行失败,退出状态:2 获取错误信息

任务失败! 任务编号: 第五阶段

登录 /tmp/ManojKumarM_R/ManojKumarM_R_20181010124747_690490ae-e59f-4e9d-9159-5c6a6e28b951.log

2018-10-10 12:47:43,984 错误 [main]: mr.MapredLocalTask​​ (MapredLocalTask​​.java:executeInProcess(398)) - Hive 运行时错误:映射本地工作失败 org.apache.hadoop.hive.ql.metadata.HiveException: 失败并出现异常 java.lang.ClassNotFoundException: org.openx.data.jsonserde.JsonSerDejava.lang.RuntimeException: java.lang.ClassNotFoundException: org.openx。 data.jsonserde.JsonSerDe 在 org.apache.hadoop.hive.ql.plan.TableDesc.getDeserializerClass(TableDesc.java:73)

这表示 Hive 无法找到 JsonSerDe JAR,即使我在该 hive 会话期间添加了 JAR 并且 selct 查询工作正常。 如果有人解决了类似的问题,请告诉我,我不确定 Hive 在 JOIN 操作期间是否在不同的目录中查找 JAR。

【问题讨论】:

【参考方案1】:

Hive 不会为所有“SELECT *”查询调用 MR 作业。在您的情况下,当调用实际 MR 作业(JOIN 查询)时,JAR 文件不会跨集群传播。因此,我建议您重新检查 JAR 文件夹/文件权限或将文件移动到 HIVE 库路径并更新 Hive-site.xml。之前有几篇关于如何添加 HIVE JAR 文件的帖子,您也可以查看。

以前的帖子。

how to add a jar file in hive

【讨论】:

我参考了上面的帖子并寻找将 SerDe JAR 传播到整个集群的方法,常用方法是在 hive-site.xml <property> <name>hive.aux.jars.path</name> <value>location to JAR file</value> </property> 中包含以下标记并重新启动 Hive 服务器。问题是,我正在一个没有管理员访问权限的集群上工作,因此我无法编辑 hive-site.xml 并且我无法重新启动 Hive 服务器。理想情况下,我应该联系管理员,但我正在寻找在没有管理员访问权限的情况下跨集群传播 SerDe JAR 的方法。

以上是关于为啥 hive 在 Join 操作期间不选择 SerDe JAR?的主要内容,如果未能解决你的问题,请参考以下文章

或者 Hive 中的 JOIN 错误当前不支持

Hive 如何使用mapjoin

hive mapjoin

hive 常用的 join 操作 实例

Hive LEFT SEMI JOIN 表示“不存在”

Hive Map Join