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 มีขนาดน้อยเกินไป ส่งผลให้ภาพรวมการทำงานช้าลง
ข้อแนะนำ:
- เนื่องจากการเลือก database instance จะเป็นการเลือก vCPU กับ Memory ที่มีให้ ดังนั้นต้องพิจารณาว่า workload ที่จะรัน เน้นการใช้ CPU หรือ Memory สูง โดยทำการทดสอบการรัน workload เพื่อปรับขนาดให้เหมาะสม
- ทดสอบการใช้งาน Graviton2 Processor เพื่อให้ได้ในเรื่องของ Price performance ที่ดีขึ้น สามาถเรียนรู้เพิ่มเติมได้ที่บล็อกโพสต์นี้
- ใน Amazon RDS Console มีฟีเจอร์ Performance Insights ซึ่งจะแสดงค่า Average active sessions (AAS) เป็นเส้นประ แสดงถึง Maximum CPU สามารถใช้เป็นเส้นบ่งชี้ว่า database instance CPU เหมาะสมกับ Workload หรือไม่ สามารถเรียนรู้เกี่ยวกับ Performance Insight เพิ่มเติมได้ที่นี่
- สำหรับ Memory ควรมีพื้นที่ว่างสำหรับ Memory ประมาณ ~20%
- พิจารณาการ enable HugePages เพื่อลด overhead ในการทำงานกับ memory ที่ใหญ่ขึ้น เหมาะสำหรับ instance ขนาดใหญ่
สามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Huge pages สำหรับ RDS for PostgreSQL ได้ที่นี่ - BufferCacheHitRatio หรือ % การ access ข้อมูลใน Buffer cache ควรเป็น 99% ซึ่งถ้า % ในการ access ข้อมูลใน memory มีค่าลดลงอาจเป็นเพราะขนาดของ memory ไม่เพียงพอต่อการใช้งาน สามารถเรียนรู้เพิ่มเติมเกี่ยวกับบล็อกโพสต์นี้ (ในบล็อกโพสต์เป็น Amazon Aurora แต่สามารถใช้เป็นแนวทางได้เช่นกัน)
- ควรตรวจสอบ read/write latency metric ต่างๆ ซึ่งสามารถดูได้ใน Amazon CloudWatch
- หลีกเลี่ยงการใช้ T instance type (Burstable) กับงาน production workload เพราะ performance จะน้อยกว่า instance type อื่นๆ โดย T instance type จะเหมาะกับงาน Dev/Test หรือปริมาณ workload ไม่ได้ต้องการ performance มาก
- เลือก storage ให้เหมาะสม ใน Amazon RDS จะมี storage type:
- General Purpose SSD เหมาะกับงานทั่วไป IOPS สามารถสูงขึ้นได้ตามขนาดของ storage มีให้ 3 IOPs/GiB, สูงสุด 16,000 IOPS
- Provisioned IOPS ซึ่งเหมาะกับการใช้งาน IOPS สูงๆ สามารถระบุตัวเลขได้ชัดเจน มีให้ 1,000 – 256,000 IOPs (ขึ้นอยู่กับประเภท Database instance)
- สามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Storage บน Amazon RDS ได้ที่นี่
- ควร enable Amazon RDS storage autoscaling ไว้ เพื่อให้ scale storage เพิ่มขึ้นได้เวลาข้อมูลใกล้เต็ม สามารถเรียนรู้รายละเอียดเกี่ยวกับ autoscaling feature ได้ที่นี่
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
- สามารถเลือกใช้ proxy service สำหรับ connection pooling เพื่อลด idle connection และลด resource overhead ของ connection บน database ได้ เพื่อช่วยรองรับการ scale, เพิ่ม security, รวมทั้งลดเวลาการ failover time ของ application สามารถเรียนรู้เพิ่มเติมได้ที่ Amazon RDS Proxy ในบล็อกโพสต์นี้
- 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:
- Performance Insights
- CloudWatch Metrics ต่างๆ ที่เกี่ยวกับ database เช่น CPU Utilization, Freeable Memory, Read/Write Latency, Read/Write IOPS
- Enhanced Monitoring เพื่อให้ดูค่า operating system ของ DB instance ได้แบบ real time สามารถดูรายละเอียดเพิ่มเติมได้ที่นี่
- ระดับ 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 เเทน
- ข้อแนะนำเกี่ยวกับ Primary Key
- Application Access
- Enable autocommit
- ควรปิด connection เมื่อทำงานเสร็จ
- ตรวจสอบ long running query สามารถเรียนรู้เพิ่มเติมได้ที่นี่
- ลด idle PostgreSQL connections สามารถเรียนรู้เพิ่มเติมได้ที่นี่
- 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
- ลด index ที่ไม่ได้ใช้งาน
- Tuning process การ Checkpoint
- Vacuum ลบ row version ที่เก่าออก
- Optimize สำหรับ Bulk loading
- Optimize สำหรับ Read heavy workload
- Manage Data Growth
- การกระจายประเภทของ workload read และ write โดยการใช้ read replica เข้ามาช่วย
- ใช้ Amazon RDS Proxy เพื่อรองรับการ scale ขอแอปพลิเคชัน
- การทำ database sharding ทั้งเรื่องการ scale ในส่วนของ instance ตามประเภทการใช้งาน สามารถเรียนรู้เพิ่มเติมได้ที่นี่
- การทำ partitioning database ซึ่ง Amazon RDS for PostgreSQL สามารถใช้ pg_partman extention สามารถเรียนรู้เพิ่มเติมได้ที่นี่ , Archive และ purge data จาก Amazon RDS โดยใช้ pg_partman และ Amazon S3
- พิจารณา Amazon Aurora PostgreSQL เป็นอีกทางเลือกเพื่อ improve ในเรื่องของ performance และ high availability
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 ได้ดีมากขึ้นครับ