Я деякий час читав про MapReduce - але те, що не можу зрозуміти, це те, як хтось прийме рішення використовувати (або не використовувати) MapReduce.
Я маю на увазі, які схеми проблем сигналізують про те, що MapReduce може бути використаний.
Я деякий час читав про MapReduce - але те, що не можу зрозуміти, це те, як хтось прийме рішення використовувати (або не використовувати) MapReduce.
Я маю на увазі, які схеми проблем сигналізують про те, що MapReduce може бути використаний.
Відповіді:
Це в основному проблеми, які величезні, але не важкі. Продавець подорожей суттєво залежить від відстані між будь-якою парою міст, тому, хоча його можна розділити на багато частин, часткові результати не можна рекомбінувати, щоб вийшло глобальне оптимальне рішення (ну, мабуть, ні; якщо ви знаєте спосіб, будь ласка, подайте заявку на медаль «Поля» зараз).
З іншого боку, підрахунок частот слів у гігантському корпусі є тривіально розділеним та тривіально рекомбінантним (ви просто складете вектори, обчислені для сегментів корпусу), тому зменшення карт - очевидне рішення.
На практиці більшість проблем, як правило, легко рекомбіновані, ніж ні, тому рішення про те, чи слід паралелізувати завдання чи ні, має більше спільного з тим, наскільки це завдання величезне, і менше з тим, наскільки воно важке.
Чи можна проблему ефективно вирішити за допомогою розподілених обчислень?
Якщо відповідь на це питання так, то у вас є проблема кандидата для MapReduce. Це тому, що модель проблеми піддається розбиттю на менші поодинокі проблеми.
Ваше завдання: розібрати цю книгу
Приклад добре допомагає ілюструвати це. У вас є великий документ ( Moby Dick від Herman Melville ), і ваше завдання полягає в проведенні частотного аналізу всіх вживаних в ньому слів.
Послідовний підхід
Це можна зробити послідовно, отримавши свою найшвидшу машину (у вас багато лежить) і перебігаючи текст від початку до кінця, підтримуючи хеш-карту кожного знайденого слова (ключа) та збільшуючи частоту (значення) кожен раз ти розбираєш слово. Простий, прямий і повільний.
Підхід MapReduce
Підходячи до цього з іншого погляду, ви зазначаєте, що всі ці запасні машини лежать навколо, і ви могли розділити це завдання на шматки. Дайте кожній машині блок 1 Мб тексту для розбору на хеш-карту, а потім зіставте всі хеш-карти з кожної в єдиний результат. Це багатошарове рішення MapReduce.
Процес читання рядка тексту та збирання слів - це фаза Map (ви створюєте просту карту, що представляє слова у рядку з їх частотою 1,2,3 тощо), тоді фаза зменшення - це коли кожна машина згортає свій рядок карти в єдину сукупну карту.
Загальне рішення виходить із подальшої фази зменшення, де всі сукупні карти об’єднуються (це слово знову) у підсумкову карту. Трохи складніші, масово паралельні та швидкі.
Підсумок
Отже, підсумовуючи, якщо ваша проблема може бути представлена ключами, значеннями, сукупними операціями над цими значеннями ізольовано, то у вас є проблема кандидата для MapReduce.
Шаблон MapReduce взято зі світу функціонального програмування. Це процес паралельного застосування чогось, що називається катаморфізмом, над структурою даних. Функціональні програмісти використовують катаморфізми майже для кожного простого перетворення або узагальнення.
Якщо припустити, що ваші дані є деревом, вирішальним фактором є те, чи можна обчислити значення для вузла, використовуючи лише дані, що містяться в цьому вузлі, та обчислені значення для його дітей.
Наприклад, ви можете обчислити розмір дерева, використовуючи катаморфізм; ви б обчислили суму обчислених значень для всіх дітей плюс один.
Цей WPI - програми зменшення карт (ppt) можуть вас зацікавити. У ньому обговорюються різні застосунки ЗМ, і як один із обговорюваних випадків показано, як, використовуючи 100 екземплярів EC2 та 24 години, New York Times змогла конвертувати 4 ТБ відсканованих статей у 1,5 ТБ PDF-документів.
Інший набір прикладів, коли MR допомагає прискорити продуктивність, знаходиться за адресою: Астер - Зменшення SQL Map показує деякі тематичні дослідження технології зменшення SQL-карт, включаючи виявлення шахрайства, трансформації та інші.
Карта / зменшення - це специфічна форма певного виду алгоритму. Ви використовуєте його для перетворення одного величезного набору даних в інший набір даних. (Набір даних результатів може бути або не бути величезним.) Якщо ви не хочете встановити статичний вихід даних у результаті статичного введення даних, то Map / Reduce не є доцільним. Map / Reduce може легко сказати вам, скільки Джона Сміта знаходиться в телефонній книзі Манхеттена, але це не дуже підходить для створення веб-сервера.
Те, як працює карта / зменшити:
Результатом є те, що список пар (k1, v1) перетворюється на список (v3) s. (Звичайно, значення "v3" може бути композитом, що включає k2, який можна визначити рівним k1.)
Отже, ви використовуєте це:
Якщо у вас є стільки даних, щоб почати з того, що запускати все це послідовно через один або два сервери буде потрібно занадто багато часу, і
Ви можете уявити вихідні дані як список значень або пар ключових значень (як правило, не надто важко, коли ви пам'ятаєте, що "ключ" означає лише "унікальну мітку"), і
Якими б не були стосунки, ви впевнені, що кожен фрагмент вхідних даних впливає лише на вихідне значення для одного ключа виводу.
Якщо ваші дані можуть бути оброблені послідовно одним сервером, то, оскільки це є домінуючою обчислювальною парадигмою (ті сервери побудовані і програмісти проходять навчання), використовуйте один сервер.
Етап карти повинен розділити всі вхідні дані за допомогою вихідного ключа. Він не повинен створювати вихідне значення, пов’язане з ключем виводу (це робиться на етапі зменшення), але він повинен однозначно призначити кожній парі значення вхідного ключа, щоб внести щонайменше одне значення вихідного ключа. Якщо дані занадто взаємопов'язані, зменшення карт може не впоратися з проблемою. З іншого боку, можливо, вам потрібно використовувати кілька раундів карти / зменшення.
Якщо ви не можете зрозуміти, як перетворити трансформацію даних у карту / зменшити, то, звичайно, це не є рішенням.
Існує справжнє мистецтво з'ясувати, чи проблема може бути розкладена на щось, з чим може впоратися Map / Reduce. Наприклад, v1 і v2 можуть взагалі не бути в наборах даних вводу або виводу. Якщо ви просто хочете порахувати унікальні елементи у вхідних даних, то k1 = k2 = елемент, а v1 = v2 = 1 або 0 або дійсно будь-що. Зменшення просто виробляє v3 як суму числа k2, яке було задано.
Тому важко сказати напевно, що трансформацію даних неможливо здійснити за допомогою Map / Reduce, але наведене вище дає вам деякі орієнтири.
MapReduce працює над будь-якою проблемою, яка складається з рівно двох функцій на деякому рівні абстракції. Перша функція застосовується до кожного з елементів вхідного набору, а друга функція агрегує результати.
Отже, щоразу, коли ви хочете отримати (1) результат від (n) входів, і всі входи можна перевірити / використати (1) функцією, ви можете використовувати MapReduce. Знову ж таки, це на певному рівні абстракції. Функція (1) може бути деякою функцією групування, яка перевіряє вхід і вирішує, яку з кількох інших функцій використовувати.
Це корисно, коли ви не знаєте заздалегідь, скільки будете мати вкладених коштів, коли вам потрібно поділитись стриманими "одиницями" роботи або коли ви хочете, щоб одне повернення представляло весь результат (IE, який працює з п'ять тисяч одиниць тестів , і якщо менше x% не вдасться, поверніть успіх).
Більшість відповідей тут здаються деякими варіантами пояснення того, що зменшення карти робить, що є дійсним. Але відповісти на питання, який саме шаблон буде сигналізувати, де ви могли б використовувати зменшення карти, насправді цим не вирішено.
Якщо наївна, нефункціональна реалізація проблеми, на яку ви розглядаєте, передбачає перекидання чимось, а потім оновлення чогось поза циклом з деяким станом зсередини циклу, швидше за все, у вас є щось, що порти добре зменшити. Особливо, якщо ви можете узагальнити оновлення центрального стану до функції, яка працює лише з двома параметрами і може гарантувати, що ця функція є комутативною та асоціативною.
Причина, за якою ви хочете використовувати зменшення карти, якщо це правда, двічі: 1) це може бути трохи чистішим та легшим для тестування та налагодження, якщо ви розбиєте речі на карту та зменшите функції. 2) Функції зменшення карти без стану і можуть запускатися одночасно, що прискорює роботу, якщо у вас є кілька cpus і щось на зразок hadoop або spark, що використовує цю функцію для запуску речей у кластері.
Це добре, якщо ви перебираєте багато речей, але пробіг може змінюватись залежно від того, наскільки складна ваша карта / зменшується. Цілком звичайно опинятися послідовним зменшенням ланцюга або дерева карт, де врешті-решт все ще є вузьким місцем на якомусь складному кроці скорочення в кінці ланцюга. Наприклад, багато алгоритмів графіків складно масштабувати ефективно з просто зменшенням карти.
Найпростіший приклад, який добре працює зі зменшенням карти, - це підрахунок матеріалів, що є дуже дешевим зменшенням. Ось чому кількість слів є часто використовуваним прикладом для зменшення карти. Ви можете дуже очікувати лінійної масштабованості для продуктивності за допомогою цього використання: кожен доданий процесор робить це швидше.
Якщо ви займаєтесь великим функціональним програмуванням, ви починаєте стикатися з ситуаціями, які вимагають загальної карти та зменшення. Ви, мабуть, навіть бачите їх в імперативному програмуванні, але не розпізнаєте їх за маскою циклів і акумуляторів.
Як приклад одного, який з’явився для мене нещодавно, я працюю над аналізатором в Haskell. Щоб перевірити свій аналізатор, я прокачую список фрагментів рядків через аналізатор, і тоді я хочу отримати одну нитку, яку я можу вивести з результатів, щоб побачити, чи правильно вона розібрана. Так виглядає так:
--my initial set of test data, a list
tests = ["string1", "string2", "string3", ...]
--Map Step: turn strings into parsed results
--note the type, which demonstrates the map
applyParser :: [String] -> [Token]
--The actual function
applyParser input = map parser input
--Second map, turn tokens into output
showTokens :: [Token] -> [String]
showTokens t = map show t
--Reduce step, concat the results
combineResults :: [String] -> String
--In haskell, reduce is the foldl function, which takes an operation to fold with, a starting element, and a list to fold on
combineResults strings = foldl concat "" strings
--Finished program
testParser = print (combineResults(showTokens(applyParser tests)))
Звичайно, це просто педагогічно. Мій реальний код виглядає трохи по- іншому, і використовує кілька внутрішніх функцій (наприклад , fold concat
не потрібно , так як Haskell вже включає в себе , unlines
що робить [String]->String
). Моя головна думка полягала в тому, що я не очікував використання карти / зменшення, коли я починав, вона просто підходила до моїх потреб. Я хотів зробити деякі речі зі списками, а потім перетворити свій список в єдиний елемент виводу. Використання карти / зменшення виникло природним шляхом.
Обробка рядків (як синтаксичний аналіз) - це дуже очевидне використання скорочення карти, картографування - це застосування різних перетворень на вхідному тексті, а зменшення - повернення тексту результату знову як вихід. Аналогічно, компілятор може бути подібним, використовуючи складки, щоб перетворити потік елементів абстрактного синтаксичного дерева в кращу форму (оптимізацію).
Це паралельно відключити?
Будь-яка паралельна проблема, по суті, полягає у зіставленні та складенні; навпаки, крок карти по своїй суті є паралельним (і крок складання може бути, залежно від структури, над якою він складається), тому це властивість двонаправлене.
Скажімо, ви шукаєте кластер серверів, і ніхто не може відповісти на той момент. Що зробить mapReduce, оскільки він не зміг отримати доступ до цього вузла дерева до більшої Map - це перенесе його на потім і виконає Map або Reduce. По суті, він намагається гарантувати, що вся інформація доступна з непередбачуваністю програмного та апаратного забезпечення в середовищах.
Ось основні питання, які я використовую, щоб перевірити рішення про використання (або не використання) MapReduce.
Чи проблема, яку я намагаюся вирішити, розкладається на операцію Map and Reduce?
по суті, це загальний шаблон "розділити і перемогти", щоб рішення для розподілу обчислень можна було записати загально.
простий приклад - це як великий документ. проблема полягає в тому, що ви хочете порахувати кількість букв у цьому документі. замість того, щоб працювати на одній машині, ви можете розбити її на масив усіх слів у документі. то ви можете обробити кожне слово окремо, а результати знову разом.
шаблон є корисним, тому що коли ви отримаєте загальну карту / зменшите роботу, ви можете вирішити будь-яку проблему за допомогою того самого програмного шару, вам просто потрібно висловити свою проблему в плані.