PostgreSQL для хранилища данных:Наилучший подход для ETL / извлечения данных практически в реальном времени

StackOverflow https://stackoverflow.com/questions/2519985

Вопрос

Предыстория:

У меня есть база данных PostgreSQL (версия 8.3), которая сильно оптимизирована для OLTP.

Мне нужно извлекать из него данные в режиме полуреального времени (кто-нибудь обязательно спросит, что означает полуреальное время, и я отвечу так часто, как только смогу, но я буду прагматичен, в качестве эталона допустим, мы надеемся на каждые 15 минут) и загружать их в хранилище данных.

Сколько данных?В пиковые периоды мы говорим примерно о 80-100 тысячах строк в минуту на стороне OLTP, в нерабочее время этот показатель значительно снизится до 15-20 тысяч.Наиболее часто обновляемые строки составляют ~ 64 байта каждая, но существуют различные таблицы и т.д., Поэтому данные довольно разнообразны и могут составлять до 4000 байт на строку.OLTP активен 24x5,5.

Лучшее решение?

Из того, что я могу собрать воедино, наиболее практичное решение заключается в следующем:

  • Создайте ТРИГГЕР для записи всех действий DML во вращающийся файл журнала CSV
  • Выполняйте любые необходимые преобразования
  • Используйте собственный инструмент DW data pump для эффективной перекачки преобразованного CSV-файла в DW

Почему такой подход?

  • ТРИГГЕРЫ позволяют настраивать целевые таблицы, а не быть общесистемными + выходные данные настраиваются (т.е.в CSV) и относительно просты в написании и развертывании.SLONY использует аналогичный подход, и накладные расходы приемлемы
  • CSV легко и быстро преобразуется
  • Легко перекачивать CSV в DW

Рассмотрены альтернативные варианты ....

  • Использование собственного ведения журнала (http://www.postgresql.org/docs/8.3/static/runtime-config-logging.html).Проблема в том, что это выглядело очень многословно по отношению к тому, что мне было нужно, и было немного сложнее разобрать и преобразовать.Однако это могло бы быть быстрее, поскольку я предполагаю, что накладные расходы меньше по сравнению с ТРИГГЕРОМ.Конечно, это упростило бы администрирование, поскольку оно является общесистемным, но опять же, мне не нужны некоторые таблицы (некоторые используются для постоянного хранения сообщений JMS, которые я не хочу регистрировать)
  • Запрашивает данные напрямую через инструмент ETL , такой как Talend , и перекачивает их в DW ...проблема в том, что схему OLTP необходимо было бы доработать для поддержки этого, а это имеет много негативных побочных эффектов
  • Использование измененного / взломанного SLONY - SLONY хорошо справляется с протоколированием и переносом изменений на ведомое устройство, поэтому концептуальная основа есть, но предлагаемое решение просто кажется проще и чище
  • Используя WAL

Кто-нибудь делал это раньше?Хотите поделиться своими мыслями?

Это было полезно?

Решение

Предполагая, что интересующие вас таблицы имеют (или могут быть дополнены) уникальный, индексированный, последовательный ключ, тогда вы получите гораздо большую ценность от простого выпуска SELECT ... FROM table ... WHERE key > :last_max_key с выводом в файл, где last_max_key является последним значением ключа из последнего извлечения (0, если первое извлечение.) Это инкрементный, несвязанный подход позволяет избежать представляя задержка срабатывания в пути вставки данных (будь то пользовательские триггеры или модифицированный Slony), и в зависимости от ваших настроек может лучше масштабироваться с увеличением количества процессоров и т.д.(Однако, если вам также необходимо трек UPDATEs, и последовательный ключ был добавлен вами, затем ваш UPDATE заявления должны SET ключевой столбец для NULL таким образом, он получает новое значение и выбирается при следующем извлечении.Ты бы так и сделал не иметь возможности отслеживать DELETEs без триггера.) Это то, что вы имели в виду, когда упомянули Talend?

Я бы так и сделал не используйте средство ведения журнала, если только вы не можете реализовать описанное выше решение;ведение журнала , скорее всего, включает в себя блокировка накладных расходов чтобы убедиться, что строки журнала записываются последовательно и не перекрывают / перезаписывают друг друга, когда несколько серверных систем записывают данные в журнал (проверьте источник Postgres.) Накладные расходы на блокировку могут не быть катастрофическими, но вы можете обойтись без них, если сможете использовать инкрементный SELECT альтернатива.Более того, протоколирование заявления заглушило бы любые полезные ПРЕДУПРЕЖДЕНИЯ или сообщения ОБ ОШИБКАХ, а также сам синтаксический анализ не будет мгновенным.

Если только вы не готовы анализировать WALS (включая отслеживание состояния транзакции и готовность переписывать код при каждом обновлении Postgres) Я бы тоже не стал обязательно использовать WALS - то есть, если вы есть ли в наличии дополнительное оборудование, в этом случае вы могли бы отправляйте отходы в другую машину для извлечения (на второй машине вы можете беззастенчиво используйте триггеры -- или даже протоколирование инструкций - поскольку все, что там происходит, не влияет INSERT/UPDATE/DELETE производительность на основной машине.) Обратите внимание, что с точки зрения производительности (на основном компьютере), если вы не сможете записывать журналы в SAN, вы получите сопоставимый прирост производительности (в основном с точки зрения загрузки кэша файловой системы) при отправке WALS на другой компьютер, чем при запуске инкрементного SELECT.

Другие советы

если вы можете представить себе "таблицу контрольных сумм", которая содержит только идентификаторы и "контрольную сумму", вы можете не только быстро выбрать новые записи, но также измененные и удаленные записи.

контрольной суммой может быть функция контрольной суммы crc32, которая вам нравится.

Новое предложение ON CONFLICT в PostgreSQL изменило способ, которым я выполняю многие обновления.Я извлекаю новые данные (на основе row_update_timestamp) во временную таблицу, затем в одном операторе SQL ВСТАВЛЯЮ в целевую таблицу с ОБНОВЛЕНИЕМ ПРИ КОНФЛИКТЕ.Если ваша целевая таблица разбита на разделы, то вам нужно перепрыгнуть через пару обручей (т.е.перейдите непосредственно к таблице разделов).ETL может произойти при загрузке временной таблицы (наиболее вероятно) или в SQL ON CONFLICT (если это тривиально).По сравнению с другими системами "UPSERT" (обновление, вставка нулевых строк и т.д.) это показывает значительное улучшение скорости.В нашей конкретной среде DW нам не нужно / не хочется учитывать удаления.Ознакомьтесь с документацией ON CONFLICT docs - это дает Oracle MERGE шанс заработать свои деньги!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top