hiveserver2/beeline在hbase表的配置单元上不返回具有内部联接的行

o75abkj4  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(354)

热释光;dri可以在hive(hiveserver1)命令行中的hbase表上使用内部联接执行hive查询,并返回正确的行。但是,在beeline(hiveserver2)命令行上的相同查询不返回任何行。我可以在hdfs表上的常规配置单元上进行内部连接。
我已经在以下mapr环境中复制了它:

MapR version: 4.0.1.27334.GA -- Hive version: hive-0.13
MapR version: 5.1.0.37549.GA -- Hive version: hive-1.2.0

我创建了两个hbase表,并像这样填充它们(注意,在mapr中,我们使用分区作为基本名称)。如果您想在非mapr环境中复制这个,请删除 /app/my_partition/ 零件号):

create '/app/my_partition/HiveParent', 'f'
create '/app/my_partition/HiveChild', 'f'

put '/app/my_partition/HiveParent', 'foo|a|', 'f:foo', 'a'
put '/app/my_partition/HiveParent', 'foo|b|', 'f:foo', 'b'

put '/app/my_partition/HiveChild', 'foo|a|1|', 'f:foo', 'a'
put '/app/my_partition/HiveChild', 'foo|a|1|', 'f:bar', '1'
put '/app/my_partition/HiveChild', 'foo|a|2|', 'f:foo', 'a'
put '/app/my_partition/HiveChild', 'foo|a|2|', 'f:bar', '2'

put '/app/my_partition/HiveChild', 'foo|b|1|', 'f:foo', 'b'
put '/app/my_partition/HiveChild', 'foo|b|1|', 'f:bar', '1'
put '/app/my_partition/HiveChild', 'foo|b|2|', 'f:foo', 'b'
put '/app/my_partition/HiveChild', 'foo|b|2|', 'f:bar', '2'

我在配置单元外壳中的hbase表上创建了配置单元,如下所示:

CREATE EXTERNAL TABLE HiveParent(rk string, foo string)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.hbase.HBaseSerDe'
STORED BY
  'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
  'serialization.format'='1',
  'hbase.columns.mapping'='f:foo'
) TBLPROPERTIES (
  'hbase.table.name'='/app/my_partition/HiveParent'
);

CREATE EXTERNAL TABLE HiveChild(rk string, foo string, bar string)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.hbase.HBaseSerDe'
STORED BY
  'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
  'serialization.format'='1',
  'hbase.columns.mapping'='f:foo,f:bar'
) TBLPROPERTIES (
  'hbase.table.name'='/app/my_partition/HiveChild'
);

以下所有查询都在配置单元(配置单元服务器1)和直线(配置单元服务器2)中成功工作:

SELECT * FROM HiveParent;
SELECT foo FROM HiveParent;
SELECT foo FROM HiveParent WHERE foo IN ('a', 'b');
SELECT * FROM HiveChild;
SELECT foo, bar FROM HiveChild;
SELECT foo, bar FROM HiveChild WHERE foo IN ('a', 'b');

这些查询只返回配置单元(配置单元服务器1)中的行。但是,它们以直线形式返回0行(配置单元服务器2):

SELECT * FROM HiveParent INNER JOIN HiveChild ON (HiveParent.foo = HiveChild.foo);

SELECT * FROM HiveParent, HiveChild WHERE HiveParent.foo = HiveChild.foo;

SELECT * FROM HiveChild WHERE HiveChild.foo IN (SELECT HiveParent.foo FROM HiveParent);

编辑:我把这个问题交叉贴到mapr的问答网站上,因为这没有引起任何注意。如果得到答案,我会把答案贴在这里。

63lcw9qa

63lcw9qa1#

我们偶然发现了这个解决方案,但可能值得研究。在一个环境中,beeline正在给予 OutOfMemory 错误并被挂起。系统管理员增加了分配给hs2的内存,之后内部连接工作正常。然而,这是令人不安的,因为beeline没有抛出任何错误,只是没有返回任何行。
将mapr5.1/hive-1.2环境中的内存从4gb增加到8gb是可行的。但是,在mapr4.0.1/hive-0.13环境中,这不起作用。
hive-env.sh :

export HADOOP_HEAPSIZE=8000
mmvthczy

mmvthczy2#

这不是一个合适的解决方案,但它是有效的。

set hive.auto.convert.join = false

是什么 hive.auto.convert.join 你知道吗?
如果hive.auto.convert.join设置为true,那么优化器不仅会将连接转换为mapjoin,还会尽可能地合并mj*模式
因此,配置单元在默认情况下尝试将连接转换为 map-side joins . map-side连接是将两个表中较小的表完全加载到mappers内存中的连接,效率更高。通过设置 hive.auto.convert.join 如果为false,我们将禁用map-side连接并强制所有连接都是reduce-side连接,这样效率会低得多。

相关问题