Потоковая передача Python Hadoop, проблемы вторичной сортировки

#algorithm #sorting #hadoop #mapreduce #hadoop-streaming

#алгоритм #сортировка #hadoop #mapreduce #потоковая передача hadoop

Вопрос:

Здесь новичок в Hadoop. У меня есть несколько журналов пользовательских событий, подобных этому, с идентификатором пользователя и меткой времени, упорядоченными случайным образом:

 userid  timestamp           serviceId
 aaa    2012-01-01 13:12:23 4
 aaa    2012-01-01 12:11:52 3
 ccc    2012-01-03 08:13:07 3
 bbb    2012-01-02 02:34:12 8
 aaa    2012-01-02 01:09:47 4
 ccc    2012-01-02 12:15:39 4
  

Я хочу получить промежуточный результат, отсортированный по идентификатору пользователя, а затем по метке времени, как показано ниже:

  aaa    2012-01-01 12:11:52 3
 aaa    2012-01-01 13:12:23 4
 aaa    2012-01-02 01:09:47 4
 bbb    2012-01-02 02:34:12 8
 ccc    2012-01-02 12:15:39 4
 ccc    2012-01-03 08:13:07 3
  

так что это может быть легко проанализировано моим редуктором.

Конечная цель — вычислить, как пользователь потратил свое время на разные сервисы (serviceIds). Возможно ли это с помощью потоковой передачи Python Hadoop? Если нет, то какой лучший подход вы бы предложили? Большое спасибо!!

Ответ №1:

В вашем mapper вы можете userid использовать как ключ, timestamp а serviceId также как значения, отсортированные по timestamp (для выполнения операции сортировки я предполагаю, что все строки для каждого пользователя могут поместиться в основной памяти).

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

Если на пользователя приходится слишком много строк (скажем, миллионы), вы можете userId-serviceId использовать их как ключ, и после фазы сокращения у вас будет однострочный файл на единицу user-service времени, затраченного на эту службу. Если вы хотите, вы можете объединить все эти файлы с помощью getmerge

Комментарии:

1. Отлично, спасибо! Поэтому, используя либо ‘userId’, либо ‘userId-serviceId’ в качестве ключа, в основном мне нужно отсортировать значения по ‘timestamp’ в моих редукторах. Что, если я хочу, чтобы выходные данные из Mapper уже были отсортированы по метке времени до достижения Reducer? Я знаю, что могу указать пользовательский разделитель в Java (используя ‘userId-timestamp’ в качестве составного ключа, но разделяя на ‘userId’), но возможно ли это и в потоковой передаче Python? Спасибо!

2. Да, вы можете установить userid-timestamp в качестве ключа, а затем разделить, userid используя -partitioner предложение потоковой передачи hadoop. Ознакомьтесь с этим примером в официальной документации.