Как упоминалось в предыдущей статье
Hadoop Основы, ценность hadoop заключается в том, что он работает во многих
машинах.
В этой статье я покажу вам, как настроить Hadoop для распределенной обработки. Я покажу, как сделать это всего двумя машинами, но это будет то же самое для большего, поскольку одним из основных значений Hadoop является возможность простого масштабирования.
1. Итак, мы загружаем hadoop 0.21.0 отсюда
http://mirror.lividpenguin.com/pub/apache//hadoop/core/hadoop-0.21.0/hadoop-0.21.0.tar.gz
на обеих машинах , распакуйте файл.
2. У нас есть два независимых Hadoops прямо сейчас, но мы хотим, чтобы они работали в кластере. Поэтому мы должны сделать некоторые настройки. Распределенные работы Hadoop
с 5 различными демонами, которые общаются друг с другом. Демонами являются:
NameNode : главный контроллер HDFS, он заботится о том, как файлы разбиваются на блоки, какие узлы содержат каждый
блок и общее
отслеживание распределенной файловой системы.
DataNode : этот демон обслуживает требования HDFS отдельных подчиненных узлов, взаимодействующих и координирующих работу с NameNode.
Вторичный NameNode : делает снимки NameNode для возможных восстановлений.
JobTracker : отвечает за координацию отправки задач на разные узлы.
TaskTracker: Существующие в каждом узле обработки, они отвечают за выполнение задач, представленных JobTracker, и поддерживают с ним постоянную связь.
Все общение между Hadoop осуществляется через SSH. Мы назначим главный узел (который будет содержать NameNode и JobTracker) и два подчиненных узла. Главный узел должен иметь возможность связываться с подчиненными узлами через ssh, используя то же имя пользователя. (Я использую свое имя пользователя cscarioni, общаясь без ключевой фразы, используя аутентификацию с закрытым / открытым ключом).
Так как мы используем две машины, наша архитектура будет выглядеть так:
Машина 1 (Мастер) | Машина 2 (Раб) |
NameNode JobTracker Вторичный NameNode TaskTracker DataNode |
TaskTracker DataNode |
Идем к нашему мастеру
установки hadoop и заходим в каталог conf.
В core-site.xml мы указываем информацию NameNode. мы ставим следующее.
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.default.name</name> <value>hdfs://master-hadoop:9000</value> </property> </configuration>
В файле mapred-site.xml мы указываем, где находится демон отслеживания заданий:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapred.job.tracker</name> <value>master-hadoop:9001</value> </property> </configuration>
В hdfs-site.xml мы указываем репликацию кластера. В нашем случае 2:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.replication</name> <value>2</value> </property> </configuration>
В
мастерах и
ведомые файлы содержат имена ведущих и ведомых узлов. Мы должны изменить их, чтобы включить наши главные и подчиненные узлы. (Я определен в файле хосты обоего машин следующих имен хостов.)
Таким образом , в
мастерах мы помещаем
Hadoop-мастер
и в
рабах мы помещаем
мастер-Hadoop
-Карло нетбук
Далее мы изменить hadoop-env.sh, раскомментировано JAVA_HOME линии и укажите его в нашем JAVA_HOME.
Хорошо, это все файлы, которые нам нужны, теперь мы распространяем (копируем) эти файлы на обе машины.
Теперь перейдем к узлу bin на главном узле и выполним ./hadoop namenode -format, чтобы отформатировать hdfs.
Наконец, мы выполняем в том же каталоге: ./start-all.sh.
Вот и все, мы запустили Hadoop. Теперь нам нужно поместить некоторые файлы в HDFS и отправить ему задачу уменьшения карты.
Для этого примера я буду использовать специально созданный файл, в каждой строке которого есть слово «Бог» или «Слово дьявол». Я создал файл со следующим скриптом Groovy
def a = new File("/tmp/biblia.txt") random = new Random() a.withWriter{ for (i in (0..5000000)){ if(random.nextInt(2)){ it << "GOD\n" }else{ it << "Devil\n" } } }
Из каталога bin мастера master скопируйте файл из файловой системы в hdfs с помощью:
./hadoop fs -put /home/cscarioni/downloads/bible.txt bible.txt,
чтобы увидеть, что файл был создан, выполните:
./hadoop fs -ls
Я получаю следующий вывод:
-rw-r — r— 2 cgarioni supergroup 4445256 2011-01-24 18:25 /user/cscarioni/bible.txt
Теперь мы создаем нашу программу MapReduce (она просто подсчитывает, сколько раз слова БОГ и Дьявол находятся в файле):
import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser; public class GodVsDevils { public static class WordMapper extends Mapper<LongWritable, Text, Text, LongWritable> { private LongWritable word = new LongWritable(); private Text theKey = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String who =value.toString(); word.set(1); if(who.equals("GOD")) { theKey.set("God"); context.write(theKey, word); } else if(who.equals("Devil")) { theKey.set("Devil"); context.write(theKey, word); } } } public static class AllTranslationsReducer extends Reducer<Text,LongWritable,Text,LongWritable> { private LongWritable result = new LongWritable(); public void reduce(Text key, Iterable<;LongWritable>; values, Context context ) throws IOException, InterruptedException { long count = 0; for (LongWritable val : values) { count += val.get(); } result.set(count); context.write(key, result); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = new Job(conf,"GodDevils"); job.setJarByClass(GodVsDevils.class); job.setMapperClass(WordMapper.class); job.setReducerClass(AllTranslationsReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); FileInputFormat.addInputPath(job, new Path("/user/cscarioni")); FileOutputFormat.setOutputPath(job, new Path("output")); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
Мы скомпилировать его, баночки , а затем выполнить следующее в главном узле:
./hadoop баночку god.jar GodVsDevils -FS мастер-Hadoop: 9000 -jt мастер-Hadoop: 9001
Это будет работать наша карта уменьшить в Hadoop кластера.