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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@machine_learning/ryBH3Z5DS</guid><link>https://teletype.in/@machine_learning/ryBH3Z5DS?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=machine_learning</link><comments>https://teletype.in/@machine_learning/ryBH3Z5DS?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=machine_learning#comments</comments><dc:creator>machine_learning</dc:creator><title>Big Data от А до Я. Часть 1: Принципы работы с большими данными, парадигма MapReduce</title><pubDate>Thu, 26 Sep 2019 10:00:28 GMT</pubDate><description><![CDATA[<img src="https://habrastorage.org/files/d4b/698/53d/d4b69853d9f94876bb922fa7d0e18939.png"></img>Этой статьёй я открываю цикл материалов, посвящённых работе с большими данными. Зачем? Хочется сохранить накопленный опыт, свой и команды, так скажем, в энциклопедическом формате – наверняка кому-то он будет полезен.]]></description><content:encoded><![CDATA[
  <p>Этой статьёй я открываю цикл материалов, посвящённых работе с большими данными. Зачем? Хочется сохранить накопленный опыт, свой и команды, так скажем, в энциклопедическом формате – наверняка кому-то он будет полезен.</p>
  <p>Проблематику больших данных постараемся описывать с разных сторон: основные принципы работы с данными, инструменты, примеры решения практических задач. Отдельное внимание окажем теме машинного обучения.</p>
  <p>Начинать надо от простого к сложному, поэтому первая статья – о принципах работы с большими данными и парадигме MapReduce.</p>
  <h2>История вопроса и определение термина</h2>
  <p>Термин Big Data появился сравнительно недавно. Google Trends показывает начало активного роста употребления словосочетания начиная с 2011 года (<a href="https://www.google.com/trends/explore" target="_blank">ссылка</a>):</p>
  <figure class="m_original">
    <img src="https://habrastorage.org/files/d4b/698/53d/d4b69853d9f94876bb922fa7d0e18939.png" width="467" />
  </figure>
  <p>При этом уже сейчас термин не использует только ленивый. Особенно часто не по делу термин используют маркетологи. Так что же такое Big Data на самом деле? Раз уж я решил системно изложить и освятить вопрос – необходимо определиться с понятием.</p>
  <p>В своей практике я встречался с разными определениями:</p>
  <p>· Big Data – это когда данных больше, чем 100Гб (500Гб, 1ТБ, кому что нравится)</p>
  <p>· Big Data – это такие данные, которые невозможно обрабатывать в Excel</p>
  <p>· Big Data – это такие данные, которые невозможно обработать на одном компьютере</p>
  <p>И даже такие:</p>
  <p>· Вig Data – это вообще любые данные.</p>
  <p>· Big Data не существует, ее придумали маркетологи.</p>
  <p>В этом цикле статей я буду придерживаться <a href="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" target="_blank">определения с wikipedia</a>:</p>
  <p><strong>Большие данные (<a href="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" target="_blank">англ.</a> big data</strong>) — серия подходов, инструментов и методов обработки структурированных и <a href="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&action=edit&redlink=1" target="_blank">неструктурированных данных</a> огромных объёмов и значительного многообразия для получения воспринимаемых человеком результатов, эффективных в условиях непрерывного прироста, распределения по многочисленным узлам <a href="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" target="_blank">вычислительной сети</a>, сформировавшихся в конце <a href="https://ru.wikipedia.org/wiki/2000-%D0%B5" target="_blank">2000-х годов</a>, альтернативных традиционным <a href="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" target="_blank">системам управления базами данных</a> и решениям класса <a href="https://ru.wikipedia.org/wiki/Business_Intelligence" target="_blank">Business Intelligence</a>.</p>
  <p>Таким образом под <strong>Big Data </strong>я буду понимать не какой-то конкретный объём данных и даже не сами данные, а методы их обработки, которые позволяют распредёлено обрабатывать информацию. Эти методы можно применить как к огромным массивам данных (таким как содержание всех страниц в интернете), так и к маленьким (таким как содержимое этой статьи).</p>
  <p>Приведу несколько примеров того, что может быть источником данных, для которых необходимы методы работы с большими данными:</p>
  <p>· Логи поведения пользователей в интернете</p>
  <p>· GPS-сигналы от автомобилей для транспортной компании</p>
  <p>· Данные, снимаемые с датчиков в большом адронном коллайдере</p>
  <p>· Оцифрованные книги в Российской Государственной Библиотеке</p>
  <p>· Информация о транзакциях всех клиентов банка</p>
  <p>· Информация о всех покупках в крупной ритейл сети и т.д.</p>
  <p>Количество источников данных стремительно растёт, а значит технологии их обработки становятся всё более востребованными.</p>
  <h2>Принципы работы с большими данными</h2>
  <p>Исходя из определения <strong>Big Data</strong>, можно сформулировать основные принципы работы с такими данными:</p>
  <p>1. <strong>Горизонтальная масштабируемость</strong>. Поскольку данных может быть сколь угодно много – любая система, которая подразумевает обработку больших данных, должна быть расширяемой. В 2 раза вырос объём данных – в 2 раза увеличили количество железа в кластере и всё продолжило работать.</p>
  <p>2. <strong>Отказоустойчивость</strong>. Принцип горизонтальной масштабируемости подразумевает, что машин в кластере может быть много. Например, Hadoop-кластер Yahoo имеет более 42000 машин (по <a href="http://www.hadoopwizard.com/which-big-data-company-has-the-worlds-biggest-hadoop-cluster/" target="_blank">этой</a> <a href="http://www.hadoopwizard.com/which-big-data-company-has-the-worlds-biggest-hadoop-cluster/" target="_blank">ссылке</a> можно посмотреть размеры кластера в разных организациях). Это означает, что часть этих машин будет гарантированно выходить из строя. Методы работы с большими данными должны учитывать возможность таких сбоев и переживать их без каких-либо значимых последствий.</p>
  <p>3. <strong>Локальность данных. </strong>В больших распределённых системах данные распределены по большому количеству машин. Если данные физически находятся на одном сервере, а обрабатываются на другом – расходы на передачу данных могут превысить расходы на саму обработку. Поэтому одним из важнейших принципов проектирования BigData-решений является принцип локальности данных – по возможности обрабатываем данные на той же машине, на которой их храним.</p>
  <p>Все современные средства работы с большими данными так или иначе следуют этим трём принципам. Для того, чтобы им следовать – необходимо придумывать какие-то методы, способы и парадигмы разработки средств разработки данных. Один из самых классических методов я разберу в сегодняшней статье.</p>
  <h2>MapReduce</h2>
  <p>Про MapReduce на хабре уже писали (<a href="http://habrahabr.ru/post/103467/" target="_blank">раз</a>, <a href="http://habrahabr.ru/company/bitrix/blog/218003/" target="_blank">два</a>, <a href="http://habrahabr.ru/post/74792/" target="_blank">три</a>), но раз уж цикл статей претендует на системное изложение вопросов Big Data – без MapReduce в первой статье не обойтись J</p>
  <p><strong>MapReduce</strong> – это модель распределенной обработки данных, предложенная компанией Google для обработки больших объёмов данных на компьютерных кластерах. MapReduce неплохо иллюстрируется следующей картинкой (взято по <a href="http://blog.sqlauthority.com/2013/10/09/big-data-buzz-words-what-is-mapreduce-day-7-of-21/" target="_blank">ссылке</a>):</p>
  <figure class="m_original">
    <img src="https://habrastorage.org/files/790/7fb/08a/7907fb08a7ab4c3f99775cf548236718.png" width="475" />
  </figure>
  <p>MapReduce предполагает, что данные организованы в виде некоторых записей. Обработка данных происходит в 3 стадии:</p>
  <p>1. <strong>Стадия Map</strong>. На этой стадии данные предобрабатываются при помощи функции map(), которую определяет пользователь. Работа этой стадии заключается в предобработке и фильтрации данных. Работа очень похожа на операцию map в функциональных языках программирования – пользовательская функция применяется к каждой входной записи.<br /><br /><strong>Функция map() примененная к одной входной записи и выдаёт множество пар ключ-значение</strong>. Множество – т.е. может выдать только одну запись, может не выдать ничего, а может выдать несколько пар ключ-значение. Что будет находится в ключе и в значении – решать пользователю, но ключ – очень важная вещь, так как данные с одним ключом в будущем попадут в один экземпляр функции reduce.</p>
  <p>2. <strong>Стадия Shuffle</strong>. Проходит незаметно для пользователя. В этой стадии вывод функции map «разбирается по корзинам» – каждая корзина соответствует одному ключу вывода стадии map. В дальнейшем эти корзины послужат входом для reduce.</p>
  <p>3. <strong>Стадия Reduce</strong>. Каждая «корзина» со значениями, сформированная на стадии shuffle, попадает на вход функции reduce().<br /><br /><strong>Функция reduce задаётся пользователем и вычисляет финальный результат для отдельной «корзины».</strong> Множество всех значений, возвращённых функцией reduce(), является финальным результатом MapReduce-задачи.</p>
  <p>Несколько дополнительных фактов про MapReduce:</p>
  <p>1) Все запуски функции <strong>map</strong> работают независимо и могут работать параллельно, в том числе на разных машинах кластера.</p>
  <p>2) Все запуски функции <strong>reduce</strong> работают независимо и могут работать параллельно, в том числе на разных машинах кластера.</p>
  <p>3) Shuffle внутри себя представляет параллельную сортировку, поэтому также может работать на разных машинах кластера. <strong>Пункты 1-3 позволяют выполнить принцип горизонтальной масштабируемости.</strong></p>
  <p>4) Функция map, как правило, применяется на той же машине, на которой хранятся данные – это позволяет снизить передачу данных по сети (принцип локальности данных).</p>
  <p>5) MapReduce – это всегда полное сканирование данных, никаких индексов нет. Это означает, что MapReduce плохо применим, когда ответ требуется очень быстро.<br /><br /></p>
  <h2>Примеры задач, эффективно решаемых при помощи MapReduce<br /><br /></h2>
  <h3>Word Count</h3>
  <p>Начнём с классической задачи – Word Count. Задача формулируется следующим образом: имеется большой корпус документов. Задача – для каждого слова, хотя бы один раз встречающегося в корпусе, посчитать суммарное количество раз, которое оно встретилось в корпусе.</p>
  <p><strong>Решение</strong>:</p>
  <p>Раз имеем большой корпус документов – пусть один документ будет одной входной записью для MapRreduce–задачи. В MapReduce мы можем только задавать пользовательские функции, что мы и сделаем (будем использовать python-like псевдокод):</p>
  <pre>def map(doc):
	for word in doc:
		yield word, 1
</pre>
  <pre>def reduce(word, values):
	yield word, sum(values)
</pre>
  <p>Функция <strong>map</strong> превращает входной документ в набор пар (слово, 1), <strong>shuffle</strong> прозрачно для нас превращает это в пары (слово, [1,1,1,1,1,1]), <strong>reduce</strong> суммирует эти единички, возвращая финальный ответ для слова.</p>
  <h3>Обработка логов рекламной системы</h3>
  <p>Второй пример взят из реальной практики <a href="http://datacentric.ru/" target="_blank">Data-Centric Alliance</a>.</p>
  <p><strong>Задача</strong>: имеется csv-лог рекламной системы вида:</p>
  <p><br /></p>
  <pre>&lt;user_id&gt;,&lt;country&gt;,&lt;city&gt;,&lt;campaign_id&gt;,&lt;creative_id&gt;,&lt;payment&gt;&lt;/p&gt;

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

</pre>
  <pre>def reduce(city, payments):
	yield city, sum(payments)/len(payments)

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

]]></content:encoded></item></channel></rss>