4 คะแนน โดย GN⁺ 2025-05-08 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • Postgres 18 ซึ่งขณะนี้อยู่ในช่วงเบต้า 1 ได้เพิ่มการรองรับ Asynchronous I/O และช่วยปรับปรุง ประสิทธิภาพการอ่านในสภาพแวดล้อมคลาวด์ ได้อย่างมาก
  • ผ่านค่าตั้งใหม่ io_method ทำให้สามารถเลือกใช้ วิธีแบบ worker และ io_uring นอกเหนือจากวิธี sync แบบดั้งเดิม ได้
  • จากผลเบนช์มาร์กบน AWS เมื่อใช้ io_uring พบว่า ประสิทธิภาพการอ่านดิสก์ดีขึ้นสูงสุด 3 เท่า
  • อย่างไรก็ตาม การทำงานแบบอะซิงโครนัสทำให้ การตีความ I/O timing ในการวิเคราะห์คิวรีแบบเดิม (EXPLAIN ANALYZE) ยากขึ้น
  • จำเป็นต้องมีการปรับแต่งประสิทธิภาพผ่าน มุมมองมอนิเตอร์ใหม่ (pg_aios) และพารามิเตอร์จูนอย่าง effective_io_concurrency

การเพิ่ม Asynchronous I/O ใน Postgres 18

  • โดยปกติแล้ว Postgres ใช้ โมเดล I/O แบบบล็อกกิง ซึ่งต้องรอให้การอ่านดิสก์แต่ละครั้งเสร็จก่อน
  • ด้วยค่า latency สูงของสตอเรจแบบเครือข่าย (เช่น EBS) จึงเกิด คอขวดในสภาพแวดล้อมคลาวด์
  • Asynchronous I/O ทำให้ สามารถประมวลผลการอ่านดิสก์หลายรายการพร้อมกัน และช่วยเพิ่มการใช้ CPU กับ throughput โดยรวม

งานเตรียมความพร้อมใน Postgres 17: Read Stream API

  • ใน Postgres 17 มีการเพิ่ม API read_stream เพื่อ ทำให้ abstraction ของงานอ่านเป็นมาตรฐานเดียวกัน
  • แต่ยังคงพึ่งพา OS page cache และ ไม่ได้สะท้อนเข้า shared buffer ของ Postgres โดยตรง
  • ใน Postgres 18 จึงสามารถทำ การอ่านแบบอะซิงโครนัสโดยตรง ไม่ใช่แค่ kernel hint ได้

ค่าตั้งใหม่: io_method

  • Postgres 18 เพิ่มการตั้งค่า io_method ใน postgresql.conf โดยมี 3 ตัวเลือกดังนี้:

io_method = sync

  • วิธีซิงโครนัสแบบเดียวกับ Postgres เดิม
  • ใช้วิธีขออ่านล่วงหน้าบนพื้นฐาน posix_fadvise()

io_method = worker (ค่าเริ่มต้น)

  • โปรเซส worker ที่รับผิดชอบ I/O โดยเฉพาะ จะอ่านข้อมูลแบบอะซิงโครนัสและส่งต่อไปยัง shared buffer
  • โปรเซสหลักจึง ทำงานต่อได้โดยไม่ต้องหยุดรอระหว่างการอ่าน
  • จำนวน worker เริ่มต้นคือ 3 และปรับได้ด้วยการตั้งค่า io_workers

io_method = io_uring

  • อินเทอร์เฟซ I/O ประสิทธิภาพสูง ที่ใช้ได้บน Linux kernel 5.1 ขึ้นไป
  • อ่านแบบอะซิงโครนัสโดยตรงผ่าน shared ring buffer กับเคอร์เนลได้โดยไม่ต้องมี worker process
  • ต้องใช้เคอร์เนล ระบบไฟล์ และการตั้งค่าที่ทันสมัย

เบนช์มาร์กประสิทธิภาพของ Asynchronous I/O (อิงตาม AWS)

  • สภาพแวดล้อมทดสอบ:
    • AWS c7i.8xlarge (32 vCPU, 64GB RAM)
    • 100GB io2 EBS, 20,000 IOPS
    • รัน SELECT COUNT(*) กับตารางขนาด 3.5GB

