Запись более 50 миллионов из Pyspark df в PostgresSQL, лучший эффективный подход

16

Какой самый эффективный способ вставить миллионы записей, скажем, 50 миллионов из фрейма данных Spark в таблицы Postgres. В прошлом я делал это от spark до MSSQL, используя опцию массового копирования и размера пакета, которая также была успешной.

Есть ли что-то подобное, что может быть здесь для Postgres?

Добавляем код, который я пробовал, и время, необходимое для запуска процесса:

def inserter():
    start = timer()
    sql_res.write.format("jdbc").option("numPartitions","5").option("batchsize","200000")\
    .option("url", "jdbc:postgresql://xyz.com:5435/abc_db") \
    .option("dbtable", "public.full_load").option("user", "root").option("password", "password").save()
    end = timer()
    print(timedelta(seconds=end-start))
inserter()

Таким образом, я применил вышеуказанный подход для 10 миллионов записей и имел 5 параллельных соединений, как указано в, numPartitionsа также пробовал размер пакета 200 КБ .

Общее время, затрачиваемое на процесс, составило 0: 14: 05.760926 (четырнадцать минут и пять секунд).

Есть ли другой эффективный подход, который бы сократил время?

Какой эффективный или оптимальный размер партии я могу использовать? Будет ли увеличение размера моей партии делать работу быстрее? Или открытие нескольких соединений, т. Е.> 5, поможет мне ускорить процесс?

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

Chetan_Vasudevan
источник
1
Вы можете сначала выгрузить данные в локальный CSV-файл, а затем использовать собственные инструменты импорта PostgreSQL для его импорта - это зависит от того, где находится узкое место: медленный экспорт из Pyspark или медленный импорт в Postgres, или что-то еще? (Тем не менее, 14 минут для 50 миллионов строк не кажутся мне такими уж плохими - какие индексы определены в таблице?).
Дай
Дай, у меня есть df 52mil, и теперь я пишу его в Postgres, это новая таблица, которую я создаю с помощью приведенного выше кода. Я не создал таблицу в Postgres, а затем писал там. Есть ли лучшая возможность, если я смогу сначала создать таблицу и проиндексировать ее в Postgres, а затем отправить данные из spark df?
Четан_Васудеван
2
(Это наоборот - индексы замедляют операции вставки в таблицы, но ускоряют запросы выбора)
Dai
Дай, я просто создаю таблицу в Postgres без индекса, а затем пытаюсь вставить и измерить мою производительность?
Chetan_Vasudevan
2
stackoverflow.com/questions/758945/… может быть полезным.
Алексей Романов

Ответы:

4

Я фактически проделал такую ​​же работу некоторое время назад, но с использованием Apache Sqoop.

Я бы сказал, что для ответа на эти вопросы мы должны попытаться оптимизировать взаимодействие между Spark и PostgresSQL, в частности, данные, передаваемые из Spark в PostgreSql.

Но будьте осторожны, не забудьте Spark Side. Не имеет смысла выполнять mapPartitions, если число разделов слишком велико по сравнению с количеством максимальных соединений, которые поддерживает PostgreSQL, если у вас слишком много разделов и вы открываете соединение для каждого из них, у вас, вероятно, будет следующая ошибкаorg.postgresql.util.PSQLException: FATAL: sorry, too many clients already ,

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

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

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

dbustosp
источник
Dbustosp Я обязательно попробую вышеупомянутые советы, до тех пор, пока вы не заслужите возражения наверняка.
Четан_Васудеван
@chetan_vasudevan, если вы предоставите более подробную информацию о данных, которые вы используете, о размере каждой записи и т. д. Если данные общедоступны, я могу попробовать что-то самостоятельно и сравнить время.
dbustosp
Dbustosp данные имеют 80 столбцов и 55 миллионов записей. Я начал работать над предложениями, которые вы мне дали.
Четан_Васудеван
@Chetan_Vasudevan Общий размер набора данных? Какой формат входных данных?
dbustosp
@Chetan_Vasudevan Любое обновление?
dbustosp