ภาพลวงตา Connection Pool: ทำไมเปิดท่อต่อ DB แค่ 10 ช่อง ถึงเร็วกว่าเปิด 1,000 ช่อง?
⏱️ ใช้เวลาอ่านประมาณ: 4 นาที 20 วินาที
เมื่อทราฟฟิกหน้าเว็บกระชากแตะระดับ 10,000 Concurrent Users สัญชาตญาณแรกของโปรแกรมเมอร์ส่วนใหญ่คือ: "ไปเพิ่ม maximum-pool-size ของ HikariCP จาก 10 เป็น 500 หรือ 1,000 ไปเลยสิ จะได้ไม่ต้องแย่งกัน!"
แต่ทันทีที่ Deploy ขึ้น Production ผลลัพธ์กลับกลายเป็นนรก: Response Time ที่เคยเร็วระดับมิลลิวินาที พุ่งทะยานไป 15 วินาที CPU ของ Database พุ่งแตะ 100% แล้วทั้งระบบก็นิ่งสนิท!
ทำไมยิ่งเปิดประตูให้รถวิ่งเข้าเยอะขึ้น รถกลับยิ่งติดจนขยับไม่ได้?
🖥️ ความจริงกายภาพ: CPU มีแค่ไม่กี่คอร์
ลองนึกภาพเครื่องเซิร์ฟเวอร์ Database ของคุณมี CPU 8 Cores
ตามหลักการทางฟิสิกส์ คอมพิวเตอร์เครื่องนี้สามารถคำนวณและประมวลผลคำสั่งจริงๆ พร้อมกันในเสี้ยววินาทีเดียวได้ แค่ 8 คำสั่งเท่านั้น
"ถ้าคุณเปิดท่อ Connection ไว้ 1,000 ช่อง Database จะต้องรับ Thread เข้ามาพร้อมกัน 1,000 ตัว เพื่อมารุมแย่งช่าง 8 คนทำงาน!"
🥊 หายนะ Context Switching: สลับงานจนไม่ได้ทำงาน
เมื่อ Thread นับพันตัวกระหน่ำเข้ามา สิ่งที่ CPU ต้องทำไม่ใช่การรัน SQL Query แต่คือ:
- ทำคำสั่งของ Thread 1 ไปได้ 0.1ms ➔ ต้องเซฟ Memory State ลงแรม
- สลับไปหยิบ Thread 2 ขึ้นมาทำต่ออีก 0.1ms ➔ เซฟทิ้ง สลับไป Thread 3
- แย่งชิง Disk I/O และแคชใน L1/L2 Cache หลุดกระจาย (Cache Invalidation)
พลังการประมวลผล 80% ของ CPU ถูกเผาทิ้งไปกับ Context Switching (ค่าใช้จ่ายในการสลับหน้าจอ) แทนที่จะเอาเวลาไปดึงข้อมูลจริงให้เสร็จไวๆ
📐 สูตรลับจากทีมสร้าง PostgreSQL: Pool Size ที่แท้จริง
ผู้สร้างฐานข้อมูลระดับโลกและทีมพัฒนา HikariCP แนะนำสูตรคำนวณขนาด Connection Pool สูงสุดไว้สั้นๆ แต่ทรงพลัง:
ถ้าเครื่องเซิร์ฟเวอร์ DB ของคุณมี 8 คอร์ และใช้ฮาร์ดดิสก์แบบ SSD (Spindle = 1):
(8 × 2) + 1 = 17 Connections เท่านั้น!
เมื่อคุณจำกัด Connection ไว้ที่ 17 ช่อง:
- แต่ละ Connection จะได้ CPU เต็มเม็ดเต็มหน่วย รันคำสั่งเสร็จใน 1ms แล้วปล่อย Connection ทันที
- Request อื่นๆ ที่รออยู่ใน Queue บน Spring Boot จะต่อคิวอย่างเป็นระเบียบ แล้วผลัดกันหยิบท่อไปใช้ต่อได้ทันที
- ผลลัพธ์คือ Throughput พุ่งขึ้นสูงกว่า และ Response Time นิ่งสนิท ไม่มีสไปก์แกว่ง
💡 5-Min Takeaway
"ท่อยิ่งเยอะ ไม่ได้แปลว่าน้ำจะไหลแรงขึ้น ถ้าก๊อกปลายทางมีขนาดเท่าเดิม" Connection Pool มีไว้เพื่อ จำกัดการแย่งชิงทรัพยากร ไม่ใช่เปิดให้เข้ามาถล่มจนเซิร์ฟเวอร์น็อก การปล่อยให้คำขอต่อคิวรอที่หน้าแอปพลิเคชันอย่างเป็นระเบียบ ดีกว่าการปล่อยให้ทุกคำขอทะลักเข้าไปเหยียบกันตายในห้องเครื่องของ Database