- 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 ความคิดเห็น
Postgres เจ๋งที่สุดจริง ๆ
ความคิดเห็นจาก Hacker News
preadv2(..., RWF_NOWAIT)เพื่อทำการอ่านแบบอะซิงโครนัสจาก page cache ได้ ซึ่งอาจมีประโยชน์ในการลด latency เมื่อใช้io_method = workeraio(4)ของ FreeBSD ไปมาก และน่าจะน่าสนใจว่ามันทำงานอย่างไร เพราะไม่มีข้อเสียแบบ Linux/glibc aioio_uringและมีคำถามว่าผู้ดูแลระบบ Linux หรือดิสโทรจำนวนมากปิดการใช้งานมันอยู่หรือไม่