เปรียบเทียบประสิทธิภาพแบบ cold cache:

เวอร์ชัน/การตั้งค่า เวลาในการรัน (ms)
Postgres 17 (sync) 15,831
Postgres 18 (sync) 15,071
Postgres 18 (worker) 10,052
Postgres 18 (io_uring) 5,723
  • io_uring ให้ประสิทธิภาพดีกว่า sync 2.8 เท่า
  • มีประสิทธิภาพโดดเด่นในการลด latency ของดิสก์บนคลาวด์

การจูน effective_io_concurrency

  • ใน Postgres 18 พารามิเตอร์นี้มีผลต่อ จำนวนคำขอ read-ahead แบบอะซิงโครนัสภายในระบบ
  • ค่าเริ่มต้นถูกเพิ่มจาก 1 → 16 และเมื่อนำไปคูณกับ io_combine_limit จะกำหนดช่วงการอ่านสูงสุด
  • ในสภาพแวดล้อมคลาวด์ที่มี latency สูง ค่าใหญ่ขึ้นอาจให้ผลดี แต่ ควรทำเบนช์มาร์กตามลักษณะ workload

เครื่องมือมอนิเตอร์ใหม่: pg_aios

  • ใน pg_stat_activity งานแบบอะซิงโครนัสจะแสดงเป็นอีเวนต์ AioIoCompletion ทำให้วิเคราะห์การรอของ backend ได้ยาก
  • ในกรณีของ io_uring นั้น เคอร์เนลเป็นผู้จัดการโดยตรง จึงมองไม่เห็นสถานะ I/O จากฝั่ง Postgres
  • สามารถดูรายละเอียดของคำขอแบบอะซิงโครนัสที่กำลังทำงานอยู่ผ่านมุมมอง pg_aios
    SELECT * FROM pg_aios;  
    
  • สามารถตรวจสอบสถานะอย่าง SUBMITTED, COMPLETED_IO และข้อมูลของบล็อกเป้าหมายได้

ข้อควรระวัง: การตีความข้อมูล I/O timing เปลี่ยนไป

  • I/O Timings ที่เคยเห็นใน EXPLAIN ANALYZE แบบเดิมนั้นเชื่อถือได้เฉพาะในโหมดซิงโครนัส
  • เมื่อใช้ worker หรือ io_uring แบบอะซิงโครนัส การประมวลผลแบบขนานและการกระจายงานไปยัง worker อาจทำให้การตีความค่า timing บิดเบือน
  • หากต้องการประเมินภาระ I/O จริง แนะนำให้ใช้ จำนวนบัฟเฟอร์ shared read ร่วมกับ pg_aios

บทสรุป

  • Postgres 18 ช่วยยกระดับประสิทธิภาพของ workload ที่เน้นการอ่านได้อย่างมีนัยสำคัญ
  • โดยเฉพาะเมื่อใช้ ดิสก์บนคลาวด์ที่มี latency สูง จะเห็นประโยชน์ได้ชัดเจน
  • ขณะเดียวกันก็ ต้องเรียนรู้ใหม่เรื่องการตีความตัวชี้วัด การจูนประสิทธิภาพ และวิธีใช้ค่าตั้งต่าง ๆ
  • ใน Postgres 19 ก็มีความคาดหวังว่าจะรองรับ การเขียนแบบอะซิงโครนัส ต่อไป

2 ความคิดเห็น

 
jujumilk3 2025-05-09

