POST Hadoop Pig выводит URL в виде данных JSON? - PullRequest
1 голос
/ 28 июня 2011

У меня есть работа Pig, которая анализирует файлы журналов и записывает сводные данные в S3.Вместо записи вывода в S3 я хочу преобразовать его в полезную нагрузку JSON и отправить его в URL.

Некоторые примечания:

  • Это задание выполняется в Amazon Elastic MapReduce.
  • I может использовать STREAM для передачи данных через внешнюю команду и загрузки их оттуда.Но поскольку Pig никогда не отправляет EOF внешним командам, это означает, что мне нужно POST каждую строку по мере ее поступления, и я не могу их пакетировать.Очевидно, что это снижает производительность.

Как лучше всего решить эту проблему?Есть ли что-то в PiggyBank или другой библиотеке, которую я могу использовать?Или я должен написать новый адаптер хранения?Спасибо за ваш совет!

Ответы [ 3 ]

4 голосов
/ 01 июля 2011

Вместо потоковой передачи вы могли бы написать UDF (поскольку do UDF обеспечивает обратный вызов finish ()) [1]

Другой подход может состоять в том, чтобы сделать POST вторым проходомданные.

  1. ваш существующий шаг PIG, который просто записывает в одно отношение в виде строк json
  2. простое потоковое задание с использованием NLineInputFormat для выполнения POST в пакетах

Я всегда предпочитаю такой подход, поскольку он разделяет проблемы и делает код PIG чистым.

Это также позволяет (на мой взгляд) упростить параметры настройки в части POST вашей работы.В этом случае (вероятно) для вас важно отключить спекулятивное выполнение в зависимости от идемпотентности вашего принимающего веб-сервиса.Помните, что ваш кластер, выполняющий лотов одновременных заданий, может также полностью убить сервер: D

например, для отправки в пакетах по 20 ...

$ hadoop jar ~/contrib/streaming/hadoop-streaming.jar \
  -D mapred.line.input.format.linespermap=20 \
  -D mapred.reduce.tasks.speculative.execution=false \
  -input json_data_to_be_posted -output output \
  -mapper your_posting_script_here.sh \
  -numReduceTasks 0 \
  -inputformat org.apache.hadoop.mapred.lib.NLineInputFormat

[1] http://pig.apache.org/docs/r0.7.0/api/org/apache/pig/EvalFunc.html#finish%28%29

1 голос
/ 03 июля 2011

Возможно, вам стоит заняться размещением данных вне Pig. Я считаю, что завернуть мою Pig в bash обычно проще, чем выполнить какой-то UDF шага обработки поста (без каламбура). Если вы никогда не хотите, чтобы он ударил по S3, вы можете использовать dump вместо store и обрабатывать стандарт для публикации. В противном случае сохраните его в S3, извлеките его с помощью hadoop fs -cat outputpath/part*, а затем отправьте с помощью curl или чего-то еще.

0 голосов
/ 21 июля 2011

Как оказалось, Pig действительно правильно отправляет EOF внешним командам, поэтому у вас есть возможность передавать все через внешний скрипт. Если не не работает, то, возможно, у вас проблема с отладкой конфигурации.

Вот как начать. Определите внешнюю команду следующим образом, используя любой интерпретатор и скрипт, который вам нужен:

DEFINE UPLOAD_RESULTS `env GEM_PATH=/usr/lib/ruby/gems/1.9.0 ruby1.9 /home/hadoop/upload_results.rb`;

Поток результатов через ваш скрипт:

/* Write our results to our Ruby script for uploading.  We add
   a trailing bogus DUMP to make sure something actually gets run. */
empty = STREAM results THROUGH UPLOAD_RESULTS;
DUMP empty;

Из Ruby вы можете группировать входные записи в блоки по 1024:

STDIN.each_line.each_slice(1024) do |chunk|
  # 'chunk' is an array of 1024 lines, each consisting of tab-separated
  # fields followed by a newline. 
end

Если это не сработает, внимательно проверьте следующее:

  1. Работает ли ваш скрипт из командной строки?
  2. При запуске из Pig, есть ли в вашем скрипте все необходимые переменные окружения?
  3. Ваши действия по загрузке в EC2 работают правильно?

Некоторые из них трудно проверить, но если какой-либо из них не работает, вы можете легко потратить много времени на отладку.

Обратите внимание, однако, что вы должны строго рассмотреть альтернативные подходы, рекомендованные Мэттом Келси.

...