Сравнение двух больших наборов данных с использованием модели программирования MapReduce - PullRequest
0 голосов
/ 28 ноября 2011

Допустим, у меня есть два довольно больших набора данных - первый называется «Base» и содержит 200 миллионов строк с разделителями табуляции, а второй - вызов «MatchSet», который содержит 10 миллионов строк с похожими данными табуляции.

Допустим, у меня также есть произвольная функция Match (row1, row2), а Match (), по сути, содержит некоторую эвристику для просмотра row1 (из MatchSet) и сравнения его с row2 (из Base) и определения, похожи ли оникаким-то образом.

Допустим, правила, реализованные в Match (), представляют собой пользовательские и сложные правила, а не простые совпадения строк, включающие некоторые проприетарные методы.Допустим, что Match (row1, row2) написан в псевдо-коде, поэтому реализация на другом языке не является проблемой (хотя сегодня это на C ++).

В линейной модели, то есть программе, работающей на одном гигантском процессоре - мы читали каждую строку из MatchSet и каждую строку из Base, сравнивали одну из них с помощью Match () и записывали нашу статистику совпадений.Например, мы могли бы захватить: X записей из MatchSet - сильные совпадения, Y записей из MatchSet - слабые совпадения, Z записей из MatchSet не совпадают.Мы также записали бы сильные / слабые / не значения в отдельные файлы для проверки.Ака, это своего рода вложенный цикл:

for each row1 in MatchSet
{
    for each row2 in Base
    {
        var type = Match(row1,row2);
        switch(type)
        {
            //do something based on type
        }
    }
}

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

В этот момент я довольно четко понимаю, как получить один входной сигнал от hadoop, обработатьданные с помощью функции отображения, а затем испустить результаты, чтобы уменьшить.Тем не менее, подход «вложенного цикла» сравнения двух наборов записей немного сбивает меня с толку.

Самое близкое к тому, что я прихожу к решению, заключается в том, что мне все равно придется сделать 10 миллионов записей.сравните параллельно по 200 миллионам записей, так что 200 миллионов / n узлов * 10 миллионов итераций на узел.Это самый эффективный способ сделать это?

Ответы [ 3 ]

2 голосов
/ 10 апреля 2013

Из вашего описания мне кажется, что ваша проблема может быть сколь угодно сложной и может стать жертвой проклятия размерности .

Представьте, например, что ваши строки представляют n-размерные векторы, и что ваша функция сопоставления является "сильной", "слабой" или "не совпадает" на основе евклидова расстояния между базовым вектором и вектором MatchSet.Есть отличные методы для решения этих проблем с компромиссом между скоростью, памятью и качеством приблизительных ответов.Крайне важно, что эти методы обычно имеют известные границы времени и пространства и вероятность найти точку на некотором расстоянии вокруг данного прототипа MatchSet, все в зависимости от некоторых параметров алгоритма.

Вместо того, чтобы яздесь вы можете прочитать следующее:

  1. Хеширование с учетом локальных особенностей
  2. Первые несколько обращений к Google Scholar при поиске по запросу "карта хэширования, чувствительная к местности, уменьшает".В частности, я помню чтение [Das, Abhinandan S., et al.«Персонализация новостей Google: масштабируемая совместная фильтрация в Интернете».Материалы 16-й международной конференции по всемирной паутине.ACM, 2007] с интересом.

Теперь, с другой стороны, если вы можете разработать схему, которая непосредственно поддается какой-либо форме хеширования, то вы можете легко создать ключ для каждой записи с такимхеш (или даже небольшое количество возможных хеш-ключей, один из которых будет соответствовать запросу «Базовые» данные), и проблема становится простым (-ish) масштабным соединением.(Я говорю «крупно», потому что объединение 200M строк с 10M строк довольно мало, если проблема действительно в соединении).В качестве примера рассмотрим способ, которым CDDB вычисляет 32-битный идентификатор для любого музыкального CD CDDB1, вычисление .Иногда данный заголовок может давать несколько разные идентификаторы (то есть разные CD с одинаковым заголовком или даже один и тот же CD, прочитанный несколько раз).Но по большому счету есть небольшой набор различных идентификаторов для этого заголовка.За счет небольшой репликации MatchSet в этом случае вы можете получить очень быстрые результаты поиска.

0 голосов
/ 16 сентября 2013

Это старый вопрос, но предложенное вами решение является правильным, если предположить, что ваше однопотоковое задание выполняет вычисления 200M * 10M Match ().Выполнив N пакетов (200M / N) * 10M вычислений, вы добились коэффициента N ускорения.Выполнив вычисления в фазе карты, а затем установив порог и направив результаты в редукторы Strong / Weak / No Match, вы можете собрать результаты для вывода в отдельные файлы.

Если можно использовать дополнительную оптимизацию, они 'Хотелось бы применять как однопотоковую, так и параллельную версии.Примеры включают в себя блокировку, так что вам нужно выполнить менее 200M * 10M вычислений или предварительно вычислить постоянные части алгоритма для набора соответствия 10M.

0 голосов
/ 28 ноября 2011

Отметьте Section 3.5 - Relational Joins в документе ' Интенсивная обработка текста с помощью MapReduce '.Я не вдавался в подробности, но это может помочь вам.

...