Как говорится, никогда такого не было, и вот опять. Мы подумали и решили выложить в свободный доступ первую лабораторную работу нашей новой программы Data Engineer. Бесплатно. Без смс.


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



Так вот. Потенциально каждый самостоятельно может пройти эту лабу и почувствовать себя немножко этим дата инженером. Для этого будет все, что требуется.


А делать в этой лабе мы будем следующее.


  1. Зарегимся на облачном сервисе.
  2. Поднимем на нем 4 виртуальных машины.
  3. Развернем кластер при помощи Ambari.
  4. Поднимем сайт на nginx на одной из виртуалок.
  5. Добавим специальный javascript на каждую страницу этого сайта.
  6. Соберем кликстрим на HDFS.
  7. Соберем его же в Kafka.

Лаба 1. Поднять свой сайт и организовать сбор кликстрима в Kafka



1. Развертывание виртуальных машин


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


Проанализировав различные облачные платформы, мы пришли к выводу, что наилучшим вариантом на текущий момент для нас будет Google Cloud Platform. Там при регистрации дают $300, которые можно потратить в течение года на любые сервисы. Этого должно хватить на всю программу при аккуратном использовании. В частности, нужно выключать машины, когда они не используются.


После регистрации вам предложат создать свой новый проект и назвать его. Название может быть любым. Можете быть оригинальными.


Зайдите в раздел Metadata, далее во вкладку SSH Keys. Сюда вы можете вставить значение вашего pub-ключа, чтобы потом зайти на любую машину со своим private-key. Здесь на GPC подробно написано, как можно создать свой ключ с нуля на MacOS и Windows. В итоге после добавления ключа у вас должно получиться что-то такое:



Далее вам нужно будет попасть в раздел Compute Engine, после чего в подраздел VM Instances, где мы и создадим 4 виртуальных машины для нашего кластера.


Тип машины: 4 vCPUs, 15 GB memory. Операционная система: Ubuntu 16.04 и диск на 30 ГБ.


Создайте 2 таких машины в регионе europe-west1-b и еще 2 в регионе europe-west2-b. К сожалению, у GCP есть квоты на количество CPU в одном регионе, которые можно изменить только, если у вас не free-аккаунт. На них вы автоматом сможете зайти с тем ключом, который добавили ранее.


Следующее действие — зарезервировать статический IP для вашей мастер-ноды. Это потребует примерно $10 из тех $300 за всё время программы. Поскольку придется включать и выключать машины, то для дальнейшего удобства это будет необходимо. Для этого перейдите из раздела Compute Engine в раздел VPC Network. Далее вкладка External IP addresses. Там в списке ваших серверов найдите тот, который вы собираетесь сделать мастер-нодой, и нажмите на Ephemeral. Там можно сделать резерв этого IP в качестве статического.


Участники программы должны будут скинуть этот IP нам, и мы в свою очередь натравим нашу пушку на их сайт, снабдив необходимыми кликами.


2. Установка Hortonworks HDP


Подробный мануал о том, как устанавливать HDP через Ambari изложен здесь. Решили вынести это в отдельный документ, потому что часть из вас это может выполнить полузакрытыми глазами.


Важное замечание. Для участников при построения всего пайплайна обработки данных потребуется большое количество разных инструментов. Для непосредственно этой лабы может быть достаточно самых необходимых компонентов: HDFS, YARN + MapReduce2, ZooKeeper, Kafka.


3. Развертывание своего сайта


Скачайте архив со статическим сайтом по этой ссылке себе на сервер со статическим IP. Разархивируйте его по пути /var/www/dataengineer/. В принципе, вы можете спарсить любой сайт. Для нас просто важно, чтобы у участников нашей программы была одна и та же версия сайта.


Следующий шаг — установка nginx.


Выполните следующие команды:


$ sudo apt-get install -y python-software-properties software-properties-common
$ sudo add-apt-repository -y ppa:nginx/stable
$ sudo apt-get update
$ sudo apt-get install nginx

Чтобы ваш сайт поднялся и был доступен из браузера, необходимо создать следующий конфиг в /etc/nginx/sites-enabled/default.


server {
     listen 80 default_server;
     listen [::]:80;
     server_name _;
     root /var/www/dataengineer;
          location / {
                  index index.html;
                  alias /var/www/dataengineer/skyeng.ru/;
                  default_type text/html;
          }
          location /tracking/ {
                proxy_pass http://localhost:8290/tracking/;
          }
}