Postgres เจ๋งที่สุดจริง ๆ

 
GN⁺ 2025-05-08
ความคิดเห็นจาก Hacker News
  • บน Linux สามารถใช้ preadv2(..., RWF_NOWAIT) เพื่อทำการอ่านแบบอะซิงโครนัสจาก page cache ได้ ซึ่งอาจมีประโยชน์ในการลด latency เมื่อใช้ io_method = worker
    • มีการเสนอวิธีให้เธรดหลักลองอ่านด้วย NOWAIT ก่อน และค่อย offload ไปยัง worker thread เฉพาะตอนที่ล้มเหลวเท่านั้น
  • มีคำถามว่าฟีเจอร์ asynchronous I/O ใหม่นี้รองรับเฉพาะ Linux หรือไม่
    • Windows มี IOCP และมี IORing implementation ของตัวเอง ส่วน macOS รองรับ POSIX AIO
    • มีการชี้ว่าคนพูดถึง IORing implementation ของ Windows กันไม่มากนัก
  • มีการพัฒนาบน aio(4) ของ FreeBSD ไปมาก และน่าจะน่าสนใจว่ามันทำงานอย่างไร เพราะไม่มีข้อเสียแบบ Linux/glibc aio
  • มีคำถามว่ามันคล้ายกับ InnoDB ของ MySQL หรือไม่
  • มีความกังวลเกี่ยวกับปัญหาด้านความปลอดภัยของ io_uring และมีคำถามว่าผู้ดูแลระบบ Linux หรือดิสโทรจำนวนมากปิดการใช้งานมันอยู่หรือไม่
  • มีความเห็นว่าอยากนำความสามารถนี้ไปใช้จริงบน NVMe และหวังว่าผู้ให้บริการคลาวด์รายใหญ่จะเปิดให้ใช้โดยเร็วที่สุด
    • การเพิ่มประสิทธิภาพนั้นน่าดึงดูดมาก
  • มีการแชร์ประสบการณ์ deploy Postgres บนเซิร์ฟเวอร์ Hetzner EX-44
    • อัตราส่วนราคาต่อประสิทธิภาพยอดเยี่ยม ให้ความจุระดับองค์กรในต้นทุนที่ประหยัด
    • ใช้ TailScale เพื่อเพิ่มความปลอดภัย และตัดการเปิดเผยต่อเครือข่ายสาธารณะออกทั้งหมด
    • แนวทางการปรับแต่งรวมถึงการตั้งค่าตาม workload ผ่าน PGTune, การติดตามประสิทธิภาพแบบเรียลไทม์ผ่าน PgHero และงาน VACUUM ANALYZE อัตโนมัติผ่าน pgcron
    • ได้พัฒนา CLI utility แบบกำหนดเองสำหรับสำรองข้อมูลด้วยการบีบอัด ZSTD โดยคงทั้งอัตราการบีบอัดสูงและ throughput สูง พร้อมรองรับการอัปโหลดไปยัง S3 อัตโนมัติ
    • การตั้งค่านี้เสถียรและมีประสิทธิภาพดี พร้อมรองรับการเติบโตได้อีกมาก
  • มีความเห็นเชิงขำเกี่ยวกับ 20k IOPS ของ AWS instance
    • NVMe สำหรับผู้บริโภคให้ได้ราว ~1 ล้าน+ IOPS และคาดว่าจะเพิ่มขึ้นอีกจาก PCIe 5.0 NVMe
    • มองว่าข้อจำกัดแบบตามอำเภอใจของคลาวด์ก่อให้เกิดปัญหาหลายอย่าง
    • asynchronous IO มีประโยชน์มาก แต่บน NVMe ระดับ 1 ล้าน IOPS ความสำคัญอาจลดลง
    • ค่าใช้จ่ายบนคลาวด์สูงมาก และมีช่องว่างด้านประสิทธิภาพเมื่อเทียบกับฮาร์ดแวร์สำหรับผู้บริโภคราคาถูก
  • มีคำถามเกี่ยวกับการเปรียบเทียบประสิทธิภาพระหว่าง Postgres, MariaDB และ Percona
    • สงสัยว่าแต่ละฐานข้อมูลโดดเด่นในกรณีใช้งานแบบใด
  • มีคำถามว่าอัปเดตที่จะรองรับการเชื่อมต่อพร้อมกันได้มากขึ้นจะออกเมื่อใด
    • หวังว่าจะเลิกใช้ pgbouncer ได้