MapReduce:Алгоритмы и приемы использования
3
4
• Задача:– Много (очень много) данных, которые надо обработать
• Решение:
5
Проблемы распределенных систем • Обмен данными требует синхронизации• Ограничение пропускной способности• Частичный отказ нод • Зависимости между процессами• Распределенное хранение данных
6
7
Input data
MapperMapper Mapper
Shuffle & Sort
ReducerReducer
Output data
MapReduce• Большие блоки данных
(обычно по 64Мб)• «Разделяй и властвуй»• Каждый блок состоит из
пар key/value• Эффективное
использование кластера
8
Map и Reduce:• Map
– Выполняет функцию для каждого значения в наборе данных
– Создает новый набор key/value
• Reduce– Агрегирует values для каждого key– Создает новое value
square x = x * xmap square [1, 2, 3, 4, 5]return [1, 4, 9, 16, 25]
sum = for each value in array, sum += sumreduce sum[1, 2, 3, 4, 5]return 15
9
Примеры задач на MapReduce:• Распределенный grep и sort• Анализ web логов, статистика• Построение поискового индекса• Кластеризация / классификация• Научные проекты (БАК)
10
Distributed File System (DFS)• Большие файлы, read/append only• Большие блоки (64Мб)• Блоки распределены и реплицируются• Master отслеживает расположение всех блоков• Последовательное чтение данных
– seeks are evil!
11
NameNode
daemon
JobTracker
daemon
SlaveNode
datanodeLinux FS
SlaveNode
datanodeLinux FS
task tracker task tracker
Apache Hadoop
• Open-source реализация MapReduce
• Фреймворк для распределенных приложений
• Java API, streaming
12
WordCountclass Mapper method Map(docid a, doc d) for all term t ∈ doc d do Emit(term t, count 1)
class Reducer method Reduce(term t, counts [c1, c2, . . ]) sum ← 0 for all count c ∈ counts [c1, c2, . . ] do sum ← sum + c Emit(term t, count sum)
Doc1
MapperMapper Mapper
Shuffle & Sort
ReducerReducer
A {6}
Doc2 Doc3 Doc4
B {9}
A{1} B{3} A{2} A{3} B{2} B{4}
A [1,2,3] B [3,2,4]
13
Local Aggregation• Проблема:
– Избыточный объем данных от mapper– Пример: стоп-слова
• Решение: Combiner– “Mini-reducer” после map, но перед shuffle и sort– Уменьшает размер промежуточных данных– Вызывается произвольное негарантированное
количество раз
WordCount, Combiner
class Combiner method Combine(term t, [c1, c2,..]) sum = 0 for all count c in [c1, c2,..] do sum = sum + c Emit(term t, count sum)
14
Doc1
MapperMapper Mapper
Shuffle & Sort
ReducerReducer
A {5}
Doc2 Doc3 Doc4
B {10}
A{1} B{3} A{2} A{2} B{3} B{4}
A [1,4] B [3,7]
Combiner Combiner Combiner
A{1} B{3} A{4} B{7}
15
Local Aggregation• In-Mapper Combining
– Агрегация данных внутри маппера– Контроль со стороны пользователя– Более эффективен, чем обычный
Combiner– Уменьшает количество
промежуточных данных– Out-of-Memory (flush)
class Mapper method Initialize H ← new AssociativeArray
method Map(docid a, doc d) for all term t ∈ doc d do H{t} ← H{t} + 1 method Close for all term t ∈ H do Emit(term t, count H{t})
16
Secondary Sort• Проблема:
– Ключи в reducer отсортированы– Но порядок значений - нет
• Решение:– Использовать композитный ключ (key + value)– Переопределить Partitioner– Переопределить Comparator
17
Map-Side Join• Алгоритм:
– Ассоциативный массив в mapper
– Ключ массива – join key– Lookup в массив,
используя join key
• Недостаток:– Out of Memory
Large data
Mapper Mapper
Output data
Small data
HashMap HashMap
18
Reduce-Side Join• Алгоритм
– Map по обоим наборам данных
– Выбрать join key– Добавить tag в value для
различия типа данных– В reduce все значения
сгруппированы по join key
Data Set 1
Mapper
ReducerReducer
Output data
MapperMapperMapper
Data Set 2
19
Обратный индекс (Inverted Index)
Words Docs
Word_1 Doc_1
Word_2 Doc_1, Doc_2
Word_3 Doc_1, Doc_3, Doc_4
Word_4 Doc_2, Doc_5
Word_5 Doc_5
Docs Words
Doc_1 Word_1 Word_2 Word_3
Doc_2 Word_2 Word_4
Doc_3 Word_3
Doc_4 Word_3
Doc_5 Word_4 Word_5
20
Обратный индекс• Mapper
– Для каждого терма t из документа d создаем пару key/value
• Все key/value сортируются и группируются по ключу
• Reducer– Для каждого слова мы получаем
все его вхождения в документы
class Mapper Map(docid n, doc d) H ← new AssociativeArray for all term t ∈ doc d do H{t} ← H{t} + 1 for all term t ∈ H do Emit(term t, posting<n, H{t}>)
class Reducer Reduce(term t, postings [<n1, f1>, <n2,
f2>. . ]) P ← new List for all posting <a, f> ∈ postings [<n1, f1>,
<n2, f2> . .] do P.Add(<a, f>) P.Sort() Emit(term t, postings P)
21
WEB
Fetcher Fetcher Fetcher
HDFS / HBase
MR Job
MR Job
MR Job
MR Job
MapReduce в Поиске• Spider
• Fetcher - быстро качает интернет
• HBase - распределенная таблица с контентом и мета-данными
• MapReduce jobs
22
Hadoop, проблемы• C++ (JNI) vs Java• Тестирование задач• Debugging & Profiling задач• Неравномерность распределения данных• Борьба за ресурсы кластера• HBase
23
Hadoop в поиске, цифры• 50 млрд. документов в базе• 20 млрд. обкачанных• 6 млрд. “хороших” документов• 500 млн. новых документов в день• 300 Тб таблица в HBase• 1 Пб данных в hdfs
24
Итого:За Против
• Готовая распределенная среда• Горизонтальная масштабируемость• Обработка больших данных• Отсутствие синхронизации• Read-once, пакетная обработка• Fault tolerance из коробки
• Не подходит для real-time систем• Не все алгоритмы одинаково полезны оптимальны• Не подходит для задач, где:
Много общих данных Высокие требования к
синхронизации процессов CPU-bound операции