Я довольно широко использую Hive, и мне было интересно, есть ли способ улучшить следующий рабочий процесс.
Каждый вечер дамп несжатого текстового файла с разделителями табуляции из нашего кластера Oracle записывается в HDFS для обработки Hive.
Я загружаю таблицу так:
CREATE EXTERNAL TABLE ACCOUNTINGTABLE (
ts STRING,
duid STRING,
owner STRING,
hidden STRING,
lgroup STRING,
nbfiles INT,
length BIGINT,
replicas INT,
provenance STRING,
state STRING,
campaign STRING,
rlength BIGINT,
rnbfiles INT,
rowner STRING,
rgroup STRING,
rarchived STRING,
rsuspicious STRING,
name STRING,
ami STRING,
site STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
LOCATION '/user/accounting/dump';
LOAD DATA INPATH '/user/accounting/dump_REPLACEWITHTIMESTAMP.lst' INTO TABLE ACCOUNTINGTABLE;
, а затем запустите несколько учетных сводок, подобных этой, чтобы получить текстовый вывод для постобработки:
set hive.exec.reducers.max=90;
CREATE EXTERNAL TABLE ACCOUNTINGTABLE_site_project_datatype_tag (
ts STRING,
project STRING,
datatype STRING,
tag STRING,
site STRING,
duids INT,
replicas INT,
nbfiles INT,
rnbfiles INT,
length BIGINT,
rlength BIGINT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
LOCATION '/user/accounting/summary/REPLACEWITHTIMESTAMP/site_project_datatype_tag';
INSERT OVERWRITE TABLE ACCOUNTINGTABLE_site_project_datatype_tag
SELECT
'REPLACEWITHTIMESTAMP',
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){1}', 1),
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){5}', 1),
split(regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){6}', 1), '_tid')[0],
site,
count(distinct duid),
sum(replicas),
sum(nbfiles),
sum(rnbfiles),
sum(length),
sum(rlength)
from
ACCOUNTINGTABLE
where
(
ami='project.datasetnumber.physicsshort.prodstep.datatype.version'
or
ami='project.runnumber.streamname.prodstep.datatype.version'
)
group by
'REPLACEWITHTIMESTAMP',
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){1}', 1),
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){5}', 1),
split(regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){6}', 1), '_tid')[0],
site;
DROP TABLE ACCOUNTINGTABLE_site_project_datatype_tag;
Сейчас:
Средний размер файла дампа Oracle составляет около 5 ГБ (так что на самом деле не так уж много), около 250 миллионов строк. Объем резюме не превышает 1-2 МБ.
Средняя работа Hive, как упоминалось выше, занимает около часа. Фаза картирования продвигается очень хорошо и составляет около 100% примерно через 15 минут, но затем снижение занимает почти 45 минут, показывая 100%.
Теперь мы постепенно добавляем все больше и больше различных сводок, и вскоре мы достигнем магического предела в 24 часа для обработки сводок. Наш мониторинг инфраструктуры также показывает, что загрузка узла низкая (процессор ~ 30-40%, io ~ 10%).
Я пытался играть с io.sort.mb, io.sort.factor и т. Д., Но это почти всегда ухудшало ситуацию. Так что теперь я использую Hadoop по умолчанию (кстати, дистрибутив Cloudera). Кластер состоит из 12 узлов (8 ядер) с оперативной памятью 24 ГБ и диском по 2 ТБ каждый, настроен на 8 картографов, 8 редукторов (6/6 в наборе).
Я также пытался создать временную таблицу в виде сжатого файла последовательности с INSERT INTO SELECT, но этот INSERT просто занял слишком много времени ...
У меня есть подозрение, что может быть что-то не так с самим рабочим процессом, а не только с кластером / конфигурацией.
Любой совет приветствуется.