Интеграция данных Pentaho (PDI) Как использовать массовый загрузчик postgresql? Моя трансформация бежит вечно

Я новичок в PDI, я использую PDI 7, у меня есть ввод Excel с 6 строками, и я хочу вставить его в postgresDB. Моя трансформация: EXCEL INPUT -> Postgres Bulk Loader (всего 2 шага).

Условие 1. Когда я запускаю преобразование, массовая загрузка Postgres не останавливается и ничего не вставляет в мой postgresDB.

Условие 2: Итак, я добавляю шаг «Вставить / Обновить» после Postgres Bulk Loader, и все данные вставляются в postgresDB, что означает успех, но массовый загрузчик все еще работает.

Моя трансформация

Из всех источников, которые я могу получить, им нужны только ввод и шаг массового загрузчика, а после завершения преобразования массовый загрузчик «готов» (мой «работает»). Итак, я хочу спросить, как это правильно сделать для Postgres? Я пропустил что-то важное? Спасибо.


person blackgee    schedule 24.01.2017    source источник


Ответы (4)


Я провел несколько экспериментов.

Среда:

  • БД: Postgresv9.5x64
  • ЧАЙНИК PDI v5.2.0
  • PDI KETTLE defautl jvm settings 512 МБ
  • Источник данных: ФАЙЛ DBF более 2_215_000 строк
  • И PDI, и чайник на одном локальном хосте
  • Таблица усекается при каждом запуске
  • PDI Kettle перезапускается при каждом запуске (чтобы избежать сильной нагрузки на ЦП при запуске gc из-за большого количества строк)

Результаты внизу, чтобы помочь вам принять решение

  1. Массовый загрузчик: в среднем более 150_000 строк в секунду, около 13-15 с.

  2. Вывод таблицы (вставки sql): в среднем 11_500 строк в секунду. Итого около 3 минут 18 секунд

  3. Вывод таблицы (пакетные вставки, размер пакета 10_000): в среднем 28_000 строк в секунду. Итого около 1 мин 30 сек.

  4. Вывод таблицы (пакетная вставка в 5 потоков, размер пакета 3_000): в среднем 7_600 строк в секунду на каждый поток. Означает около 37_000 строк в секунду. Общее время составляет около 59 секунд.

Преимущество загрузчика Buld в том, что он не заполняет память jmv, все данные сразу передаются в процесс psql.

Вывод таблицы заполняет память jvm данными. Фактически, примерно через 1_600_000 строк память заполняется и запускается gc. ЦП в это время загружается до 100%, и скорость значительно замедляется. Вот почему стоит поиграть с размером пакета, чтобы найти значение, которое обеспечит лучшую производительность (больше лучше), но на каком-то уровне вызовет накладные расходы GC.

Последний эксперимент. Памяти, предоставленной jvm, достаточно для хранения данных. Это можно настроить в переменной PENTAHO_DI_JAVA_OPTIONS. Я установил значение размера кучи jvm на 1024 МБ и увеличил значение размера пакета.

  1. Вывод таблицы (пакетная вставка в 5 потоков, размер пакета 10_000): в среднем 12_500 строк в секунду на каждый поток. Это означает около 60_000 строк в секунду. Общее время около 35 секунд.

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

введите описание изображения здесь

person simar    schedule 26.01.2017
comment
Это действительно полезный эксперимент. Массовый загрузчик - хороший вариант для больших данных, но вернемся к моему сообщению, когда я использую массовый загрузчик, он просто работает вечно и ничего не вставляет, но он читает все строки. Можете ли вы предоставить мне снимок экрана с этапом эксперимента с массовой загрузкой? Потому что мои шаги: ввод Excel и массовый загрузчик Postgres не увенчались успехом. Интересно, нужен ли мне еще один шаг после выполнения двух шагов. Спасибо, Симар. - person blackgee; 27.01.2017

Пакетный загрузчик PostgreSQL раньше был только экспериментальным. Давно не пробовал. Вы уверены, что вам это нужно? Если вы загружаете из Excel, маловероятно, что у вас будет достаточно строк, чтобы оправдать использование массового загрузчика.

Попробуйте просто обычный Table Output шаг. Если вы только вставляете, шаг Insert/Update также не нужен.

