Как синхронизировать преобразованные данные из MongoDB в Elasticsearch с помощью Transporter в Ubuntu 16.04

Вступление

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

В Transporter вы создаете pipelines, который определяет поток данных от source (где данные читаются) к sink (где данные записываются). Источниками и приемниками могут быть базы данных SQL или NoSQL, плоские файлы или другие ресурсы. Transporter использует adaptors, которые являются подключаемыми расширениями, для взаимодействия с этими ресурсами, и проект по умолчанию включает в себя several adapters для популярных баз данных.

В дополнение к перемещению данных Transporter также позволяет изменять данные при их перемещении по конвейеру с помощью transformer. Как и адаптеры, по умолчанию включены several преобразователи. Вы также можете написать свои собственные преобразователи, чтобы настроить модификацию ваших данных.

В этом руководстве мы рассмотрим пример перемещения и обработки данных из базы данных MongoDB в Elasticsearch с использованием встроенных адаптеров Transporter и настраиваемого преобразователя, написанного на JavaScript.

Предпосылки

Чтобы следовать этому уроку, вам понадобится:

Транспортирующие конвейеры написаны на JavaScript. Вам не понадобятся какие-либо предварительные знания или опыт работы с JavaScript, чтобы следовать этому руководству, но вы можете узнать больше в these руководства по JavaScript.

Шаг 1 - Установка Transporter

Transporter предоставляет двоичные файлы для большинства распространенных операционных систем. Процесс установки Ubuntu состоит из двух этапов: загрузка бинарного файла Linux и его запуск.

Во-первых, получите ссылку на последнюю версию на странице последних выпусков Transporter на GitHub. Скопируйте ссылку, которая заканчивается на + -linux-amd64 +. В этом руководстве используется версия 0.2.2, которая является самой последней на момент написания.

Загрузите двоичный файл в свой домашний каталог.

cd
wget https://github.com/compose/transporter/releases/download/v/transporter--linux-amd64

Move это в + / usr / local / bin + или в ваш предпочтительный установочный каталог.

mv transporter-*-linux-amd64 /usr/local/bin/transporter

Затем сделайте его исполняемым, чтобы вы могли запустить его.

chmod +x /usr/local/bin/

Вы можете проверить, что Transporter настроен правильно, запустив бинарный файл.

transporter

Вы увидите вывод справки об использовании и номер версии:

OutputUSAGE
 transporter <command> [flags]

COMMANDS
 run       run pipeline loaded from a file
 . . .

VERSION

Чтобы использовать Transporter для перемещения данных из MongoDB в Elasticsearch, нам нужны две вещи: данные в MongoDB, которые мы хотим переместить, и конвейер, который сообщает Transporter, как его перемещать. На следующем шаге создаются некоторые примеры данных, но если у вас уже есть база данных MongoDB, которую вы хотите переместить, вы можете пропустить следующий шаг и перейти сразу к шагу 3.

Шаг 2 - Добавление примеров данных в MongoDB (необязательно)

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

Сначала подключитесь к вашей базе данных MongoDB.

mongo

Это изменит ваше приглашение на + mongo> +, указывая, что вы используете оболочку MongoDB.

Отсюда выберите базу данных для работы. Мы назовем наш + my_application +.

use my_application

В + MongoDB + вам не нужно явно создавать базу данных или коллекцию. Как только вы начнете добавлять данные в базу данных, которую вы выбрали по имени, эта база данных будет создана автоматически.

Итак, чтобы создать базу данных + my_application +, сохраните два документа в ее коллекции + users +: один, представляющий Sammy Shark, и один, представляющий Gilly Glowfish. Это будут наши тестовые данные.

db.users.save({"firstName": "Sammy", "lastName": "Shark"});
db.users.save({"firstName": "Gilly", "lastName": "Glowfish"});

После добавления документов вы можете запросить коллекцию + users +, чтобы просмотреть ваши записи.

db.users.find().pretty();

Вывод будет выглядеть аналогично выводу ниже, но столбцы + _id + будут другими. MongoDB автоматически добавляет идентификаторы объектов для уникальной идентификации документов в коллекции.

output{
 "_id" : ObjectId("59299ac7f80b31254a916456"),
 "firstName" : "Sammy",
 "lastName" : "Shark"
}
{
 "_id" : ObjectId("59299ac7f80b31254a916457"),
 "firstName" : "Gilly",
 "lastName" : "Glowfish"
}

Нажмите + CTRL + C +, чтобы выйти из оболочки MongoDB.

Далее, давайте создадим конвейер Transporter для перемещения этих данных из MongoDB в Elasticsearch.

Шаг 3 - Создание базового конвейера

Конвейер в Transporter определяется файлом JavaScript с именем + pipeline.js + по умолчанию. Встроенная команда + init + создает основной configuration файл в правильном каталоге, учитывая источник и приемник.

