Hive Server 2 / Beeline не возвращает строки с INNER JOIN в таблице Hive on HBase

TL; DR Я могу выполнить запрос Hive с помощью INNER JOIN в таблице HBase в командной строке Hive (Hive Server 1) и вернуть правильные строки. Однако тот же запрос в командной строке Beeline (Hive Server 2) не возвращает строк. Я могу нормально выполнить INNER JOIN на обычном Hive на таблицах 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'

Я создал Hive на таблицах 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'
);

Все следующие запросы успешно работают в Hive (Hive Server 1) и Beeline (Hive Server 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'); 

Эти запросы возвращают только строки в Hive (Hive Server 1). Однако в Билайне (Hive Server 2) они возвращают 0 строк:

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, потому что это не привлекло никакого внимания. Я отправлю ответ здесь, если он его получит.


person Matthew Moisen    schedule 23.05.2016    source источник


Ответы (2)


Это не подходящее решение, но оно работает.

set hive.auto.convert.join = false

Что делает hive.auto.convert.join?

Если для hive.auto.convert.join задано значение true, оптимизатор не только преобразует объединения в сопоставления, но и максимально объединяет шаблоны MJ *.

Итак, hive по умолчанию пытается преобразовать объединения в map-side joins. Соединение на стороне карты - это соединение, при котором меньшая из двух таблиц полностью загружается в память преобразователя и является гораздо более эффективным. Устанавливая для hive.auto.convert.join значение false, мы отключаем соединения на стороне карты и заставляем все соединения быть соединениями на стороне сокращения, что гораздо менее эффективно.

person Matthew Moisen    schedule 25.05.2016

Мы нашли это решение случайно, но, возможно, стоит изучить его. В одной среде beeline выдавал OutOfMemory ошибку и зависал. Системные администраторы увеличили объем памяти, выделенной HS2, и после этого INNER JOIN заработал нормально. Однако это тревожит, потому что Билайн не выдавал ошибок, а просто не возвращал строк.

Увеличение памяти в среде MapR5.1 / Hive-1.2 с 4 ГБ до 8 ГБ помогло. Однако в среде MapR4.0.1 / Hive-0.13 это не сработало.

In hive-env.sh:

export HADOOP_HEAPSIZE=8000
person Matthew Moisen    schedule 25.05.2016