Pull to refresh

Comments 15

Оригинальная реализация MapReduce была написана в Google на Си++, но так получилось, что широкое распространение парадигмы началось в индустрии только с реализации MapReduce от Apache, которая на Java.

Вероятно, дело не в языке, а в том, что Google никогда не открывал исходников MapReduce. Поэтому пришлось ждать, пока кто-нибудь воплотит идею в open-source.

Конечно же речь о самой парадигме, и путях прихода её в индустрию. Но так уж получилось, что в 2004 году речь шла о Си++ реализации в Google, а в 2006 Hadoop был выпущен с Java реализацией. Вполне, даже, допускаю, что Яндекс свою Си++ реализацию написл примерно в тот же временной период.
Но, к сожалению, ни Google, ни Яндекс, не опубликовали Си++ реализации, и народу оставалось играться на Java. (Вы только представьте себе, какой другой, «более лучшей» была бы индустрия HPC/BigData если бы изначально у народа были бы доступны C++ библиотеки для масштабирования bigdata решений. Но, история не терпит сослагательного наклонения, и мы рабоиаем на чем работаем)
Как известно, «хороша ложка к обеду», и, по счастливому стечению обстоятельств, maxim_babenko из Яндекса сегодня опубликовал описание их системы MapReduce https://habrahabr.ru/company/yandex/blog/311104/
Только «хороша ложка к обеду» вроде не про MapReduce? В том смысле, что вроде бы MapReduce «уже все»?
Почему всё? Слухи и смерти MapReduce слегка преувеличены. И пока за ним такие большие игроки, как Яндекс, пусть и с изменениями и улучшениями, парадигма будет жить.

Здесь же («хороша ложка к обеду») речь шла про то, как плотно пошли статьи, моя — вчера, и из Яндекса сегодня. Что, опять же, свидетельствует о том, что технология еще актуальна и о ней говорят и её применяют.
И, раз пошел такой разговор, а почему, кстати, вы (Гугл) не опубликовали эту библиотеку ни тогда ни сейчас?
вы (Гугл)

Мои комментарии выражают только моё личное мнение и не имеют никакого отношения к мнению компании.


почему не опубликовали эту библиотеку ни тогда ни сейчас?

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

Потому что это не библиотека, это сервис. Чтобы он хорошо работал и был удобным, нужен огромный кусок инфраструктуры: планировщик задач, система управления ресурсами, система развёртывания приложений, распределённая файловая система, системы мониторинга и половина стандартной библиотеки впридачу.


Вот, кстати, нет. Это именно библиотека, которая может основываться на инфраструктуре (определенная распределенная файловая система, или развертывание приложений), а может быть и абстрагиована от всего этого. Как я покажу в остальных статьях серии, MapReduce остаётся MapReduce дже если у него вынуть GFS или HDFS и пользовться другими средствами доставки данных в кластере.

(В-общем и целом, если бы Google выложил MapReduce только как библиотеку, то сообщество нашло бы чем заменить инфраструктуру. Но чего уж тут. Нет так нет)
Это именно библиотека

Ну понятно, что любой сервис можно оформить в виде библиотеки и исполняемого файла, абстрагировать библиотеку от внешних зависимостей, выделив интерфейсы для коммуникации и определив семантику и ожидаемую производительность каждого вызова каждого метода каждого интерфейса. Проблема в том, что если это не было сделано изначально, то обычно проще переписать всё с нуля, чем сделать такой рефакторинг. К тому же, чтобы правильно выделить абстракции, обычно нужно иметь в виду как минимум несколько возможных реализаций каждой абстракции (хотя бы три).


Далее, чтобы пользователь мог использовать эту библиотеку, нужно попросить его реализовать все зависимости в соответствии с их семантикой. Это много работы.


В теории это может работать, но на практике не выглядит особо хорошей инвестицией времени для компании, у которой много другой работы.

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

Предположим, что мы в полном соответствии с примером в статье хотим посчитать повторения слов в следующем известном шуточном стихотворении:
Ехал Гитлер через Гитлер
Видит Гитлер Гитлер Гитлер
Сунул Гитлер в Гитлер Гитлер
Гитлер Гитлер Гитлер Гитлер

Размер чанка примем равным 8 байтам, и для простоты будем считать, что текст у нас в какой-то однобайтовой кодировке, поэтому 1 байт = 1 знак, и вместо переносов строки — обычные пробелы.

Если я все правильно понимаю, то это значит, что мапперы на входе получат следующее разбиение:
0:  "Ехал Гит"
1:  "лер чере"
2:  "з Гитлер"
3:  " Видит Г"
4:  "итлер Ги"
5:  "тлер Гит"
6:  "лер Суну"
7:  "л Гитлер"
8:  " в Гитле"
9:  "р Гитлер"
10: "Гитлер Г"
11: "итлер Ги"
12: "тлер Гит"
13: "лер"

Теперь мапперы прогоняют свой алгоритм для каждого чанка и выдают следующие ключи:
0:
	"Ехал": 1
	"Гит": 1
1:
	"лер": 1
	"чере": 1