Инициализируйте стартовый + pipe.js + с MongoDB в качестве источника и Elasticsearch в качестве приемника.

transporter init mongodb elasticsearch

Вы увидите следующий вывод:

OutputWriting pipeline.js...

Вам не нужно изменять + pipeline.js + для этого шага, но давайте посмотрим, как он работает.

Файл выглядит следующим образом, но вы также можете просмотреть его содержимое с помощью команды + cat pipe.js +, + less pipeline.js + (выйти из + less + нажатием + q +) или открыв его в вашем любимом текстовом редакторе.

pipeline.js

var source = mongodb({
 "uri": "${MONGODB_URI}"
 // "timeout": "30s",
 // "tail": false,
 // "ssl": false,
 // "cacerts": ["/path/to/cert.pem"],
 // "wc": 1,
 // "fsync": false,
 // "bulk": false,
 // "collection_filters": "{}",
 // "read_preference": "Primary"
})

var sink = elasticsearch({
 "uri": "${ELASTICSEARCH_URI}"
 // "timeout": "10s", // defaults to 30s
 // "aws_access_key": "ABCDEF", // used for signing requests to AWS Elasticsearch service
 // "aws_access_secret": "ABCDEF" // used for signing requests to AWS Elasticsearch service
 // "parent_id": "elastic_parent" // defaults to "elastic_parent" parent identifier for Elasticsearch
})

t.Source("source", source, "/.*/").Save("sink", sink, "/.*/")

Строки, начинающиеся с + var source + и + var sink +, определяют JavaScript variable для MongoDB и Elasticsearch адаптеры, соответственно. Мы определим переменные окружения + MONGODB_URI + и + ELASTICSEARCH_URI +, которые нужны этим адаптерам позже на этом шаге.

Строки, начинающиеся с + // +, являются комментариями. Они выделяют некоторые общие параметры конфигурации, которые вы можете установить для своего конвейера, но мы не используем их для базового конвейера, который мы создаем здесь.

Последняя строка соединяет источник и приемник. Переменная + transporter + или + t + позволяет нам получить доступ к нашему конвейеру. Мы используем + .Source () + и + .Save () + functions, чтобы добавить источник и приемник с использованием переменных + source + и + sink +, определенных ранее в файле.

Третий аргумент функций + Source () + и + Save () + - это пространство имен +. + Передача + /. * / + В качестве последнего аргумента означает, что мы хотим передать все данные из MongoDB и сохраните их в том же пространстве имен в Elasticsearch.

Прежде чем мы сможем запустить этот конвейер, нам нужно установить https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux- vps [переменные окружения] для MongoDB URI и https://www.elastic.co/guide/en/elasticsearch/reference/current/ modules-network.html [Elasticsearch URI]. В примере, который мы используем, оба размещаются локально с настройками по умолчанию, но не забудьте настроить эти параметры, если вы используете существующие экземпляры MongoDB или Elasticsearch.

export MONGODB_URI='mongodb://localhost/my_application'
export ELASTICSEARCH_URI='http://localhost:9200/my_application'

Теперь мы готовы запустить трубопровод.

transporter run pipeline.js

Вы увидите вывод, который заканчивается так:

Output. . .
INFO[0001] metrics source records: 2                     path=source ts=1522942118483391242
INFO[0001] metrics source/sink records: 2                path="source/sink" ts=1522942118483395960
INFO[0001] exit map[source:mongodb sink:elasticsearch]   ts=1522942118483396878

Во второй и третьей к последней строке этот вывод показывает, что в источнике было 2 записи и 2 записи были перемещены в приемник.

Чтобы подтвердить, что обе записи были обработаны, вы можете запросить у Elasticsearch содержимое базы данных + my_application +, которая должна теперь существовать.

curl $ELASTICSEARCH_URI/_search?pretty=true

Параметр +? Pretty = true + облегчает чтение выходных данных:

Output{
 "took" : 5,
 "timed_out" : false,
 "_shards" : {
   "total" : 5,
   "successful" : 5,
   "skipped" : 0,
   "failed" : 0
 },
 "hits" : {
   "total" : 2,
   "max_score" : 1.0,
   "hits" : [
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e9c6687d9f638ced4fe",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Gilly",
         "lastName" : "Glowfish"
       }
     },
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e986687d9f638ced4fd",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Sammy",
         "lastName" : "Shark"
       }
     }
   ]
 }
}

Базы данных и коллекции в MongoDB аналогичны индексам и типам в Elasticsearch. Имея это в виду, вы должны увидеть:

  • Поле + _index + установлено в + my_application, + имя исходной базы данных MongoDB).

  • Поле + _type + установлено в + users, + имя коллекции MongoDB.

  • Поля + firstName + и + lastName + заполнены соответственно полями «Sammy», «Shark» и «Gilly», «Glowfish».

