การเขียนมากกว่า 50 ล้านจาก Pyspark df ไปยัง PostgresSQL ซึ่งเป็นวิธีการที่มีประสิทธิภาพที่สุด


16

อะไรจะเป็นวิธีที่มีประสิทธิภาพมากที่สุดในการแทรกเรคคอร์ดนับล้านบันทึกว่า 50 ล้านจาก Spark dataframe ไปยัง Postgres Tables ฉันได้ทำสิ่งนี้ตั้งแต่ประกายไปจนถึง 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และยังพยายามขนาดชุดของ 200k

เวลาทั้งหมดที่ใช้ในกระบวนการคือ0: 14: 05.760926 (สิบสี่นาทีและห้าวินาที)

มีวิธีอื่นที่มีประสิทธิภาพซึ่งจะลดเวลาหรือไม่?

ขนาดแบทช์ที่มีประสิทธิภาพหรือเหมาะสมที่สุดที่ฉันสามารถใช้ได้คืออะไร การเพิ่มขนาดชุดของฉันจะทำงานเร็วขึ้นหรือไม่ หรือเปิดการเชื่อมต่อที่หลากหลายเช่น> 5 ช่วยให้กระบวนการเร็วขึ้นหรือไม่

บนเฉลี่ย 14 นาที 10 ล้านระเบียนไม่เลวแต่มองหาคนออกมีที่จะทำแบบนี้มาก่อนที่จะช่วยตอบคำถามนี้


1
คุณสามารถถ่ายโอนข้อมูลไปยังไฟล์ CSV ภายในเครื่องก่อนจากนั้นใช้เครื่องมือนำเข้าของ PostgreSQL เพื่อนำเข้าข้อมูล - ขึ้นอยู่กับว่าปัญหาคอขวดคืออะไร: มันช้าในการส่งออกจาก Pyspark หรือนำเข้าสู่ Postgres ช้าหรืออย่างอื่น? (ที่กล่าวว่า 14 นาทีสำหรับ 50 ล้านแถวดูเหมือนจะไม่ดีสำหรับฉัน - ดัชนีใดที่กำหนดไว้ในตาราง?)
Dai

Dai ฉันมี df ซึ่งเป็น 52mil และตอนนี้ฉันเขียนถึง Postgres มันเป็นตารางใหม่ที่ฉันสร้างผ่านโค้ดด้านบน ฉันยังไม่ได้สร้างตารางใน Postgres แล้วเขียนที่นั่น มีความเป็นไปได้ที่ดีกว่าหรือไม่ถ้าฉันสามารถสร้างตารางแรกและสร้างดัชนีใน Postgres แล้วส่งข้อมูลจาก spark df ได้หรือไม่
Chetan_Vasudevan

2
(เป็นวิธีอื่น ๆ - ดัชนีชะลอการดำเนินการแทรกในตาราง แต่เร่งแบบสอบถามแบบใช้เลือกข้อมูล)
Dai

Dai ดังนั้นฉันเพียงแค่สร้างตารางใน Postgres โดยไม่ต้องดัชนีแล้วลองใส่และวัดประสิทธิภาพการทำงานของฉันได้อย่างไร
Chetan_Vasudevan

2
stackoverflow.com/questions/758945/…อาจเป็นประโยชน์
Alexey Romanov

คำตอบ:


4

จริง ๆ แล้วฉันก็ทำงานเหมือนเดิมมาซักพักแล้ว แต่ใช้ Apache Sqoop

ฉันจะบอกว่าสำหรับการตอบคำถามนี้เราต้องพยายามเพิ่มประสิทธิภาพการสื่อสารระหว่าง Spark และ PostgresSQL โดยเฉพาะข้อมูลที่ไหลจาก Spark ไปยัง PostgreSql

แต่ระวังอย่าลืมด้าน Spark ไม่เหมาะสมที่จะเรียกใช้งานmapPartitionsหากจำนวนพาร์ติชันสูงเกินไปเมื่อเทียบกับจำนวนการเชื่อมต่อสูงสุดที่ PostgreSQL รองรับหากคุณมีพาร์ติชันมากเกินไปและคุณกำลังเปิดการเชื่อมต่อสำหรับแต่ละพาร์ติชันคุณอาจจะมีข้อผิดพลาดต่อไปนี้org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

เพื่อปรับกระบวนการแทรกฉันจะเข้าใกล้ปัญหาตามขั้นตอนถัดไป:

  • โปรดจำไว้ว่าจำนวนพาร์ติชันมีความสำคัญ ตรวจสอบจำนวนพาร์ติชันแล้วปรับตามจำนวนการเชื่อมต่อแบบขนานที่คุณต้องการ คุณอาจต้องการที่จะมีการเชื่อมต่อหนึ่งต่อพาร์ทิชันดังนั้นฉันจะแนะนำให้ตรวจสอบcoalesceตามที่ถูกกล่าวถึงที่นี่
  • ตรวจสอบจำนวนสูงสุดของการเชื่อมต่อที่สนับสนุนเช่น PostgreSQL ของคุณและคุณต้องการที่จะเพิ่มจำนวน
  • สำหรับการใส่ข้อมูลลงใน PostgreSQL ขอแนะนำให้ใช้คำสั่งคัดลอก ต่อไปนี้เป็นคำตอบที่ละเอียดยิ่งขึ้นเกี่ยวกับวิธีเพิ่มความเร็วของการแทรก postgreSQL

ในที่สุดก็ไม่มีกระสุนเงินในการทำงานนี้ คุณสามารถใช้เคล็ดลับทั้งหมดที่ฉันกล่าวถึงข้างต้น แต่ขึ้นอยู่กับข้อมูลของคุณและกรณีใช้


Dbustosp ฉันจะลองทำตามเคล็ดลับข้างต้นอย่างแน่นอนจนกว่าคุณจะสมควรได้รับการโหวตอย่างแน่นอน
Chetan_Vasudevan

@chetan_vasudevan หากคุณให้รายละเอียดเพิ่มเติมเกี่ยวกับข้อมูลที่คุณกำลังใช้ขนาดต่อเร็กคอร์ด ฯลฯ หากข้อมูลเป็นสาธารณะฉันสามารถลองด้วยตัวเองและเปรียบเทียบเวลา
dbustosp

Dbustosp ข้อมูลมี 80 คอลัมน์และบันทึก 55 ล้านรายการ ฉันเริ่มทำตามคำแนะนำที่คุณให้ไว้
Chetan_Vasudevan

@Chetan_Vasudevan ขนาดรวมของชุดข้อมูลหรือไม่ รูปแบบของข้อมูลอินพุตคืออะไร?
dbustosp

@Chetan_Vasudevan การปรับปรุงใด ๆ
dbustosp
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.