person Brian.D.Myers    schedule 24.01.2017
comment
Я точно не знаю, нужен ли мне массовый загрузчик или нет, я знаю, что insert / update заняло слишком много времени 150 тыс. Строк = 27-33 минут, с выводом таблицы потребовалось всего 1 сек, но это только тогда, когда мне нужно сделать только вставку. Для удаления обновления это не полезно. В ближайшем будущем мне может потребоваться обновить или удалить, так что вы можете дать мне какое-нибудь решение? Спасибо. - person blackgee; 25.01.2017
comment
Для обновления / удаления ознакомьтесь с шагом Merge Rows (diff). Ваш Insert/Update шаг, вероятно, выполняется медленно, потому что в базовой таблице отсутствует индекс. - person Brian.D.Myers; 25.01.2017
comment
Объединить строки (diff) в сочетании с выводом таблицы кажется нормальным. Тем не менее, мне интересно, как ускорить вставку / обновление, я уже установил индекс, когда возникла проблема. Спасибо, Брайан. - person blackgee; 26.01.2017
comment
Merge Rows (diff) не следует сочетать с Table Output; его следует сочетать с Synchronize after merge. Цель состоит в том, чтобы загрузить только те строки, которые изменились. Каждая строка помечена как новые, измененные, удаленные или идентичные. Если количество одинаковых строк велико, а остальных мало, это должно быть довольно быстро. - person Brian.D.Myers; 26.01.2017
comment
True, Merge Rows (diff), Sync after merge, sort, filter: dummy (false) table output (true) кажется нормальным, это определенно быстрее, чем Merge Rows (diff), Sync after слияние, сортировка, фильтр: пустышка (ложь) вставка / обновление (истина). Спасибо. - person blackgee; 27.01.2017

Чтобы вставить всего 7 строк, вам не нужен массовый загрузчик. Массовый загрузчик предназначен для загрузки огромного количества данных. Он использует собственный клиент psql. Клиент PSQL передает данные намного быстрее, поскольку он использует все функции двоичного протокола без каких-либо ограничений спецификации jdbc. JDBC используется на других этапах, таких как вывод таблицы. В большинстве случаев вывода таблицы достаточно.

Шаг Postgres Bulk Loader просто встраивает в память данные в формате csv из входящих шагов и передает их клиенту psql.

person simar    schedule 25.01.2017
comment
Привет, Симар. Мои фактические данные - 350 тыс. Строк. 7 рядов только для моделирования того, как это работает. Результат с обоими данными: 350 тыс. Строк и 7 строк. Я получаю результат, когда ничего не вставлено, и шаг массовой загрузки со статусом работает. Шаг Postgres Bulk Loader просто встраивает данные в память в формате csv из входящих шагов и передает их клиенту psql. Передайте их клиенту psql, но почему ничего не вставлено? Я что-то пропустил? - person blackgee; 26.01.2017
comment
Обычно у меня есть преобразование со вставками более миллиона строк. На это нужно время. Хосты базы данных и PDI в одном дата-центре. БД postgres. Всего строк 3.2млн. Строк. Преобразование загружает данные одновременно в 4 потока, это занимает около 30 минут. - person simar; 26.01.2017
comment
Другой пример PDI и DB на одном хосте. 90_000 строк из файла CSV в БД postgres. Общее время около 4 с. - person simar; 26.01.2017
comment
90 тыс. Строк из CSV в БД Postgres с insert = 4s быстро. По сравнению с моими 350 тыс. Строк, 3 потока, 20 тыс. Строк, от CSV до DB postgres со вставкой = 33 минуты. Даже ваша вставка миллиона строк с 4 потоками = 30 минут быстрее. О, я забыл упомянуть, я попытался заменить шаг обновления вставки фиктивным, это заняло менее 1 секунды. И, как я упоминал ранее, вывод таблицы также занял менее 1 секунды. Это абсолютно узкое место на этапе вставки / обновления. Есть ли способ сделать это хоть немного быстрее, чем 33 минуты? Даже 5 минут не приемлемо. Мне нужно, чтобы он работал быстрее, чем за 5 минут. - person blackgee; 27.01.2017
comment
Почему следует избегать использования шага вставки / обновления - ›graymatter.co.in/blog/ - person simar; 15.02.2017

Медленный шаг вставки / обновления Почему вам следует избегать использования вставки / обновления (в случае обработки большого количества данных или если вы ограничены во времени)?

Посмотрим документацию

На этапе «Вставить / обновить» сначала выполняется поиск строки в таблице с помощью одного или нескольких ключей поиска. Если строку не удается найти, она вставляет строку. Если его можно найти и поля для обновления совпадают, ничего не делается. Если они не все одинаковы, строка в таблице обновляется.

Перед состояниями для каждой строки на шаге потока будет выполняться 2 запроса. Сначала выполняется поиск, а затем обновление или вставка. Источник PDI Kettle утверждает, что PreparedStatement используется для всех запросов: вставки, обновления и поиска.

Итак, если этот шаг является узким местом, попробуйте выяснить, что именно медленное.

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

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

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

person simar    schedule 15.02.2017