Если Вы являетесь постоянным читателем моего блога, то вполне вероятно, что Вы помните мой старый пост об этом замечательном проекте от Apache Foundation. С тех пор он развивался невероятными темпами и очень многое успело измениться, об этом я и хотел бы сегодня поделиться своими впечатлениями. В дополнение к этому планируется небольшая инструкция по развертыванию Hadoop на кластере из большого количества машин, который послужит неплохим развитием темы, начатой в посте "Hadoop для разработчика".
Что нового?
Для начала вкратце напомню что их себя представляет данный продукт, всего в нем три компонента:
- HDFS
- кластерная файловая система.
- MapReduce framework
- программная основа для построения приложений, работающих по одноименной модели.
- HBase
- нереляционная база данных.
Повторно повторяться смысла не вижу, все уже давно разложено по полочкам. Так что сразу перейдем к глобальным изменениям в проекте, произошедшим с написания вышеупомянутого поста, то есть с февраля. Сразу хочу сказать, что подробно пересказывать release notes у меня нет никакого желания, если Вам интересны все подробности о каждом bugfix'е или изменении в API, то имеет смысл почитать их в оригинале.
Наиболее значительным событием в развитии Apache Hadoop было, пожалуй, отделение HBase в отдельный проект. Какие же это повлекло последствия? С точки зрения простого смертного наиболее заметен тот факт, что HBase пропал из основного архива или репозитория Hadoop и его теперь нужно качать отдельно :) На самом же деле такое обособление лишь ускорило ее развитие, совсем недавно HBase отпраздновала свой релиз версии 0.2.0, включающий в себя массу нововведений и исправленных проблем, например язык запросов HQL был полностью заменен на jirb/jython shell, а также было добавлено кэширование данных в памяти. Помимо этого сильно изменилось API, очень рекомендую заглянуть в javadoc проекта, если Вас это интересует.
На уровне файловой системы наиболее значительным изменением стало добавление еще одного типа узлов - Secondary NameNode. Это нововведение является первым шагом на пути к устранению узких мест в системе (так называемых single points of failure). Название этого типа узлов говорит само за себя: они подстраховывают основной NameNode на случай непредвиденных сбоев. Они создают резервную копию образа метаданных файловой системы и лога транзакций (то есть всех операций с файлами и директориями в HDFS) и периодически ее обновляют. Полноценного автоматического восстановления системы они в случае сбоя на сервере с NameNode они на данный момент не обеспечивают, но сохранность данных на случай, скажем, разрушившегося RAID обеспечить могут.
MapReduce framework тоже несомненно развивается и дорабатывается, но каких-либо особо выдающихся изменений в нем не произошло: появляются дополнительные возможности, исправляются ошибки, снимаются те или иные ограничения. В общем все идет своим чередом.
Поднимаем кластер
ВНИМАНИЕ!
Перед продолжением чтения этого раздела, настоятельно рекомендуется прочитать статью о запуске псевдо-кластера из одного компьютера.
Для начала нам понадобится некоторое количество компьютеров (хотя если у Вас серьезные намерения, то лучше все же гордо называть их серверами, а для "побаловаться" сойдут и обычные рабочие станции с Linux). Конкретное количество на самом деле роли не играет, продолжать можно как с 2 серверами, так и с 20 тысячами (по крайней мере теоретически). Хотя пару рекомендаций все же могу дать: при использовании в "боевых" условиях стоит стараться избегать физического совмещения мастер-узлов компонентов системы (NameNode, JobTracker, HMaster) с "рядовыми" серверами, таким образом желательно начинать с, как минимум, 5-7 серверов.
Удостоверившись, что на всем оборудовании установлен какой-нибудь дистрибутив Linux или Unix (любители особо поизвращаться могут попытать счастья с "окнами" в совокупности с Cygwin) и 5 или 6 версия JRE/JDK (желательно от Sun), можно приступать к настройке каждого узла по тому же принципу, что и для псевдо-кластера (да-да, предупреждение в начале раздела было написано не для мебели). Кстати не забудьте, что HBasе теперь нужно скачивать отдельно. О небольших присутствующих особенностях я расскажу чуть позже, а пока дам маленький совет, который позволит несколько облегчить это непростое дело.
Вручную выполнять одни и те же операции на паре десятков/сотен/тысяч серверов мало того что долго, но и чрезвычайно утомительно. Уже на втором-третьем сервере начнет появляться желание каким-либо образом автоматизировать процесс установки. Конечно же можно воспользоваться специализированным программным обеспечением, скажем gexec, но есть и более простой способ: существенно упростить жизнь может простой скрипт на bash в 5 строчек:
#!/bin/bash
for x in `cat ~/nodes`
do
ssh hadoop@$x $1
done
В файле ~/nodes
должен располагаться список IP-адресов всех серверов, тогда получив первым параметром произвольную консольную команду скрипт выполнит ее на каждом сервере. С его помощью можно существенно сократить время, требуемое на выполнение всех необходимых действий для запуска кластера.
После небольшого лирического отступления вернемся собственно к Hadoop. Как Вы уже, надеюсь, знаете, система использует ssh для управления всеми компонентами системы, причем очень желателен беспарольный доступ между всеми узлами. Для этого необходимо собрать в один файл все публичные ключи ~/.ssh/id_rsa.pub
на каждом из узлов (по одному на строчку) и разместить его под именем ~/.ssh/authorized_keys
тоже на каждом из узлов. Кстати для упоминавшегося выше скрипта беспарольный доступ тоже очень желателен.
Следующим этапом нужно подготовить конфигурационные файлы, они должны быть идентичными на всех узлах, так что заполнив их все на одном из узлов нужно скопировать их по всем остальным серверам (очень удобно делать это с помощью rsync). Теперь пройдемся по необходимым изменениям в каждом из них:
hadoop-site.xml
<property>
<name>fs.default.name</name>
<value>hdfs://namenode:54310</value>
<description>
The name of the default file system. A URI whose
scheme and authority determine the FileSystem implementation. The
uri's scheme determines the config property (fs.SCHEME.impl) naming
the FileSystem implementation class. The uri's authority is used to
determine the host, port, etc. for a filesystem.
</description>
</property>
<property>
<name>mapred.job.tracker</name>
<value>jobtracker:54311</value>
<description>
The host and port that the MapReduce job tracker runs
at. If "local", then jobs are run in-process as a single map
and reduce task.
</description>
</property>
Каждый сервер должен знать где расположен NameNode, по-этому он явно указывается в полном пути к файловой системе, практически аналогичная ситуация и с JobTracker. Вместо namenode и jobtracker необходимо указать их IP-адреса или доменные имена (или в крайнем случае - имя в /etc/hosts
)
masters
Вопреки логике, здесь указывается список всех SecondaryNameNode. Одного-двух серверов здесь будет вполне достаточно, самое главное не указывать здесь адрес основного NameNode, лучше всего подойдет какой-нибудь другой мастер-сервер, может быть дополненный одним из обычных узлов кластера. Выделять под это отдельный сервер смысла не много, так как нагрузка на них минимальна.
slaves
Список всех рядовых серверов, по одному на строку (опять же: IP или доменное имя). На них будут запущенны DataNode и TaskTracker.
hbase-site.xml
<property>
<name>hbase.master</name>
<value>localhost:60000</value>
<description>
the host and port that the HBase master runs at
</description>
</property>
Первое изменение достаточно очевидно: HRegionServer должны знать где находится HMaster, о чем им и сообщает первое свойство (заменяем hmaster на соответствующий адрес). А вот второе свойство является следствием "обособления" HBase от Hadoop, о котором шла речь ранее. Теперь имеется возможность использовать их отдельно (с локальной файловой системой вместо HDFS), а так как появился выбор файловой системы - ее адрес необходимо указывать полностью. В данном случае указан адрес HDFS (такой же как в hadoop-site.xml).
regionservers
Вполне очевидный конфигурационный файл, по аналогии со slaves, заполняется списком адресов для запуска HRegionServer. Часто совпадает с упомянутым slaves, обычно достаточно просто скопировать.
Запуск
Удостоверившись, что с конфигурационными файлами все нормально и что они на всех серверах совпадают, можно приступать собственно к запуску. Этот процесс практически полностью совпадает с запуском на одном узле, хотя обычно проще желать это тоже простеньким скриптом примерно такого вида:
#!/bin/bash
ssh hadoop@namenode ~/hadoop/bin/start-dfs.sh
ssh hadoop@jobtracker ~/hadoop/bin/start-mapred.sh
ssh hadoop@hmaster ~/hbase/bin/start-hbase.sh
Если мы нигде не ошиблись и все сделано правильно, то кластер благополучно запустится, что легко проследить выполнив на каждом узле команду jps
и проверив соответствие запущенных компонентов запланированному (читай: указанному в конфигурационных файлах).
В целом процесс достаточно прост и не занимает много времени, если Вы все же столкнулись с какими-либо проблемами в процессе - обращайтесь, вполне возможно, что я смогу помочь. Удостовериться, что все нормально можно абсолютно так же, как и для псевдо-кластера - с помощью MapReduce задач, идущих в комплекте с Hadoop. Выглядеть это может, например, вот так:
$ ~/hadoop/bin/hadoop jar hadoop-*-examples.jar pi 4 10000
По-хорошему надо было бы написать подобную инструкцию сразу после первой, но почему-то как-то не сложилось...
Заключение
На данный момент Hadoop стал еще более работоспособным, по сравнению с его февральским состоянием. Сообщество использующих его разработчиков растет с каждым днем, а все ошибки и проблемы исправляются очень и очень оперативно, многие коммерческие проекты могут позавидовать таким темпам развития. Хоть до по-настоящему стабильного релиза еще далеко, данный продукт уже сейчас очень активно используется в достаточно большом количестве крупных интернет-проектов.
Если Вы еще не успели подписаться на RSS - сейчас самое время!