2:
	"з": 1
	"Гитлер": 1
3:
	"Видит": 1
	"Г": 1
4:
	"итлер": 1
	"Ги": 1
5:
	"тлер": 1
	"Гит": 1
6:
	"лер": 1
	"Суну": 1
7:
	"л": 1
	"Гитлер": 1
8:
	"в": 1
	"Гитле": 1
9:
	"р": 1
	"Гитлер": 1
10:
	"Гитлер": 1
	"Г": 1
11:
	"итлер": 1
	"Ги": 1
12:
	"тлер": 1
	"Гит": 1
13:
	"лер": 1

Наверное, вы уже поняли, что меня смущает, но я доведу мысль до конца. Теперь, перед тем, как передать данные в reducer-ы, платформа выполняет группировку по ключу.
"Видит": 1
"Г": 1, 1
"Ги": 1, 1
"Гит": 1, 1, 1
"Гитле": 1
"Гитлер": 1, 1, 1, 1
"Ехал": 1
"Суну": 1
"в": 1
"з": 1
"итлер": 1, 1
"л": 1
"лер": 1, 1, 1
"р": 1
"тлер": 1, 1
"чере": 1

Ну и наши reducer-ы просто суммируют единички для каждого слова.

Мне кажется проблемой то, что мы, по моему пониманию, решили не ту задачу, которую хотели. Мы получили вот это:
"Видит": 1
"Г": 2
"Ги": 2
"Гит": 3
"Гитле": 1
"Гитлер": 4
"Ехал": 1
"Суну": 1
"в": 1
"з": 1
"итлер": 2
"л": 1
"лер": 3
"р": 1
"тлер": 2
"чере": 1

А хотели (я хотел) вот это:
"Видит": 1
"Гитлер": 12
"Ехал": 1
"Сунул": 1
"в": 1
"через": 1

Если варьировать размер блока, результаты тоже будут дико гулять, и все еще не иметь ничего общего с правильным ответом, полученным традиционным способом. Что я понял неправильно? Почему так получается? Как с таким бороться?
А зачем делать размер чанка 8 байт? Почему весь исходный текст («файл») не был чанком?
Ну, у нас же big data, правильно? Пусть исходный текст является повторением вот той строки 1 триллион раз, т.е. итоговый размер структуры будет составлять 1.09e+14 байт, или порядка 99 ТиБ. Т.е. в память мы эту строку запихнуть точно не сможем. При этом ожидаемый выхлоп алгоритма должен быть
"Видит": 1000000000000
"Гитлер": 12000000000000
"Ехал": 1000000000000
"Сунул": 1000000000000
"в": 1000000000000
"через": 1000000000000

А по факту будет отчет с разными комбинациями слов, разрезанных пополам в произвольных позициях. И даже если увеличить размер чанка до, например, 4 ГиБ, которые поместятся в памяти произвольной ноды, у нас все равно есть слова на границах, которые были разрезаны. Или я все же упускаю что-то в понимании?
БигДата в данном случе не бесконечной длины поток сознания, а большое количество файлов конечного размера (пусть и достаточно большого). При создании системы надо попытаться сбалансировать количество параллельных обработчиков, размер чанка (чем больше тем лучше, но не больше чем), и накладные расходы на планировщик (при маленьких чанках у нас не останется времени на полезную работу — одни функции планировщика и мастера).
Здравый смысл подсказывает, что если входные данные расположены в файлах, то проще всего отдавать отдельному обработчику на стадии отображения файл полностью.
(Главное, не пытаться запихнуть весь файл в память, ни к чему это.)
Ну и я тут говорю не о бесконечном потоке сознания, а о вполне конечном огромном файле размером в 99 ТиБ, который содержит какой-то текст — возможно, про Гитлера, возможно, Lorem ipsum, или вообще краткое содержание Википедии.

Просто верно ли я понимаю, что mapreduce не приспособлен к работе с неструктурированными данными? И в данном конкретном случае, нельзя получить корректный результат без предварительной обработки и разбиения мегафайла на записи приемлемого размера, которые могут поместиться в память? И при этом мы можем выбрать только такой размер чанка, который кратен размеру записи?
Давайте вернемся к основам: парадигма MapReduce работает в пакетном (batch) режиме. Пока текущая стадия не закончит обработку, следующая стадия конвейера не запустится. Для очень больших объемов чанка вы такого не хотите. Вы хотите много, разумного размера чанков, или, если нет возможности нарезать данные на чанки, то вы хотите поточный режим. Это уже не MapReduce, т.е. как минимум не его оригинальная реализация.
Если нужна поточная реализация (и вы пишете на Java) то вам в Spark Streaming или Apache Storm. Если вы про Си++, то увы, и MapReduce реализации у вас нет, не говоря про streaming реализацию (ждем публичного релиза Yandex YT как-нибудь в будущем, тогда появится всё). Если же вы про InterSystems Caché ObjectScript, то продолжайте читать данную серию. (Вторая часть, третья часть) Там будет и поточный режим.
Sign up to leave a comment.