AWS Thai Blog

AWS Well-Architected สำหรับ Amazon RDS PostgreSQL : Performance Efficiency

Amazon RDS PostgreSQL คือ Relational Database service เป็นลักษณะ Fully-Managed ซึ่งช่วยให้การ set up, operate และ scale สามารถทำได้ง่าย โดย Amazon RDS ใช้ให้ในส่วนของการจัดการในส่วนของ Hardware, Operating System, ติดตั้ง database software, และสร้าง database พร้อมทั้งมีฟีเจอร์ในด้านการจัดการ administration task เช่น automated backup ซึ่งสามารถ enable มาใช้ได้

เมื่อมีการสร้าง หรือ deploy database ต่างๆขึ้นไปบน AWS แล้ว หลายๆท่านจะมีคำถามว่า database นั้น มี architecture หรือการทำงาน ตาม best practice หรือยัง, สามารถรองรับ fault ที่เกิดขึ้นได้หรือไม่, หรือสามารถทำงานได้อย่างมีประสิทธิภาพหรือเปล่า

คำถามเหล่านี้สามารถตอบโจทย์ด้วย AWS-Well Architected​ Framework ซึ่งเป็น best practice หรือแนวทางปฏิบัติต่างๆ เพื่อทำให้มั่นใจว่าการรัน workload ต่างๆบน AWS จะสามารถตอบในแง่มุมต่างๆเช่น การ operate, security, efficient, cost-effective

AWS Well-Architected Framework มีด้วยกัน 6 pillar 

  • Operational Excellence: เน้นเรื่องการ running, operate, monitor และ การพัฒนา process โดยจะรีวิวเกี่ยวกับ automating changes, การ response กับ event ต่างๆที่เกิดขึ้น หรือเป็นการ manage daily operation
  • Security: เน้นเรื่องการปกป้องข้อมูลและระบบ ซึ่งจะรีวิวเกี่ยวกับ ความปลอดภัยของข้อมูล, การจัดการ user permission สิทธิ์ในการเข้าถึงต่างๆ รวมทั้งการควบคุม ตรวจสอบ security event ที่เกิดขึ้น
  • Reliability: เน้นเรื่องการรับมือกับ failure ที่จะเกิดขึ้น ซึ่งตามคำกล่าวของ AWS CTO ดร. Werner Vogels ที่เคยกล่าวไว้ว่า “Everything fails, all the time” ทุกส่ิงสามารถ fail หรือทำงานผิดพลาดได้เสมอ ดังนั้นการเตรียมพร้อมรับมือกับเหตุการณ์ไม่คาดฝันเป็นอีกหนึ่งสิ่งที่สำคัญ โดยใน pillar นี้จะ review เกี่ยวกับ การออกแบบระบบให้เป็นแบบ distributed system หรือกระจายการทำงาน ซึ่งจะกระจายความเสี่ยงไปด้วย, การออกแบบการ recovery และพร้อมรับมือกับสิ่งที่เปลี่ยนแปลงในอนาคต
  • Performance Efficiency: เน้นเรื่องการจัดการ resource ให้เพียงพอรองรับต่อการใช้งาน, มี performance และประสิทธิภาพสูงสุด โดยจะรีวิวเกี่ยวกับการเลือกประเภทของ resource, การ optimize size ของ workload, การ monitoring performance, และการ maintain ประสิทธิภาพตามที่ธุรกิจต้องการ
  • Cost Optimization: เน้นเรื่องการจัดการ cost หรือค่าใช้จ่ายต่างๆ รีวิวเกี่ยวกับการทำความเข้าใจค่าใช้จ่ายและควบคุมงบประมาณ และการใช้ reousce ให้คุ้มค่ามากที่สุด และไม่เสียเปล่า
  • Sustainability: เน้นเรื่องความยั่งยืน การรัน workload ต่างๆให้มีผลกระทบกับสิ่งแวดล้อมน้อยที่สุด โดยจะรีวิวเกี่ยวกับบทบาทความรับผิดชอบในด้านความยั่งยืน, การทำความเข้าใจ และ utilize resource ให้มากที่สุด เพื่อใช้ resource ตามที่จำเป็น

AWS ได้ provide AWS Well-Architected Tool ซึ่งเป็นเครื่องมือในหน้า Console

และมี AWS Well-Architected Lenses ซึ่งเป็นแนวทางปฏิบัติตามกลุ่มอุตสาหกรรมและเทคโนโลยี สามารถเรียนรู้เพิ่มเติมได้ที่นี่

