Шаблон для загрузки данных в Elasticsearch с SQL-сервера

Вот что мы придумали. Используя столбец состояния с 3 значениями.

0 = Not indexed
1 = Updated
2 = Indexed

Будет 2 работы...

Задание 1 выберет первые X записей, где статус = 0, и поместит их в очередь, например RabitMQ. Затем потребитель массово вставит эти записи в ES и обновит статус записей БД до 1.

Для обновлений, поскольку мы контролируем наши данные... Сохраненная процедура SQL, которая обновляет эту конкретную запись, установит ее статус на 2. Job2 выберет верхние x записей, где статус = 2, и вытолкнет их на RabitMQ. Затем потребитель массово вставит эти записи в ES и обновит статус записей БД до 1.

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

Итак, я знаю, что есть реки (но они устарели и, вероятно, не гибки, как ETL)

Я хотел бы массово вставлять записи с моего SQL-сервера в Elasticsearch.

Напишите какое-нибудь запланированное пакетное задание, будь то ETL или любой другой инструмент, не имеет значения.

выберите из таблицы, где id › lastIdInsertedToElasticSearch, это позволит загружать последние записи в Elasticsearch с заданным интервалом.

Но что, если запись обновляется на сервере SQL? Что было бы хорошим шаблоном для отслеживания обновленных записей на сервере SQL, а затем отправки обновленных записей в ES? Я знаю, что у ES есть версии документов при указании одного и того же идентификатора. Но, кажется, не может визуализировать закономерность.


person user432024    schedule 04.07.2014    source источник
comment
Вам не кажется это слишком сложным? Какое преимущество вы особенно получаете от этого решения, чем просто использовать очередь для записи/обновления и позволить приложению помещаться в очередь? Я спрашиваю об этом, потому что кажется, что вам придется взломать какую-то блокировку, чтобы добиться этого, поскольку вы уже упоминали, что вам нужно будет поддерживать статус для очереди. И, честно говоря, единственный прирост производительности, который ваше приложение увидит в этом решении, — это отсутствие записи в RabbitMQ, что будет незначительным, если ваше приложение и Rabbit находятся в одном центре обработки данных.   -  person vaidik    schedule 05.07.2014
comment
Поэтому я предлагаю вам выбрать простоту вместо этого незначительного прироста производительности, потому что это только усложнит вашу жизнь, когда что-то пойдет не так, и затруднит отладку вашего приложения и потребительской логики.   -  person vaidik    schedule 05.07.2014
comment
Столбец состояния не для производительности. Это нужно для того, чтобы узнать, какие записи из БД уже были вставлены в Elasticsearch и какие записи были обновлены в БД, чтобы затем пакетное задание могло обновить Elasticsearch.   -  person user432024    schedule 07.07.2014


Ответы (2)


Так что ИМХО, пакетные вставки хороши для построения или перестроения индекса. Таким образом, вы впервые можете запускать пакетные задания, выполняющие SQL-запросы и выполняющие массовые обновления. Реки, как вы правильно заметили, не обеспечивают большой гибкости с точки зрения трансформации.

Если записи в вашем хранилище данных SQL созданы вами (т.е. какой-то кодовой базой под вашим контролем), то лучше, чтобы эта же кодовая база обновляла документы в Elasticsearch, может быть не напрямую, а уведомляя какой-то другой сервис или с помощью очереди, чтобы не тратить время на ответы на запросы (если у вас такая настройка).

У нас есть довольно похожий вариант использования Elasticsearch. Мы предоставляем поиск внутри нашего приложения, которое выполняет поиск по различным категориям данных. Некоторые из этих данных на самом деле создаются пользователями нашего приложения через наше приложение, поэтому мы справляемся с этим легко. Наше приложение записывает эти данные в наше хранилище данных SQL и отправляет те же данные в RabbitMQ для индексации/обновления в Elasticsearch. С другой стороны RabbitMQ у нас есть потребитель, написанный на Python, который фактически заменяет весь документ в Elasticsearch. Таким образом, соответствующие строки в нашем хранилище данных SQL и документы в Elasticsearch имеют общий идентификатор, который позволяет нам обновлять документ.