Теперь в браузере попробуйте набрать ваш ip в браузерной строке, и вы должны будете попасть на свою копию сайта.


4. Установка и конфигурирование Divolte


Отлично, копия сайта у нас поднята, кластер развернут. Теперь как-то надо организовать сбор кликстрима с этого сайта на наш кластер. Для этой задачи предлагаем воспользоваться инструментом Divolte, который позволяет довольно удобно собирать клики и сохранять их в HDFS или отправлять в Kafka. Мы попробуем оба варианта.


Перед установкой этого инструмента нам потребуется установить Java 8-й версии.


На всякий случай проверим, что ее у нас, действительно, нет.


$ java -version

Если вы видите, что-то подобное, то это значит, что ее у вас нет:


The program 'java' can be found in the following packages:
  • default-jre
  • gcj-4.8-jre-headless
  • openjdk-7-jre-headless
  • gcj-4.6-jre-headless
  • openjdk-6-jre-headless
    Try: sudo apt-get install <selected package>

Для установки Java воспользуйтесь следующими командами:


$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer

Далее добавим путь к Java в окружение:


$ sudo nano /etc/environment

Там нужно вставить следующую строчку JAVA_HOME="/usr/lib/jvm/java-8-oracle" и сохранить файл.


Далее:


$ source /etc/environment
$ echo $JAVA_HOME

Результат должен быть таким:


/usr/lib/jvm/java-8-oracle

Еще раз проверим:


$ java -version

java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

Теперь можем переходить непосредственно к Divolte.


Возьмите актуальную версию этого инструмента отсюда и скачайте себе на мастер.


Далее:


$ tar -xzf divolte-collector-*.tar.gz
$ cd divolte-collector-*
$ touch conf/divolte-collector.conf

Перейдите в папку conf. Переименуйте файл divolte-env.sh.example в divolte-env.sh. Отредактируйте его, добавив туда:


HADOOP_CONF_DIR=/usr/hdp/2.6.2.0-205/hadoop/conf


Теперь очередь divolte-collector.conf. Туда добавьте следующее:


divolte {
  global {
    hdfs {
      client {
        fs.defaultFS = "hdfs://node1.c.data-engineer-173012.internal:8020"
      }
      // Enable HDFS sinks.
      enabled = true

      // Use multiple threads to write to HDFS.
      threads = 2
    }
  }

  sinks {
    // The name of the sink. (It's referred to by the mapping.)
    hdfs {
      type = hdfs

      // For HDFS sinks we can control how the files are created.
      file_strategy {
        // Create a new file every hour
        roll_every = 1 hour

        // Perform a hsync call on the HDFS files after every 1000 records are written
        // or every 5 seconds, whichever happens first.

        // Performing a hsync call periodically can prevent data loss in the case of
        // some failure scenarios.
        sync_file_after_records = 1000
        sync_file_after_duration = 5 seconds

        // Files that are being written will be created in a working directory.
        // Once a file is closed, Divolte Collector will move the file to the
        // publish directory. The working and publish directories are allowed
        // to be the same, but this is not recommended.
        working_dir = "/divolte/inflight"
        publish_dir = "/divolte/published"
      }

      // Set the replication factor for created files.
      replication = 3
    }
  }

  sources {
    a_source {
      type = browser
      prefix = /tracking
    }
  }
}

Этот конфиг позволит вам сохранять кликстрим на HDFS. Обратите внимание, что в fs.defaultFS вам нужно добавить FQDN вашего сервера.


Чтобы всё заработало, надо сделать две вещи. Первая — это создать на HDFS две папки, которые мы указали в конфиге в working_dir и publish_dir. Для этого перейдите под юзера hdfs:


$ sudo su hdfs
$ hdfs dfs -mkdir /divolte
$ hdfs dfs -mkdir /divolte/inflight
$ hdfs dfs -mkdir /divolte/published

Поменяем права на директорию divolte, чтобы был доступ к записи у других юзеров:


$ hdfs dfs -chmod -R 0777 /divolte

Вторая вещь — это добавить скрипт на все страницы вашей копии сайта. Скрипт выглядит следующим образом:


<script type="text/javascript" src="/tracking/divolte.js" defer async></script>

Один из способов — это воспользоваться sed. Например, такой командой можно добавить скрипт в низ страницы index.html:


sed -i 's#</body>#<script type="text/javascript" src="/tracking/divolte.js" defer async></script> \n</body>#g' index.html

Важно! Подумайте, как это распространить на все страницы.