Это подтверждает, что обе записи из MongoDB были успешно обработаны через Transporter и загружены в Elasticsearch. Чтобы построить этот базовый конвейер, мы добавим промежуточный этап обработки, который может преобразовать входные данные.

Шаг 4 - Создание Трансформера

Как следует из названия, transformers изменяет исходные данные перед загрузкой в ​​приемник. Например, они позволяют добавить новое поле, удалить поле или изменить данные поля. Transporter поставляется с некоторыми предопределенными преобразователями, а также поддержкой пользовательских.

Как правило, пользовательские преобразователи записываются как функции JavaScript и сохраняются в отдельном файле. Чтобы использовать их, вы добавляете ссылку на файл трансформера в + pipeline.js +. Transporter включает в себя как JavaScript-движки Otto, так и Goja. Поскольку Goja новее и, как правило, быстрее, мы будем использовать его здесь. Единственным функциональным отличием является синтаксис.

Создайте файл с именем + transform.js +, который мы будем использовать для написания нашей функции преобразования.

nano transform.js

Вот функция, которую мы будем использовать, которая создаст новое поле с именем + fullName +, значением которого будут поля + firstName + и + lastName +, объединенные вместе, разделенные пробелом (например, `+ Sammy Shark + `).

transform.js

function transform(msg) {
   msg.data.fullName = msg.data.firstName + " " + msg.data.lastName;
   return msg
}

Давайте пройдемся по строкам этого файла:

  • Первая строка файла, + function transform (msg), +, - это определение функции функции https://www.digitalocean.com/community/tutorials/how-to-define-functions-in-javascript].

  • + msg + - это JavaScript объект, содержащий подробности исходного документа. Мы используем этот объект для access data, проходящего через конвейер.

  • Первая строка функции concatenates два существующих поля и https: // www .digitalocean.com / community / tutorials / понимание-objects-in-javascript # добавление-и-изменение-объект-свойства [присваивает это значение] новому полю + fullName +.

  • Последняя строка функции возвращает недавно измененный объект + msg + для использования остальной частью конвейера.

Сохраните и закройте файл.

Далее нам нужно изменить конвейер для использования этого преобразователя. Откройте файл + pipeline.js + для редактирования.

nano pipeline.js

В последней строке нам нужно добавить вызов в функцию + Transform () +, чтобы добавить преобразователь в конвейер между вызовами + Source () + и + Save () +, вот так :

~ / Транспортеров / pipeline.js

. . .
t.Source("source", source, "/.*/")

.Save("sink", sink, "/.*/")

Аргумент, передаваемый в + Transform () +, является типом преобразования, в данном случае это Goja. Используя функцию + goja +, мы указываем имя файла преобразователя, используя его https://www.digitalocean.com/community/tutorials/basic-linux-navigation-and-file-management#moving-around-the- файловая система с-quot-cd-quot [относительный путь].

Сохраните и закройте файл. Прежде чем мы повторно запустим конвейер для тестирования преобразователя, давайте удалим существующие данные в Elasticsearch из предыдущего теста.

curl -XDELETE $ELASTICSEARCH_URI

Вы увидите этот вывод, подтверждающий успех команды.

Output{"acknowledged":true}

Теперь перезапустите конвейер.

transporter run pipeline.js

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

curl $ELASTICSEARCH_URI/_search?pretty=true

Вы можете увидеть поле + fullName + в новом выводе:

Output{
 "took" : 9,
 "timed_out" : false,
 "_shards" : {
   "total" : 5,
   "successful" : 5,
   "skipped" : 0,
   "failed" : 0
 },
 "hits" : {
   "total" : 2,
   "max_score" : 1.0,
   "hits" : [
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e9c6687d9f638ced4fe",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Gilly",

         "lastName" : "Glowfish"
       }
     },
     {
       "_index" : "my_application",
       "_type" : "users",
       "_id" : "5ac63e986687d9f638ced4fd",
       "_score" : 1.0,
       "_source" : {
         "firstName" : "Sammy",

         "lastName" : "Shark"
       }
     }
   ]
 }
}

Обратите внимание, что поле + fullName + было добавлено в оба документа с правильно установленными значениями. Теперь мы знаем, как добавить пользовательские преобразования в конвейер Transporter.

Заключение

Вы создали базовый конвейер Transporter с преобразователем для копирования и изменения данных из MongoDB в Elasticsearch. Таким же образом можно применять более сложные преобразования, объединять несколько преобразований в одном конвейере и многое другое. MongoDB и Elasticsearch - это только два адаптера, которые поддерживает Transporter. Он также поддерживает простые файлы, базы данных SQL, такие как Postgres, и многие другие источники данных.

Вы можете проверить Transporter проект на GitHub, чтобы оставаться в курсе последних изменений в API, и посетить the Transporter wiki для получения более подробной информации о том, как использовать адаптеры, трансформаторы и другие функции Transformer.

Related