Другой случай, когда есть несколько типов данных, по которым мы выполняем поиск, поступает от какой-то сторонней службы, которая предоставляет данные через свой HTTP API. Создание данных находится под нашим контролем, но у нас нет автоматического механизма обновления записей в Elasticsearch. В этом случае мы в основном запускаем задание cron, которое позаботится об этом. Нам удалось настроить расписание cron, потому что у нас также есть ограниченная квота на количество запросов к API. Но в этом случае наши данные не так сильно обновляются в день. Так что такая система у нас работает.

person vaidik    schedule 04.07.2014
comment
Я проголосую за ваш ответ, потому что ни одна система не похожа на другую, но они всегда похожи! Но полезно знать, как ведут себя разные системы. Мне нравится идея RabitMQ. И я обновлю свой вопрос тем, что придумал. - person user432024; 04.07.2014

Отказ от ответственности: я участвовал в разработке этого решения.

Мне нужно было что-то вроде jdbc-river, которое могло бы выполнять более сложные "свертывания" данные. После тщательного рассмотрения того, что потребуется для изменения jdbc-river в соответствии с моими потребностями, я написал river -net.

Вот некоторые особенности:

  • Он имеет довольно приличную производительность (сравнимую с jdbc-river. Мы получаем более 6 тыс. строк в секунду).
  • Он может объединять множество таблиц для создания сложных вложенных массивов документов без создания дубликатов дочерних документов.
  • Он следует многим тем же соглашениям, что и jdbc-river.
  • Он также поддерживает чтение из файлов.
  • Он написан на С#
  • Он использует Quartz.Net и поддерживает выражения cron для планирования.

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

Чтобы бороться с большими обновлениями, мы не обращаемся к таблицам напрямую. Вместо этого мы используем stored procedures, которые захватывают только дельты. У нас также есть возможность на sp сбросить дельту для переиндексации всего.

Проект довольно молодой, всего несколько коммитов, но мы открыты для сотрудничества и новых идей.

person Josh C.    schedule 04.07.2014
comment
А что с рекой он выбирает все записи из таблицы и по ним выдает дельты? Что произойдет, если у вас есть миллионы строк? - person user432024; 04.07.2014
comment
@user432024 user432024 мы не нажимаем столы напрямую. Вместо этого мы нажимаем хранимые процедуры, и да, мы только хватаем дельты. У нас также есть возможность на SP сбросить дельту. - person Josh C.; 04.07.2014
comment
Я имею в виду, что река ES делает что-то вроде выбора * из таблицы. Для меня это означает, что он возвращает каждую запись. Поэтому, если у вас есть записи большого количества, например 5 миллионов, это не самая эффективная вещь. - person user432024; 07.07.2014
comment
@ user432024 мы поддерживаем миллиард записей в elasticsearch с помощью river-net. Мы используем хранимые процедуры вместо прямого выбора из таблицы, и в каждой хранимой процедуре мы удостоверяемся, что выбираем только то, что изменилось. - person Josh C.; 07.07.2014
comment
Ах, это имеет больше смысла ... Ах, хорошо, так как вы отслеживаете новые записи на сервере SQL и отправляете их только в ES, и как вы отслеживаете, обновляются ли записи в базе данных SQL и отправляете их в ES? В основном, как вы проверяете дельты? - person user432024; 07.07.2014
comment
@user432024 user432024 в зависимости от версии SQL Server этот ответ будет различаться. Вероятно, вам следует задать это в отдельном вопросе SO. - person Josh C.; 07.07.2014
comment
Хоть пошутите! Просто любопытно! :) Может быть, подскажете, что искать... - person user432024; 07.07.2014
comment
метки времени, триггеры, CDC (msdn.microsoft.com/en-us/library/ bb933994.aspx)... - person Josh C.; 07.07.2014