Hive: лучший подход для использования большого количества небольших XML-файлов

Я хотел бы получить советы относительно наилучшего подхода к хранению моих данных в HDFS и дальнейшему извлечению из них значений с помощью SQL через Hive.

Я получаю много файлов в формате XML, в основном десятки тысяч в день. Каждый файл имеет размер около 10 КБ и подчиняется заданной схеме XSD. В настоящее время у меня более 120 ТБ этих XML-файлов, хранящихся в файловой системе.

Мне было интересно поместить все эти файлы XML в HDFS, чтобы предложить интерфейс SQL для некоторых приложений, выполняющих реляционные запросы к данным.

Как вы думаете, какие ключевые технологии мне потребуются для создания этого решения?

Для эффективной обработки мне, возможно, потребуется преобразовать эти XML-файлы в формат, более подходящий для Hadoop (например, RCfile или ORC), и сохранить их в HDFS. Проблема в том, что схема этих файлов со временем должна измениться. Характер моих данных, кажется, выигрывает от разделения (т. е. по дате/времени или состоянию). Кроме того, я не знаю, является ли сжатие данных хорошей идеей.

Вот пример содержимого, которое у меня есть в одном файле XML:

<invoice schema_version="1.1">
  <general id="123456798">
    <creationdate>2016-03-21 16:25:09-03:00</creationdate>
  </general>
  <buyer id="11">
    <name>The Buyer</name>
    <address>
      <street>1st St</street>
      <city>Los Angeles</city>
      <state>CA</state>
    </address>
  </buyer>
  <seller id="22">
    <name>The Seller</name>
    <address>
      <street>2nd Ave</street>
      <city>Miami</city>
      <state>FL</state>
    </address>
  </seller>
  <items>
    <product id="123">
      <name>Blue Pen</name>
      <price>1.50</price>
      <quantity>4</quantity>
      <subtotal>6.00</subtotal>
    </product>
    <product id="456">
      <name>White Board</name>
      <price>5.20</price>
      <quantity>2</quantity>
      <subtotal>10.40</subtotal>
    </product>
  </items>
  <amount>
    <products>16.40</products>
    <shipping>2.35</shipping>
    <total>18.75</shipping>
  </amount>
</invoice>

Таким образом, я хотел бы выполнять SQL-запросы, подобные этим:

SELECT general.creationdate, buyer.name, amount.total
FROM invoice
WHERE general_id = '123456798';

SELECT count(*) AS qty, sum(amount.total) AS total
FROM invoice
WHERE general.creationdate >= '2016-03-01'
GROUP BY seller.address.state;

SELECT b.name, avg(b.price) AS avg_price, sum(b.quantity) AS sum_quantity
FROM invoice a
  JOIN invoice_items b ON (...)
WHERE a.buyer.address.state = 'CA'
GROUP BY b.name
ORDER BY sum_quantity DESC;

Заранее спасибо!


person Rodrigo Hjort    schedule 21.03.2016    source источник


Ответы (1)


Вы можете написать xslt-файл для перевода входящих XML-файлов в формат csv и применить его к своим файлам, например. используя потоковое задание:

hadoop jar hadoop-streaming.jar \
    -mapper 'xsltproc file.xslt -' -file file.xslt \
    -input /path/to/your/xmls \
    -output /path/to/resulting/files

посмотрите на https://github.com/whale2/iow-hadoop-streaming, если вы хотите использовать avro или паркет вместо простого текста, эта библиотека также может обрабатывать несколько выходных данных, поэтому вы можете сохранять каждую таблицу в отдельной папке (и, конечно, в подпапках, если вы хотите разбить на разделы).

Затем просто создайте внешнюю таблицу в улье для ваших результирующих файлов и сделайте свои sql-запросы.

если ваша схема изменится, вы можете просто изменить xslt-файл.

добавить: чтобы это заработало, вы должны удалить новые строки из входных xml-файлов или написать оболочку (см. http://www.science.smith.edu/dftwiki/index.php/Hadoop_Tutorial_2.1_--_Streaming_XML_Files)

upd Вы должны написать 1 xslt, чтобы создать всю запись в файле следующим образом:

header\tval1,val2,val3
details\tval1,val2,val3,val4

затем добавьте опцию -outputformat net.iponweb.hadoop.streaming.io.ByKeyOutputFormat к вашей команде, и вы получите разные файлы для каждого ключа.

А как насчет профита от хаупа в этой задаче - распределенная обработка, если у вас мало данных, то хауп не нужен

person fi11er    schedule 22.03.2016
comment
Мне удалось создать 2 отдельных файла XSLT, header.xsl и details.xslt, которые из одного файла invoice.xml создают соответственно header.csv и details.csv. Я протестировал его, запустив xsltproc напрямую, поэтому я мог создать сценарий оболочки для автоматизации этого. В этом случае, какова основная причина запуска этого «преобразования XML в CSV» через потоковую передачу Hadoop? - person Rodrigo Hjort; 02.04.2016
comment
После того как я создал CSV-файлы и загрузил их на пограничный узел Hadoop, потребовалось много времени, чтобы загрузить их в HDFS, поскольку я использовал hadoop fs -copyFromLocal. В этом ли смысл использования этого подхода Hadoop Streaming? - person Rodrigo Hjort; 08.04.2016