Я довольно широко использую 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%, ввод-вывод ~ 10%).
Я пробовал играть с io.sort.mb, io.sort.factor и т. д., но это почти всегда усугубляло ситуацию. Итак, теперь я использую настройки Hadoop по умолчанию (кстати, дистрибутив Cloudera). Кластер состоит из 12 узлов (8 ядер), по 24 ГБ ОЗУ и 2 ТБ на диске каждый, настроен на 8 картографов, 8 редукторов (6/6 на namenode).
Я также пытался создать временную таблицу в виде сжатого файла последовательности с помощью INSERT INTO SELECT, но эта INSERT заняла слишком много времени...
У меня есть подозрение, что может быть что-то не так с самим рабочим процессом, а не только с кластером/конфигурацией.
Любые советы с радостью приветствуются.