ซึ่งในบล็อกโพสต์นี้จะอธิบายเกี่ยวกับ AWS Well-Architected สำหรับ Amazon RDS PostgreSQL ใน pillar ของ Performance Efficiency เพื่อให้ท่านผู้อ่านได้เรียนรู้เกี่ยวกับแนวทางปฏิบัติ, การออกแบบ, การค้นหาปัญหาเกี่ยวกับ Performance บน Amazon RDS PostgreSQL

1. Database Right Sizing

ตอนสร้าง Amazon RDS Database instance จะต้องมีการเลือก database instance sizing ให้เหมาะสม โดยมีปัจจัยที่ส่งผลเรื่อง performance ดังนี้

  • vCPU คือ ขนาดของหน่วยประมวลผล
  • Memory คือ ขนาดของหน่วยความจำ หน่วยเป็น GB
  • Network Performance คือ ประสิทธิภาพของ network หน่วยเป็น MB/s แสดงถึงปริมาณ Network Throughput ที่ทำได้
  • Storage คือ ประเภทของที่ block storage ที่ใช้ในการเก็บข้อมูล แสดงถึง I/O Throughput ที่ทำได้

ดังนั้นการ optimize database instance เป็นสิ่งที่สำคัญมาก เพราะจะส่งผลกับ performance และ cost โดยตรง, ถ้าขนาดของ database instance ไม่สัมพันธ์กับ workload ที่รันใน database ทำให้ CPU ไม่เพียงต่อการทำงาน, หรือ Memory ที่จะใช้ใน database engine เพื่อ caching ข้อมูลต่างๆเพื่อให้ database ทำงานกับ memory ซึ่งจะเร็วกว่าการทำงานกับ storage โดยตรง ก็มีไม่เพียงพอ, หรือ I/O bandwidth มีขนาดน้อยเกินไป ส่งผลให้ภาพรวมการทำงานช้าลง

ข้อแนะนำ:

2. Database Configuration Considerations

Database parameters มีส่วนสำคัญในด้าน Performance ผมจะ list database parameter ที่สำคัญเพื่อสามารถรีวิว​ และปรับแก้ไข

โดย default Amazon RDS จะมี parameter group ซึ่งเป็นค่า default และไม่สามารถแก้ไขได้ แต่สามารถสร้าง customize database parameter group สำหรับ database instance หรือ cluster นั้นๆ เพื่อ configure ค่า ตามที่ database instance นั้นต้องการ สามารถเรียนรู้วิธีการสร้างและเปลี่ยน database parameter group ได้ที่นี่

Parameter ที่สำคัญเกี่ยวกับ Memory (หน่วยความจำ)

  • Shared_buffers: เป็น parameter ที่ระบุค่าพื้นที่ของ shared memory ที่ไว้เก็บ cached ในการ read และ write ซึ่งเวลามี read request เข้ามาที่ PostgreSQL จะเข้ามาอ่านใน memory ก่อนเพื่อลดการใช้งาน I/O ของ disk storage, และถ้ามีการ write request ก็จะทำการแก้ไขที่ shared memory เรียกว่า dirty buffer และจะ flush การเปลี่ยนแปลงหลังจาก database checkpoint
    • ค่า default คือ 25% ของ memory ใน database instance ซึ่งค่า default เป็นค่าเริ่มต้นที่ดี
  • Effective_cache_size: เป็น parameter ที่บอกถึงค่าประสิทธิภาพของ cache ข้อมูลจาก disk ที่พร้อมให้บริการสำหรับการ query ข้อมูล
    • โดยทั่วไปแล้วตั้งค่า 75% ของ memory เป็นค่าเริ่มต้นที่ใช้ได้
  • Work_mem: เป็น parameter ที่ระบุค่า memory สำหรับการ sort หรือทำเรื่องของ hash operations ต่อ connection
    • ค่าต่ำสุดที่ recommend สำหรับ OLTP workload คือ 4 MB โดยสามารถ monitor การใช้งาน memory หลังจาก config ไปแล้วได้ที่ monitoring metric: FreeableMemory
  • Maintenance_work_mem: เป็น parameter ที่ระบุค่า memory สำหรับ database maintenance operation เช่น VACUUM, CREATE INDEX, และ ALTER TABLE ADD FOREIGN KE โดยทั่วไป autovacuum worker process จะทำงานเป็นแบบ parallel ดังนั้นต้องเช็คค่า autovacuum_max_worker ด้วย
    •  สามารถปรับปรุง performance ของ database maintenance operation เหล่านี้ได้โดยเพิ่มค่านี้ โดยค่า default ของ RDS เป็นค่าเริ่มต้นที่ดี

