Menulis lebih dari 50 juta dari Pyspark df ke PostgresSQL, pendekatan efisien terbaik


16

Apa yang akan menjadi cara paling efisien untuk menyisipkan jutaan catatan katakan 50 juta dari bingkai data Spark ke Postgres Tables. Saya telah melakukan ini dari percikan ke MSSQL di masa lalu dengan memanfaatkan salinan massal dan opsi ukuran batch yang berhasil juga.

Adakah sesuatu yang serupa yang bisa ada di sini untuk Postgres?

Menambahkan kode yang telah saya coba dan waktu yang diperlukan untuk menjalankan proses:

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()

Jadi saya melakukan pendekatan di atas untuk 10 juta catatan dan memiliki 5 koneksi paralel sebagaimana ditentukan dalam numPartitionsdan juga mencoba ukuran batch 200k .

Total waktu yang dibutuhkan untuk proses ini adalah 0: 14: 05.760926 (empat belas menit dan lima detik).

Apakah ada pendekatan efisien lain yang akan mengurangi waktu?

Berapa ukuran batch yang efisien atau optimal yang dapat saya gunakan? Apakah meningkatkan ukuran batch saya melakukan pekerjaan lebih cepat? Atau membuka banyak koneksi, misalnya> 5 membantu saya membuat proses lebih cepat?

Rata - rata 14 menit untuk 10 juta catatan tidak buruk , tetapi mencari orang di luar sana yang akan melakukan ini sebelumnya untuk membantu menjawab pertanyaan ini.


1
Anda dapat membuang data ke file CSV lokal terlebih dahulu, dan kemudian menggunakan alat impor PostgreSQL sendiri untuk mengimpornya - tergantung di mana kemacetannya: apakah lambat untuk mengekspor dari Pyspark atau lambat untuk mengimpor ke Postgres, atau yang lain? (Yang mengatakan, 14 menit untuk 50 juta baris sepertinya tidak buruk bagi saya - indeks apa yang didefinisikan pada tabel?).
Dai

Dai, saya punya df yaitu 52mil dan sekarang saya menulisnya ke Postgres, ini adalah tabel baru yang saya buat melalui kode di atas. Saya belum membuat tabel di Postgres dan kemudian menulis di sana. Apakah ada kemungkinan lebih baik jika saya dapat membuat tabel terlebih dahulu dan mengindeksnya di Postgres dan kemudian mengirim data dari spark df?
Chetan_Vasudevan

2
(Ini sebaliknya - indeks memperlambat operasi memasukkan pada tabel, tetapi mempercepat pertanyaan pilih)
Dai

Dai, jadi saya hanya membuat tabel di Postgres tanpa indeks dan kemudian mencoba memasukkan dan mengukur kinerja saya?
Chetan_Vasudevan

Jawaban:


4

Saya sebenarnya melakukan pekerjaan yang sama beberapa waktu lalu tetapi menggunakan Apache Sqoop.

Saya akan mengatakan bahwa untuk menjawab pertanyaan ini kita harus mencoba mengoptimalkan komunikasi antara Spark dan PostgresSQL, khususnya data yang mengalir dari Spark ke PostgreSql.

Tapi hati-hati, jangan lupa Spark side. Tidak masuk akal untuk mengeksekusi mapPartitions jika jumlah partisi terlalu tinggi dibandingkan dengan jumlah koneksi maksimum yang didukung PostgreSQL, jika Anda memiliki terlalu banyak partisi dan Anda membuka koneksi untuk masing-masing partisi, Anda mungkin akan memiliki kesalahan berikut org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

Untuk menyesuaikan proses penyisipan, saya akan mendekati masalah dengan mengikuti langkah-langkah berikut:

  • Ingat jumlah partisi itu penting. Periksa jumlah partisi dan kemudian sesuaikan berdasarkan jumlah koneksi paralel yang Anda inginkan. Anda mungkin ingin memiliki satu koneksi per partisi, jadi saya sarankan untuk memeriksa coalesce, seperti yang disebutkan di sini .
  • Periksa jumlah maksimum koneksi yang didukung oleh instance postgreSQL Anda dan Anda ingin menambah jumlahnya .
  • Untuk memasukkan data ke dalam PostgreSQL disarankan menggunakan perintah COPY . Berikut ini juga jawaban yang lebih terperinci tentang cara mempercepat penyisipan postgreSQL.

Akhirnya, tidak ada peluru perak untuk melakukan pekerjaan ini. Anda dapat menggunakan semua tips yang saya sebutkan di atas tetapi itu akan sangat tergantung pada data Anda dan kasus penggunaan.


Dbustosp Saya pasti akan mencoba tips di atas, sampai saat itu Anda pantas mendapatkan upvote pasti.
Chetan_Vasudevan

@chetan_vasudevan jika Anda memberikan detail lebih lanjut tentang data yang Anda gunakan, ukuran per catatan, dll. Jika data bersifat publik, saya dapat mencoba sesuatu sendiri dan membandingkan waktu.
dbustosp

Dbustosp data memiliki 80 kolom dan 55 juta catatan. Saya sudah mulai mengerjakan saran yang Anda berikan kepada saya.
Chetan_Vasudevan

@Chetan_Vasudevan Ukuran total dataset? Apa format data input?
dbustosp

@Chetan_Vasudevan Ada pembaruan?
dbustosp
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.