Просто поставить * не сильно поможет, потому что внутри директории с сайтом существуют поддиректории, и sed будет на них ругаться. Подробнее про sed можно почитать здесь. Или придумайте свой способ с нуля.


Как только решите эту задачу, можете запустить divolte:


ubuntu@node1:~/divolte-collector-0.6.0$ ./bin/divolte-collector

Увидеть вы должны что-то такое:


ubuntu@node1:~/divolte-collector-0.5.0/bin$ ./divolte-collector

2017-07-12 15:12:29.463Z [main] INFO [Version]: HV000001: Hibernate Validator 5.4.1.Final

2017-07-12 15:12:29.701Z [main] INFO [SchemaRegistry]: Using builtin default Avro schema.

2017-07-12 15:12:29.852Z [main] INFO [SchemaRegistry]: Loaded schemas used for mappings: [default]

2017-07-12 15:12:29.854Z [main] INFO [SchemaRegistry]: Inferred schemas used for sinks: [hdfs]

2017-07-12 15:12:30.112Z [main] WARN [NativeCodeLoader]: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable

2017-07-12 15:12:31.431Z [main] INFO [Server]: Initialized sinks: [hdfs]

2017-07-12 15:12:31.551Z [main] INFO [Mapping]: Using built in default schema mapping.

2017-07-12 15:12:31.663Z [main] INFO [UserAgentParserAndCache]: Using non-updating (resource module based) user agent parser.

2017-07-12 15:12:32.262Z [main] INFO [UserAgentParserAndCache]: User agent parser data version: 20141024-01

2017-07-12 15:12:37.363Z [main] INFO [Slf4jErrorManager]: 0 error(s), 0 warning(s), 87.60016870518768% typed

2017-07-12 15:12:37.363Z [main] INFO [JavaScriptResource]: Pre-compiled JavaScript source: divolte.js

2017-07-12 15:12:37.452Z [main] INFO [GzippableHttpBody]: Compressed resource: 9828 -> 4401

2017-07-12 15:12:37.592Z [main] INFO [BrowserSource]: Registered source[a_source] script location: /tracking/divolte.js

2017-07-12 15:12:37.592Z [main] INFO [BrowserSource]: Registered source[a_source] event handler: /tracking/csc-event

2017-07-12 15:12:37.592Z [main] INFO [Server]: Initialized sources: [a_source]

2017-07-12 15:12:37.779Z [main] INFO [Server]: Starting server on 0.0.0.0:8290

2017-07-12 15:12:37.867Z [main] INFO [xnio]: XNIO version 3.3.6.Final

2017-07-12 15:12:37.971Z [main] INFO [nio]: XNIO NIO Implementation Version 3.3.6.Final

Если нет и появляется ошибка про JAVA, то перезайдите на машину.


Зайдите теперь на свой сайт и покликайте, попереходите на разные страницы. Вернитесь в терминал и нажмите Ctrl+C. Теперь посмотрите, появилось ли что-то в папке /divolte/published на HDFS. Если да, значит у вас всё работает, и вы научились собирать кликстрим!


5. Задача


Ваша задача теперь — сделать так, чтобы он собирался не на HDFS, а в Kafka.


6. Ссылки для изучения



P.S. Да, лаба похоже местами на инструкцию. Но в этом есть необходимость особенно на старте программы. Эта лаба создает тот фундамент, от которого все будут отталкиваться в построении своего пайплайна данных. Хочется быть уверенными, что у всех всё сделано правильно на старте.

Комментарии (2)


  1. jbionic
    29.10.2017 20:48

    Зарегимся на облачном сервисе.
    Поднимем на нем 4 виртуальных машины.
    Развернем кластер при помощи Ambari.
    Поднимем сайт на nginx на одной из виртуалок.
    Добавим специальный javascript на каждую страницу этого сайта.
    Соберем кликстрим на HDFS.
    Соберем его же в Kafka.


    Простите, а не могли бы Вы пояснить подробнее в комментарии, зачем всё вышеперечисленное нужно?


    1. a-pichugin Автор
      29.10.2017 20:51

      Конечно :)

      Что мы хотим сделать в целом — это построить пайплайн обработки данных: от их сбора с нашего сайта (кликстрим) до их визуализации в каком-нибудь BI-инструменте. В промежутке разный ML.

      Соответственно, в нашей первой лабе мы только начинаем этот процесс. Разворачиваем кластер со всеми сервисами, которые могут понадобиться позднее. Поднимаем «учебный сайт», с которого и будем собирать данные и т.д.