Parameter ที่สำคัญเกี่ยวกับ CPU (หน่วยประมวลผล)

  • Max_connections: เป็น parameter ที่ระบุค่าจำนวน concurrent connection มากที่สุดบน server
  • Max_worker_processes: เป็น parameter ที่ระบุค่า จำนวนของ background processes มากที่สุดที่ system สามารถรองรับได้
    • โดยทั่วไปจะไป config ค่านี้เกินจำนวน vCPUs
  • Max_parallel_maintenance_workers: เป็น parameter ที่ระบุค่าจำนวนของ parallel workers มากที่สุด ที่ใช้ใน single command เช่น CREATE INDEX, VACUUM
    • สามารถพิจารณาเพิ่มค่านี้ได้ เพื่อต้องการรัน maintenance workload ได้เร็วขึ้น
  • Max_parallel_workers_per_gather: เป็น parameter ที่ระบุค่าจำนวนของ workers เพื่อใช้ใน single Gather หรือ Gather Merge node
    • สามารถพิจารณาเพิ่มค่านี้ได้ เมื่อ concurrent sessions ของระบบมีมากขึ้น

3. Performance Monitoring

การ monitor database เป็นกุญแจสำคัญในการตรวจเช็คว่ามีอะไรเกิดขึ้น database บ้าง เพื่อนำไปสู่การปรับปรุง performance ได้ตรงจุด โดยใน Amazon RDS มีเครื่องมีอที่ช่วยให้ monitor database เชิงลึก ได้ง่ายขึ้น คือ Amazon RDS Performance Insights ซึ่งสามารถหน้า dashboard เกี่ยวกับ wait event, top sql queries, performance metric ต่างๆที่เกิดขึ้น รวมทั้งดู Average Active Session (AAS) ของ users เพื่อแสดงภาพรวมของ load ใน database , สามารถเก็บ performance data history ได้ฟรี 7 วัน และตั้งค่า retention ได้สูงถึง 2 ปี (สามารถดูรายละเอียดค่าใช้จ่ายได้ที่นี่)

โดยทั่วไปแล้ว database ที่มีปัญหา performance จะเริ่มมีอาการเช่น CPU/Memory/DB connection/IO/Execution time ที่สูงขึ้น ซึ่งอาจเกิดได้หลายสาเหตุเช่น เกิด lock ต่างๆ (สามารถดูรายละเอียดเพิ่มเติมได้ที่นี่), ประมาณ resource ไม่เพียงพอกับ database workload, การรันงานที่ตั้งค่า parallel สูง, query ที่ไม่มีประสิทธิภาพ

ซึ่งสามารถแบ่งระดับการ monitoring ได้ 3 ระดับดังนี้

  • ระดับ RDS instance:
  • ระดับ PostgreSQL Engine:
    • Database Postgres log ซึ่งจะถูกส่งไปที่ CloudWatch เช่น log_statement, log_min_duration_statement, log_connections/log_disconnections, log_autovacuum_min_duration
    • Contrib modules ซึ่งเป็น module tool ที่มีประโยชน์
      • pg_stat_statements ใช้สำหรับ monitor SQL statistics
      • pg_buffercache ใช้สำหรับ monitor shared buffer cache แบบ real time
      • pgrowlocks ใช้สำหรับ monitor row locking กับ specific table
      • pgstattuple ใช้สำหรับ monitor tuple-level statistics (tuple คือที่เก็บข้อมูล internal ของ row ใน table)
    • Guideline จาก AWS Premium Support เพื่อช่วยในการหา performance issue สามารถศึกษาเพิ่มเติมได้ที่นี่
  • ระดับ Query:
    • Explain Analyze สำหรับ SQL statement
    • pg_stat_statements ใช้สำหรับ track execution plan statistics ของทุกๆ SQL statements ที่ execute อยู่ใน database

