<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>@machine_learning</title><author><name>@machine_learning</name></author><id>https://teletype.in/atom/machine_learning</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/machine_learning?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@machine_learning?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=machine_learning"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/machine_learning?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-13T20:57:21.496Z</updated><entry><id>machine_learning:SkvFWrCvB</id><link rel="alternate" type="text/html" href="https://teletype.in/@machine_learning/SkvFWrCvB?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=machine_learning"></link><title>Big Data от А до Я. Часть 2: Hadoop</title><published>2019-09-29T14:36:46.842Z</published><updated>2019-09-29T14:37:36.422Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/c7/c7fbb5ab-9df3-4bc1-a9f6-e945d9dd9702.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/fc/fc8fb033-0922-4364-a6b4-2340105c9fb6.png&quot;&gt;В предыдущей статье мы рассмотрели парадигму параллельных вычислений MapReduce. В этой статье мы перейдём от теории к практике и рассмотрим Hadoop – мощный инструментарий для работы с большими данными от Apache foundation.</summary><content type="html">
  &lt;p&gt;В &lt;a href=&quot;http://habrahabr.ru/company/dca/blog/267361/&quot; target=&quot;_blank&quot;&gt;предыдущей &lt;/a&gt;статье мы рассмотрели парадигму параллельных вычислений MapReduce. В этой статье мы перейдём от теории к практике и рассмотрим &lt;a href=&quot;http://hadoop.apache.org/&quot; target=&quot;_blank&quot;&gt;Hadoop &lt;/a&gt;– мощный инструментарий для работы с большими данными от Apache foundation.&lt;/p&gt;
  &lt;p&gt;В статье описано, какие инструменты и средства включает в себя Hadoop, каким образом установить Hadoop у себя, приведены инструкции и примеры разработки MapReduce-программ под Hadoop.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/fc/fc8fb033-0922-4364-a6b4-2340105c9fb6.png&quot; width=&quot;848&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2&gt;Общая информация о Hadoop&lt;/h2&gt;
  &lt;p&gt;Как известно парадигму MapReduce предложила компания Google в 2004 году в своей статье &lt;a href=&quot;http://research.google.com/archive/mapreduce.html&quot; target=&quot;_blank&quot;&gt;MapReduce: Simplified Data Processing on Large Clusters&lt;/a&gt;. Поскольку предложенная статья содержала описание парадигмы, но реализация отсутствовала – несколько программистов из Yahoo предложили свою реализацию в рамках работ над web-краулером &lt;a href=&quot;http://nutch.apache.org/&quot; target=&quot;_blank&quot;&gt;nutch&lt;/a&gt;. Более подробно историю Hadoop можно почитать в статье &lt;a href=&quot;https://gigaom.com/2013/03/04/the-history-of-hadoop-from-4-nodes-to-the-future-of-data/&quot; target=&quot;_blank&quot;&gt;The history of Hadoop: From 4 nodes to the future of data.&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Изначально Hadoop был, в первую очередь, инструментом для хранения данных и запуска MapReduce-задач, сейчас же Hadoop представляет собой большой стек технологий, так или иначе связанных с обработкой больших данных (не только при помощи MapReduce).&lt;/p&gt;
  &lt;p&gt;Основными (core) компонентами Hadoop являются:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://hadoop.apache.org/docs/r1.2.1/hdfs_design.html&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Hadoop Distributed File System (HDFS)&lt;/strong&gt;&lt;/a&gt; – распределённая файловая система, позволяющая хранить информацию практически неограниченного объёма.&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Hadoop YARN&lt;/strong&gt;&lt;/a&gt; – фреймворк для управления ресурсами кластера и менеджмента задач, в том числе включает фреймворк MapReduce.&lt;/li&gt;
    &lt;li&gt;Hadoop common&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Также существует большое количество проектов непосредственно связанных с Hadoop, но не входящих в Hadoop core:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://hive.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Hive&lt;/strong&gt;&lt;/a&gt; – инструмент для SQL-like запросов над большими данными (превращает SQL-запросы в серию MapReduce–задач);&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://pig.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Pig&lt;/strong&gt;&lt;/a&gt; – язык программирования для анализа данных на высоком уровне. Одна строчка кода на этом языке может превратиться в последовательность MapReduce-задач;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://hbase.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Hbase&lt;/strong&gt;&lt;/a&gt; – колоночная база данных, реализующая парадигму &lt;a href=&quot;https://ru.wikipedia.org/wiki/BigTable&quot; target=&quot;_blank&quot;&gt;BigTable&lt;/a&gt;;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://cassandra.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Cassandra&lt;/strong&gt;&lt;/a&gt; – высокопроизводительная распределенная key-value база данных;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://zookeeper.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;ZooKeeper&lt;/strong&gt;&lt;/a&gt; – сервис для распределённого хранения конфигурации и синхронизации изменений этой конфигурации;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://mahout.apache.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Mahout&lt;/strong&gt;&lt;/a&gt; – библиотека и движок машинного обучения на больших данных.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Отдельно хотелось бы отметить проект &lt;a href=&quot;http://spark.apache.org/&quot; target=&quot;_blank&quot;&gt;Apache Spark&lt;/a&gt;, который представляет собой движок для распределённой обработки данных. Apache Spark обычно использует компоненты Hadoop, такие как HDFS и YARN для своей работы, при этом сам в последнее время стал популярнее, чем Hadoop:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/fb6/32c/1a5/fb632c1a5b3843bd4dc292a4a226cc01.png&quot; width=&quot;1600&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Некоторым из перечисленных компонент будут посвящены отдельные статьи этого цикла материалов, а пока разберём, каким образом можно начать работать с Hadoop и применять его на практике.&lt;/p&gt;
  &lt;h2&gt;Установка Hadoop на кластер при помощи Cloudera Manager&lt;/h2&gt;
  &lt;p&gt;Раньше установка Hadoop представляла собой достаточно тяжёлое занятие – нужно было по отдельности конфигурировать каждую машину в кластере, следить за тем, что ничего не забыто, аккуратно настраивать мониторинги. С ростом популярности Hadoop появились компании (такие как &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/home.html&quot; target=&quot;_blank&quot;&gt;Cloudera&lt;/a&gt;, &lt;a href=&quot;http://hortonworks.com/&quot; target=&quot;_blank&quot;&gt;Hortonworks &lt;/a&gt;, &lt;a href=&quot;https://www.mapr.com/&quot; target=&quot;_blank&quot;&gt;MapR&lt;/a&gt;), которые предоставляют собственные сборки Hadoop и мощные средства для управления Hadoop-кластером. В нашем цикле материалов мы будем пользоваться сборкой Hadoop от компании Cloudera.&lt;/p&gt;
  &lt;p&gt;Для того чтобы установить Hadoop на свой кластер, нужно проделать несколько простых шагов:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Скачать Cloudera Manager Express на одну из машин своего кластера &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/downloads/cloudera_manager/cm-5-4-7.html&quot; target=&quot;_blank&quot;&gt;отсюда&lt;/a&gt;;&lt;/li&gt;
    &lt;li&gt;Присвоить права на выполнение и запустить;&lt;/li&gt;
    &lt;li&gt;Следовать инструкциям установки.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Кластер должен работать на одной из поддерживаемых операционных систем семейства linux: RHEL, Oracle Enterprise linux, SLES, Debian, Ubuntu.&lt;/p&gt;
  &lt;p&gt;После установки вы получите консоль управления кластером, где можно смотреть установленные сервисы, добавлять/удалять сервисы, следить за состоянием кластера, редактировать конфигурацию кластера:&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/475/209/2d8/4752092d8a708fadd8ee2988d952e31e.png&quot; width=&quot;1455&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Более подробно с процессом установки Hadoop на кластер при помощи cloudera manager можно ознакомиться по &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/downloads/cloudera_manager/cm-5-4-7.html&quot; target=&quot;_blank&quot;&gt;ссылке &lt;/a&gt;в разделе Quick Start.&lt;/p&gt;
  &lt;p&gt;Если же Hadoop планируется использовать для «попробовать» – можно не заморачиваться с приобретением дорогого железа и настройкой Hadoop на нём, а просто скачать преднастроенную виртуальную машину по &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/downloads/quickstart_vms/cdh-5-4-x.html&quot; target=&quot;_blank&quot;&gt;ссылке &lt;/a&gt;и пользоваться настроенным hadoop’ом.&lt;/p&gt;
  &lt;h2&gt;Запуск MapReduce программ на Hadoop&lt;/h2&gt;
  &lt;p&gt;Теперь покажем как запустить MapReduce-задачу на Hadoop. В качестве задачи воспользуемся классическим примером&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;WordCount&lt;/strong&gt;, который был разобран в &lt;a href=&quot;http://habrahabr.ru/company/dca/blog/267361/&quot; target=&quot;_blank&quot;&gt;предыдущей статье цикла&lt;/a&gt;. Для того, чтобы экспериментировать на реальных данных, я подготовил архив из случайных новостей с сайта &lt;a href=&quot;http://lenta.ru/&quot; target=&quot;_blank&quot;&gt;lenta.ru&lt;/a&gt;. Скачать архив можно по &lt;a href=&quot;https://www.dropbox.com/s/opp5psid1x3jt41/lenta_articles.tar.gz&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Напомню формулировку задачи:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;имеется набор документов. Необходимо для каждого слова, встречающегося в наборе документов, посчитать, сколько раз встречается слово в наборе.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Решение&lt;/strong&gt;:&lt;/p&gt;
  &lt;p&gt;Map разбивает документ на слова и возвращает множество пар (word, 1).&lt;/p&gt;
  &lt;p&gt;Reduce суммирует вхождения каждого слова:&lt;/p&gt;
  &lt;pre&gt;def map(doc): 
for word in doc.split(): 
    yield word, 1&lt;/pre&gt;
  &lt;pre&gt;def reduce(word, values): 
    yield word, sum(values)

&lt;/pre&gt;
  &lt;p&gt;Теперь задача запрограммировать это решение в виде кода, который можно будет исполнить на Hadoop и запустить.&lt;/p&gt;
  &lt;h1&gt;Способ №1. Hadoop Streaming&lt;/h1&gt;
  &lt;p&gt;Самый простой способ запустить MapReduce-программу на Hadoop – воспользоваться streaming-интерфейсом Hadoop. Streaming-интерфейс предполагает, что map и reduce реализованы в виде программ, которые принимают данные с &lt;strong&gt;stdin &lt;/strong&gt;и выдают результат на &lt;strong&gt;stdout&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;Программа, которая исполняет функцию map называется &lt;strong&gt;mapper&lt;/strong&gt;. Программа, которая выполняет reduce, называется, соответственно, &lt;strong&gt;reducer&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;Streaming интерфейс предполагает по умолчанию, что одна входящая строка в mapper или reducer соответствует одной входящей записи для map.&lt;/p&gt;
  &lt;p&gt;Вывод mapper’a попадает на вход reducer’у в виде пар (ключ, значение), при этом все пары соответствующие одному ключу:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Гарантированно будут обработаны одним запуском reducer’a;&lt;/li&gt;
    &lt;li&gt;Будут поданы на вход подряд (то есть если один reducer обрабатывает несколько разных ключей – вход будет сгруппирован по ключу).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Итак, реализуем mapper и reducer на python:&lt;/p&gt;
  &lt;pre&gt;#mapper.py 
import sys 
 
def do_map(doc): 
for word in doc.split(): 
    yield word.lower(), 1 
 
for line in sys.stdin: 
    for key, value in do_map(line): 
        print(key + &amp;quot;\t&amp;quot; + str(value)) &lt;/pre&gt;
  &lt;pre&gt;#reducer.py 
import sys 
 
def do_reduce(word, values): 
    return word, sum(values) 
 
prev_key = None 
values = [] 
 
for line in sys.stdin: 
    key, value = line.split(&amp;quot;\t&amp;quot;) 
    if key != prev_key and prev_key is not None: 
        result_key, result_value = do_reduce(prev_key, values) 
        print(result_key + &amp;quot;\t&amp;quot; + str(result_value)) 
        values = [] 
    prev_key = key 
    values.append(int(value)) 
 
if prev_key is not None: 
    result_key, result_value = do_reduce(prev_key, values) 
    print(result_key + &amp;quot;\t&amp;quot; + str(result_value)) &lt;/pre&gt;
  &lt;p&gt;Данные, которые будет обрабатывать Hadoop должны храниться на HDFS. Загрузим наши статьи и положим на HDFS. Для этого нужно воспользоваться командой &lt;strong&gt;hadoop fs&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre&gt;wget https://www.dropbox.com/s/opp5psid1x3jt41/lenta_articles.tar.gz 
tar xzvf lenta_articles.tar.gz 
hadoop fs -put lenta_articles&lt;/pre&gt;
  &lt;p&gt;Утилита hadoop fs поддерживает большое количество методов для манипуляций с файловой системой, многие из которых один в один повторяют стандартные утилиты linux. Подробнее с её возможностями можно ознакомиться по &lt;a href=&quot;https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;. &lt;/p&gt;
  &lt;p&gt;Теперь запустим streaming-задачу:&lt;/p&gt;
  &lt;pre&gt;yarn jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar\ 
 -input lenta_articles\ 
 -output lenta_wordcount\ 
 -file mapper.py\ 
 -file reducer.py\ 
 -mapper &amp;quot;python mapper.py&amp;quot;\ 
 -reducer &amp;quot;python reducer.py&amp;quot;&lt;/pre&gt;
  &lt;p&gt;Утилита yarn служит для запуска и управления различными приложениями (в том числе map-reduce based) на кластере. Hadoop-streaming.jar – это как раз один из примеров такого yarn-приложения.&lt;/p&gt;
  &lt;p&gt;Дальше идут параметры запуска:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;input – папка с исходными данными на hdfs;&lt;/li&gt;
    &lt;li&gt;output – папка на hdfs, куда нужно положить результат;&lt;/li&gt;
    &lt;li&gt;file – файлы, которые нужны в процессе работы map-reduce задачи;&lt;/li&gt;
    &lt;li&gt;mapper – консольная команда, которая будет использоваться для map-стадии;&lt;/li&gt;
    &lt;li&gt;reduce – консольная команда которая будет использоваться для reduce-стадии.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;После запуска в консоли можно будет увидеть прогресс выполнения задачи и URL для просмотра более детальной информации о задаче.&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/120/d38/394/120d38394178136bb5a54a6849098539.png&quot; width=&quot;1429&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;В интерфейсе доступном по этому URL можно узнать более детальный статус выполнения задачи, посмотреть логи каждого маппера и редьюсера (что очень полезно в случае упавших задач).&lt;/p&gt;
  &lt;figure class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/getpro/habr/post_images/593/618/89b/59361889be8b9428e814af24ba11384a.png&quot; width=&quot;1428&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Результат работы после успешного выполнения складывается на HDFS в папку, которую мы указали в поле output. Просмотреть её содержание можно при помощи команды «hadoop fs -ls lenta_wordcount».&lt;/p&gt;
  &lt;p&gt;Сам результат можно получить следующим образом:&lt;/p&gt;
  &lt;pre&gt;hadoop fs -text lenta_wordcount/* | sort -n -k2,2 | tail -n5 
с	 41 
что	 43 
на	 82 
и	 111 
в	 194&lt;/pre&gt;
  &lt;p&gt;Команда «hadoop fs -text» выдаёт содержимое папки в текстовом виде. Я отсортировал результат по количеству вхождений слов. Как и ожидалось, самые частые слова в языке – предлоги.&lt;/p&gt;
  &lt;h2&gt;Способ №2&lt;/h2&gt;
  &lt;p&gt;Сам по себе hadoop написан на java, и нативный интерфейс у hadoop-a тоже java-based. Покажем, как выглядит нативное java-приложение для wordcount:&lt;/p&gt;
  &lt;pre&gt;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.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.output.FileOutputFormat; 
 
public class WordCount { 
 
    public static class TokenizerMapper 
            extends Mapper&amp;lt;Object, Text, Text, IntWritable&amp;gt;{ 
 
        private final static IntWritable one = new IntWritable(1); 
        private Text word = new Text(); 
 
        public void map(Object key, Text value, Context context 
        ) throws IOException, InterruptedException { 
            StringTokenizer itr = new StringTokenizer(value.toString()); 
            while (itr.hasMoreTokens()) { 
                word.set(itr.nextToken()); 
                context.write(word, one); 
            } 
        } 
    } 
 
    public static class IntSumReducer 
            extends Reducer&amp;lt;Text,IntWritable,Text,IntWritable&amp;gt; { 
        private IntWritable result = new IntWritable(); 
 
        public void reduce(Text key, Iterable&amp;lt;IntWritable&amp;gt; values, 
                           Context context 
        ) throws IOException, InterruptedException { 
            int sum = 0; 
            for (IntWritable val : values) { 
                sum += val.get(); 
            } 
            result.set(sum); 
            context.write(key, result); 
        } 
    } 
 
    public static void main(String[] args) throws Exception { 
        Configuration conf = new Configuration(); 
        Job job = Job.getInstance(conf, &amp;quot;word count&amp;quot;); 
        job.setJarByClass(WordCount.class); 
        job.setMapperClass(TokenizerMapper.class); 
        job.setReducerClass(IntSumReducer.class); 
        job.setOutputKeyClass(Text.class); 
        job.setOutputValueClass(IntWritable.class); 
        FileInputFormat.addInputPath(job, new Path(&amp;quot;hdfs://localhost/user/cloudera/lenta_articles&amp;quot;)); 
        FileOutputFormat.setOutputPath(job, new Path(&amp;quot;hdfs://localhost/user/cloudera/lenta_wordcount&amp;quot;)); 
        System.exit(job.waitForCompletion(true) ? 0 : 1); 
    } 
}&lt;/pre&gt;
  &lt;p&gt;Этот класс делает абсолютно то же самое, что наш пример на Python. Мы создаём классы TokenizerMapper и IntSumReducer, наследуя их от классов Mapper и Reducer соответсвенно. Классы, передаваемые в качестве параметров шаблона, указывают типы входных и выходных значений. Нативный API подразумевает, что функции map на вход подаётся пара ключ-значение. Поскольку в нашем случае ключ пустой – в качестве типа ключа мы определяем просто Object.&lt;/p&gt;
  &lt;p&gt;В методе Main мы заводим mapreduce-задачу и определяем её параметры – имя, mapper и reducer, путь в HDFS, где находятся входные данные и куда положить результат.&lt;/p&gt;
  &lt;p&gt;Для компиляции нам потребуются hadoop-овские библиотеки. Я использую для сборки Maven, для которого у cloudera есть репозиторий. Инструкции по его настройке можно найти по &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_vd_cdh5_maven_repo.html&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;. В итоге файл pom.xmp (который используется maven’ом для описания сборки проекта) у меня получился следующий):&lt;/p&gt;
  &lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; 
&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; 
         xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; 
         xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&amp;quot;&amp;gt; 
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt; 
 
    &amp;lt;repositories&amp;gt; 
        &amp;lt;repository&amp;gt; 
            &amp;lt;id&amp;gt;cloudera&amp;lt;/id&amp;gt; 
            &amp;lt;url&amp;gt;https://repository.cloudera.com/artifactory/cloudera-repos/&amp;lt;/url&amp;gt; 
        &amp;lt;/repository&amp;gt; 
    &amp;lt;/repositories&amp;gt; 
 
    &amp;lt;dependencies&amp;gt; 
        &amp;lt;dependency&amp;gt; 
            &amp;lt;groupId&amp;gt;org.apache.hadoop&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;hadoop-common&amp;lt;/artifactId&amp;gt; 
            &amp;lt;version&amp;gt;2.6.0-cdh5.4.2&amp;lt;/version&amp;gt; 
        &amp;lt;/dependency&amp;gt; 
 
        &amp;lt;dependency&amp;gt; 
            &amp;lt;groupId&amp;gt;org.apache.hadoop&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;hadoop-auth&amp;lt;/artifactId&amp;gt; 
            &amp;lt;version&amp;gt;2.6.0-cdh5.4.2&amp;lt;/version&amp;gt; 
        &amp;lt;/dependency&amp;gt; 
 
        &amp;lt;dependency&amp;gt; 
            &amp;lt;groupId&amp;gt;org.apache.hadoop&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;hadoop-hdfs&amp;lt;/artifactId&amp;gt; 
            &amp;lt;version&amp;gt;2.6.0-cdh5.4.2&amp;lt;/version&amp;gt; 
        &amp;lt;/dependency&amp;gt; 
 
        &amp;lt;dependency&amp;gt; 
            &amp;lt;groupId&amp;gt;org.apache.hadoop&amp;lt;/groupId&amp;gt; 
            &amp;lt;artifactId&amp;gt;hadoop-mapreduce-client-app&amp;lt;/artifactId&amp;gt; 
            &amp;lt;version&amp;gt;2.6.0-cdh5.4.2&amp;lt;/version&amp;gt; 
        &amp;lt;/dependency&amp;gt; 
 
    &amp;lt;/dependencies&amp;gt; 
 
    &amp;lt;groupId&amp;gt;org.dca.examples&amp;lt;/groupId&amp;gt; 
    &amp;lt;artifactId&amp;gt;wordcount&amp;lt;/artifactId&amp;gt; 
    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt; 

&amp;lt;/project&amp;gt;&lt;/pre&gt;
  &lt;p&gt;Соберём проект в jar-пакет:&lt;/p&gt;
  &lt;pre&gt;mvn clean package&lt;/pre&gt;
  &lt;p&gt;После сборки проекта в jar-файл запуск происходит похожим образом, как и в случае streaming-интерфейса:&lt;/p&gt;
  &lt;pre&gt;yarn jar wordcount-1.0-SNAPSHOT.jar  WordCount&lt;/pre&gt;
  &lt;p&gt;Дожидаемся выполнения и проверяем результат:&lt;/p&gt;
  &lt;pre&gt;hadoop fs -text lenta_wordcount/* | sort -n -k2,2 | tail -n5 
с	 41 
что	 43 
на	 82 
и	 111 
в	 194&lt;/pre&gt;
  &lt;p&gt;Как нетрудно догадаться, результат выполнения нашего нативного приложения совпадает с результатом streaming-приложения, которое мы запустили предыдущим способом.&lt;/p&gt;
  &lt;h1&gt;Резюме&lt;/h1&gt;
  &lt;p&gt;В статье мы рассмотрели Hadoop – программный стек для работы с большими данными, описали процесс установки Hadoop на примере дистрибутива cloudera, показали, как писать mapreduce-программы, используя streaming-интерфейс и нативный API Hadoop’a.&lt;/p&gt;
  &lt;p&gt;В следующих статьях цикла мы рассмотрим более детально архитектуру отдельных компонент Hadoop и Hadoop-related ПО, покажем более сложные варианты MapReduce-программ, разберём способы упрощения работы с MapReduce, а также ограничения MapReduce и как эти ограничения обходить.&lt;/p&gt;

</content></entry><entry><id>machine_learning:ryBH3Z5DS</id><link rel="alternate" type="text/html" href="https://teletype.in/@machine_learning/ryBH3Z5DS?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=machine_learning"></link><title>Big Data от А до Я. Часть 1: Принципы работы с большими данными, парадигма MapReduce</title><published>2019-09-26T10:00:28.806Z</published><updated>2019-09-26T10:02:11.493Z</updated><summary type="html">&lt;img src=&quot;https://habrastorage.org/files/d4b/698/53d/d4b69853d9f94876bb922fa7d0e18939.png&quot;&gt;Этой статьёй я открываю цикл материалов, посвящённых работе с большими данными. Зачем? Хочется сохранить накопленный опыт, свой и команды, так скажем, в энциклопедическом формате – наверняка кому-то он будет полезен.</summary><content type="html">
  &lt;p&gt;Этой статьёй я открываю цикл материалов, посвящённых работе с большими данными. Зачем? Хочется сохранить накопленный опыт, свой и команды, так скажем, в энциклопедическом формате – наверняка кому-то он будет полезен.&lt;/p&gt;
  &lt;p&gt;Проблематику больших данных постараемся описывать с разных сторон: основные принципы работы с данными, инструменты, примеры решения практических задач. Отдельное внимание окажем теме машинного обучения.&lt;/p&gt;
  &lt;p&gt;Начинать надо от простого к сложному, поэтому первая статья – о принципах работы с большими данными и парадигме MapReduce.&lt;/p&gt;
  &lt;h2&gt;История вопроса и определение термина&lt;/h2&gt;
  &lt;p&gt;Термин Big Data появился сравнительно недавно. Google Trends показывает начало активного роста употребления словосочетания начиная с 2011 года (&lt;a href=&quot;https://www.google.com/trends/explore&quot; target=&quot;_blank&quot;&gt;ссылка&lt;/a&gt;):&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/files/d4b/698/53d/d4b69853d9f94876bb922fa7d0e18939.png&quot; width=&quot;467&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;При этом уже сейчас термин не использует только ленивый. Особенно часто не по делу термин используют маркетологи. Так что же такое Big Data на самом деле? Раз уж я решил системно изложить и освятить вопрос – необходимо определиться с понятием.&lt;/p&gt;
  &lt;p&gt;В своей практике я встречался с разными определениями:&lt;/p&gt;
  &lt;p&gt;· Big Data – это когда данных больше, чем 100Гб (500Гб, 1ТБ, кому что нравится)&lt;/p&gt;
  &lt;p&gt;· Big Data – это такие данные, которые невозможно обрабатывать в Excel&lt;/p&gt;
  &lt;p&gt;· Big Data – это такие данные, которые невозможно обработать на одном компьютере&lt;/p&gt;
  &lt;p&gt;И даже такие:&lt;/p&gt;
  &lt;p&gt;· Вig Data – это вообще любые данные.&lt;/p&gt;
  &lt;p&gt;· Big Data не существует, ее придумали маркетологи.&lt;/p&gt;
  &lt;p&gt;В этом цикле статей я буду придерживаться &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%91%D0%BE%D0%BB%D1%8C%D1%88%D0%B8%D0%B5_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5&quot; target=&quot;_blank&quot;&gt;определения с wikipedia&lt;/a&gt;:&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Большие данные (&lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B3%D0%BB%D0%B8%D0%B9%D1%81%D0%BA%D0%B8%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA&quot; target=&quot;_blank&quot;&gt;англ.&lt;/a&gt; big data&lt;/strong&gt;) — серия подходов, инструментов и методов обработки структурированных и &lt;a href=&quot;https://ru.wikipedia.org/w/index.php?title=%D0%9D%D0%B5%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5&amp;action=edit&amp;redlink=1&quot; target=&quot;_blank&quot;&gt;неструктурированных данных&lt;/a&gt; огромных объёмов и значительного многообразия для получения воспринимаемых человеком результатов, эффективных в условиях непрерывного прироста, распределения по многочисленным узлам &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D1%81%D0%B5%D1%82%D1%8C&quot; target=&quot;_blank&quot;&gt;вычислительной сети&lt;/a&gt;, сформировавшихся в конце &lt;a href=&quot;https://ru.wikipedia.org/wiki/2000-%D0%B5&quot; target=&quot;_blank&quot;&gt;2000-х годов&lt;/a&gt;, альтернативных традиционным &lt;a href=&quot;https://ru.wikipedia.org/wiki/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B1%D0%B0%D0%B7%D0%B0%D0%BC%D0%B8_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&quot; target=&quot;_blank&quot;&gt;системам управления базами данных&lt;/a&gt; и решениям класса &lt;a href=&quot;https://ru.wikipedia.org/wiki/Business_Intelligence&quot; target=&quot;_blank&quot;&gt;Business Intelligence&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;Таким образом под &lt;strong&gt;Big Data &lt;/strong&gt;я буду понимать не какой-то конкретный объём данных и даже не сами данные, а методы их обработки, которые позволяют распредёлено обрабатывать информацию. Эти методы можно применить как к огромным массивам данных (таким как содержание всех страниц в интернете), так и к маленьким (таким как содержимое этой статьи).&lt;/p&gt;
  &lt;p&gt;Приведу несколько примеров того, что может быть источником данных, для которых необходимы методы работы с большими данными:&lt;/p&gt;
  &lt;p&gt;· Логи поведения пользователей в интернете&lt;/p&gt;
  &lt;p&gt;· GPS-сигналы от автомобилей для транспортной компании&lt;/p&gt;
  &lt;p&gt;· Данные, снимаемые с датчиков в большом адронном коллайдере&lt;/p&gt;
  &lt;p&gt;· Оцифрованные книги в Российской Государственной Библиотеке&lt;/p&gt;
  &lt;p&gt;· Информация о транзакциях всех клиентов банка&lt;/p&gt;
  &lt;p&gt;· Информация о всех покупках в крупной ритейл сети и т.д.&lt;/p&gt;
  &lt;p&gt;Количество источников данных стремительно растёт, а значит технологии их обработки становятся всё более востребованными.&lt;/p&gt;
  &lt;h2&gt;Принципы работы с большими данными&lt;/h2&gt;
  &lt;p&gt;Исходя из определения &lt;strong&gt;Big Data&lt;/strong&gt;, можно сформулировать основные принципы работы с такими данными:&lt;/p&gt;
  &lt;p&gt;1. &lt;strong&gt;Горизонтальная масштабируемость&lt;/strong&gt;. Поскольку данных может быть сколь угодно много – любая система, которая подразумевает обработку больших данных, должна быть расширяемой. В 2 раза вырос объём данных – в 2 раза увеличили количество железа в кластере и всё продолжило работать.&lt;/p&gt;
  &lt;p&gt;2. &lt;strong&gt;Отказоустойчивость&lt;/strong&gt;. Принцип горизонтальной масштабируемости подразумевает, что машин в кластере может быть много. Например, Hadoop-кластер Yahoo имеет более 42000 машин (по &lt;a href=&quot;http://www.hadoopwizard.com/which-big-data-company-has-the-worlds-biggest-hadoop-cluster/&quot; target=&quot;_blank&quot;&gt;этой&lt;/a&gt; &lt;a href=&quot;http://www.hadoopwizard.com/which-big-data-company-has-the-worlds-biggest-hadoop-cluster/&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt; можно посмотреть размеры кластера в разных организациях). Это означает, что часть этих машин будет гарантированно выходить из строя. Методы работы с большими данными должны учитывать возможность таких сбоев и переживать их без каких-либо значимых последствий.&lt;/p&gt;
  &lt;p&gt;3. &lt;strong&gt;Локальность данных. &lt;/strong&gt;В больших распределённых системах данные распределены по большому количеству машин. Если данные физически находятся на одном сервере, а обрабатываются на другом – расходы на передачу данных могут превысить расходы на саму обработку. Поэтому одним из важнейших принципов проектирования BigData-решений является принцип локальности данных – по возможности обрабатываем данные на той же машине, на которой их храним.&lt;/p&gt;
  &lt;p&gt;Все современные средства работы с большими данными так или иначе следуют этим трём принципам. Для того, чтобы им следовать – необходимо придумывать какие-то методы, способы и парадигмы разработки средств разработки данных. Один из самых классических методов я разберу в сегодняшней статье.&lt;/p&gt;
  &lt;h2&gt;MapReduce&lt;/h2&gt;
  &lt;p&gt;Про MapReduce на хабре уже писали (&lt;a href=&quot;http://habrahabr.ru/post/103467/&quot; target=&quot;_blank&quot;&gt;раз&lt;/a&gt;, &lt;a href=&quot;http://habrahabr.ru/company/bitrix/blog/218003/&quot; target=&quot;_blank&quot;&gt;два&lt;/a&gt;, &lt;a href=&quot;http://habrahabr.ru/post/74792/&quot; target=&quot;_blank&quot;&gt;три&lt;/a&gt;), но раз уж цикл статей претендует на системное изложение вопросов Big Data – без MapReduce в первой статье не обойтись J&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;MapReduce&lt;/strong&gt; – это модель распределенной обработки данных, предложенная компанией Google для обработки больших объёмов данных на компьютерных кластерах. MapReduce неплохо иллюстрируется следующей картинкой (взято по &lt;a href=&quot;http://blog.sqlauthority.com/2013/10/09/big-data-buzz-words-what-is-mapreduce-day-7-of-21/&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;):&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://habrastorage.org/files/790/7fb/08a/7907fb08a7ab4c3f99775cf548236718.png&quot; width=&quot;475&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;MapReduce предполагает, что данные организованы в виде некоторых записей. Обработка данных происходит в 3 стадии:&lt;/p&gt;
  &lt;p&gt;1. &lt;strong&gt;Стадия Map&lt;/strong&gt;. На этой стадии данные предобрабатываются при помощи функции map(), которую определяет пользователь. Работа этой стадии заключается в предобработке и фильтрации данных. Работа очень похожа на операцию map в функциональных языках программирования – пользовательская функция применяется к каждой входной записи.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Функция map() примененная к одной входной записи и выдаёт множество пар ключ-значение&lt;/strong&gt;. Множество – т.е. может выдать только одну запись, может не выдать ничего, а может выдать несколько пар ключ-значение. Что будет находится в ключе и в значении – решать пользователю, но ключ – очень важная вещь, так как данные с одним ключом в будущем попадут в один экземпляр функции reduce.&lt;/p&gt;
  &lt;p&gt;2. &lt;strong&gt;Стадия Shuffle&lt;/strong&gt;. Проходит незаметно для пользователя. В этой стадии вывод функции map «разбирается по корзинам» – каждая корзина соответствует одному ключу вывода стадии map. В дальнейшем эти корзины послужат входом для reduce.&lt;/p&gt;
  &lt;p&gt;3. &lt;strong&gt;Стадия Reduce&lt;/strong&gt;. Каждая «корзина» со значениями, сформированная на стадии shuffle, попадает на вход функции reduce().&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Функция reduce задаётся пользователем и вычисляет финальный результат для отдельной «корзины».&lt;/strong&gt; Множество всех значений, возвращённых функцией reduce(), является финальным результатом MapReduce-задачи.&lt;/p&gt;
  &lt;p&gt;Несколько дополнительных фактов про MapReduce:&lt;/p&gt;
  &lt;p&gt;1) Все запуски функции &lt;strong&gt;map&lt;/strong&gt; работают независимо и могут работать параллельно, в том числе на разных машинах кластера.&lt;/p&gt;
  &lt;p&gt;2) Все запуски функции &lt;strong&gt;reduce&lt;/strong&gt; работают независимо и могут работать параллельно, в том числе на разных машинах кластера.&lt;/p&gt;
  &lt;p&gt;3) Shuffle внутри себя представляет параллельную сортировку, поэтому также может работать на разных машинах кластера. &lt;strong&gt;Пункты 1-3 позволяют выполнить принцип горизонтальной масштабируемости.&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;4) Функция map, как правило, применяется на той же машине, на которой хранятся данные – это позволяет снизить передачу данных по сети (принцип локальности данных).&lt;/p&gt;
  &lt;p&gt;5) MapReduce – это всегда полное сканирование данных, никаких индексов нет. Это означает, что MapReduce плохо применим, когда ответ требуется очень быстро.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;h2&gt;Примеры задач, эффективно решаемых при помощи MapReduce&lt;br /&gt;&lt;br /&gt;&lt;/h2&gt;
  &lt;h3&gt;Word Count&lt;/h3&gt;
  &lt;p&gt;Начнём с классической задачи – Word Count. Задача формулируется следующим образом: имеется большой корпус документов. Задача – для каждого слова, хотя бы один раз встречающегося в корпусе, посчитать суммарное количество раз, которое оно встретилось в корпусе.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Решение&lt;/strong&gt;:&lt;/p&gt;
  &lt;p&gt;Раз имеем большой корпус документов – пусть один документ будет одной входной записью для MapRreduce–задачи. В MapReduce мы можем только задавать пользовательские функции, что мы и сделаем (будем использовать python-like псевдокод):&lt;/p&gt;
  &lt;pre&gt;def map(doc):
	for word in doc:
		yield word, 1
&lt;/pre&gt;
  &lt;pre&gt;def reduce(word, values):
	yield word, sum(values)
&lt;/pre&gt;
  &lt;p&gt;Функция &lt;strong&gt;map&lt;/strong&gt; превращает входной документ в набор пар (слово, 1), &lt;strong&gt;shuffle&lt;/strong&gt; прозрачно для нас превращает это в пары (слово, [1,1,1,1,1,1]), &lt;strong&gt;reduce&lt;/strong&gt; суммирует эти единички, возвращая финальный ответ для слова.&lt;/p&gt;
  &lt;h3&gt;Обработка логов рекламной системы&lt;/h3&gt;
  &lt;p&gt;Второй пример взят из реальной практики &lt;a href=&quot;http://datacentric.ru/&quot; target=&quot;_blank&quot;&gt;Data-Centric Alliance&lt;/a&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Задача&lt;/strong&gt;: имеется csv-лог рекламной системы вида:&lt;/p&gt;
  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;pre&gt;&amp;lt;user_id&amp;gt;,&amp;lt;country&amp;gt;,&amp;lt;city&amp;gt;,&amp;lt;campaign_id&amp;gt;,&amp;lt;creative_id&amp;gt;,&amp;lt;payment&amp;gt;&amp;lt;/p&amp;gt;

11111,RU,Moscow,2,4,0.3
22222,RU,Voronezh,2,3,0.2
13413,UA,Kiev,4,11,0.7
…
&lt;/pre&gt;
  &lt;p&gt;Необходимо рассчитать среднюю стоимость показа рекламы по городам России.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Решение:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;def map(record):
	user_id, country, city, campaign_id, creative_id, payment = record.split(&amp;quot;,&amp;quot;)
	payment=float(payment)
	if country == &amp;quot;RU&amp;quot;:
		yield city, payment

&lt;/pre&gt;
  &lt;pre&gt;def reduce(city, payments):
	yield city, sum(payments)/len(payments)

&lt;/pre&gt;
  &lt;p&gt;Функция &lt;strong&gt;map&lt;/strong&gt; проверяет, нужна ли нам данная запись – и если нужна, оставляет только нужную информацию (город и размер платежа). Функция &lt;strong&gt;reduce&lt;/strong&gt; вычисляет финальный ответ по городу, имея список всех платежей в этом городе.&lt;/p&gt;
  &lt;h2&gt;Резюме&lt;/h2&gt;
  &lt;p&gt;В статье мы рассмотрели несколько вводных моментов про большие данные:&lt;/p&gt;
  &lt;p&gt;· Что такое &lt;strong&gt;Big Data&lt;/strong&gt; и откуда берётся;&lt;/p&gt;
  &lt;p&gt;· Каким основным принципам следуют все средства и парадигмы работы с большими данными;&lt;/p&gt;
  &lt;p&gt;· Рассмотрели парадигму &lt;strong&gt;MapReduce &lt;/strong&gt;и разобрали несколько задач, в которой она может быть применена.&lt;/p&gt;
  &lt;p&gt;Первая статья была больше теоретической&lt;strong&gt;, &lt;/strong&gt;во второй статье мы перейдем к практике, рассмотрим &lt;a href=&quot;http://hadoop.apache.org/&quot; target=&quot;_blank&quot;&gt;Hadoop&lt;/a&gt; – одну из самых известных технологий для работы с большими данными и покажем, как запускать &lt;strong&gt;MapReduce-&lt;/strong&gt;задачи на Hadoop.&lt;/p&gt;
  &lt;p&gt;В последующих статьях цикла мы рассмотрим более сложные задачи, решаемые при помощи &lt;strong&gt;MapReduce&lt;/strong&gt;, расскажем об ограничениях &lt;strong&gt;MapReduce &lt;/strong&gt;и о том, какими инструментами и техниками можно обходить эти ограничения.&lt;/p&gt;
  &lt;p&gt;&lt;br /&gt;Спасибо за внимание, готовы ответить на ваши вопросы.&lt;br /&gt;&lt;a href=&quot;https://habr.com/ru/company/dca/blog/267361/&quot; target=&quot;_blank&quot;&gt;Источник&lt;/a&gt;&lt;/p&gt;

</content></entry></feed>