4. Scalability Considerations 

  • Database Schema
    • ข้อแนะนำเกี่ยวกับ Primary Key
      • ตรวจสอบการระบุค่า primary key สำหรับแต่ละ table
      • สามารถหลีกเลี่ยงปัญหา ค่า integer หมด โดยการใช้ bigint แทน integer
    • ข้อแนะนำเกี่ยวกับ Foreign Key
      • ลดการใช้ foreign key ใน database
      • Enforce referential integrity ที่ application layer
    • ข้อแนะนำเกี่ยวกับ Data Type
      • เลือก Data Type ให้เหมาะสม เช่น ใช้ Boolean เเทนที่จะเป็น String “Yes” หรือ “No” เพื่อทำให้ database optimizer ทำงานได้รวดเร็วมากขึ้น
      • Offload พวก data ที่เป็น large object (LOB) ออกจาก database โดยเก็บไว้ใน Object storage ใน Amazon S3 เเทน
  • Application Access
  • Workload characteristics
    • Optimize สำหรับ Read heavy workload
      • จำกัดจำนวน column ที่ใช้ใน Query Select Statement
      • Index tuning เพื่อให้ cover การ Query
      • ลดการ sort/hash operation บน disk
      • Breakdown complex query ขนาดใหญ่ เป็น query ที่เล็กลง หรือ merge result บน application layer
      • Offload งานทางด้าน Read-only เช่น reporting ไปที่ Read replica
      • ถ้างานเป็นลักษณะของ Online analytical processing (OLAP) ที่ต้องใช้ในการ analysis ที่มีความซับซ้อน สามารถพิจารณาเลือกใช้ Data Warehouse solution: Amazon Redshift หรือสร้าง Lakehouse architecture บน AWS
    • Optimize สำหรับ Write heavy workload
  • Manage Data Growth

5. Database Maintenance

ใน PostgreSQL database จะมีกระบวนการ Multi-Version Concurrency Control (MVCC) ซึ่งเป็นการ maintain version ของ row เมื่อมีการเเก้ไขข้อมูล เช่น UPDATE, DELETE operation ใน table database จะมีการเก็บ old version ของ row เพื่อให้ transaction อื่นๆสามารถใช้ในการ access consistent data ได้ ทุกๆ record ที่มีการแก้ไขจะมีการใช้งานพื้นพี่ใน database เรียกว่า dead tuple หลังจากที่มีการแก้ไขข้อมูล และไม่มี dependency กับ dead tuple แล้ว,​ dead tuple เหล่านั้นก็จะไม่ได้ถูกใช้งาน, พื้นที่ที่ใช้เก็บ dead tuple เหล่านี้จะเรียกว่า Bloat

ดังนั้นเพื่อให้ dead tuple เหล่านั้นใช้งานได้อีกครั้ง และ reclaim space ใน PostgreSQL จะมี database maintenance operation ที่สำคัญ คือการทำ Vacuum​ (โดย default Vacuum จะไม่ได้ reclaim disk space แต่จะทำให้ dead tuple เหล่านั้นสามารถ reuse ได้, ถ้าจะ reclaim space ต้องใช้ vacuum full (offline), cluster (offline) หรือ ใช้ PostgreSQL extension: ‘pg_repack’ (online)

ใน PostgreSQL จะมี Autovacuum ซึ่งเป็น daemon process ในการทำ automate VACUUM และ ANALYZE (ใช้สำหรับ gather statistics) โดย Autovacuum จะเช็ค dead tuple ใน table เหล่านี้ เพื่อ reclaim space

สามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Autovacuum operation ได้ที่นี่ , บล็อกโพสต์เกี่ยวกับ pg_repack , บล็อกโพสต์เกี่ยวกับ Autovacuum

6. Questions List เพื่อเป็นแนวทางในการรีวิว

  • database มี right sizing เหมาะสมกับ workload หรือไม่
  • database parameter เป็นไปตาม best practices ทางด้าน performance หรือไม่
  • มี process สำหรับจัดการ bloat หรือมี database maintenance หรือไม่
  • Index optimize เหมาะกับ workload แล้วหรือไม่
  • database schema ออกแบบเพื่อรองรับการ scale แล้วหรือไม่
  • จัดการ connection ใน database อย่างไร
  • มี optimize SQL statement เพื่อให้ performance ดีขึ้นหรือไม่
  • มีการ scale ในส่วนของ write/read หรือไม่
  • มีการ monitor performance ใน database หรือไม่

บทสรุป

ในบล็อกโพสต์นี้ ผมได้รวบรวมแนวทางในการรีวิว AWS Well-Architected สำหรับ Amazon RDS PostgreSQL ในด้าน Performance Efficiency เพื่อปรับปรุง performance database ให้ดีขึ้น ด้วยการทำ Database Right Sizing, การ configure database, การ monitor database, การ scale, การ maintenance database ด้วยการทำ Vacuum, และรวบรวมคำถามที่เกี่ยวข้อง ซึ่งหวังว่าจะช่วยให้ผู้อ่านได้เห็นภาพรวมเกี่ยวกับการทำ performance tuning Amazon RDS PostgreSQL ได้ดีมากขึ้นครับ