การทดลองทดสอบโหลดล่าสุดที่ศึกษาว่าเครื่องเดียวสามารถจัดการคำขอ HTTP ได้กี่ครั้งต่อวินาทีได้จุดประกายให้เกิดการอภิปรายในชุมชนนักพัฒนาเกี่ยวกับตัวเลือกการจัดเก็บฐานข้อมูล การรวม connection และขณะจำกัดที่แท้จริงของฮาร์ดแวร์สมัยใหม่ การทดสอบใช้การตั้งค่าพื้นฐานกับ PostgreSQL ที่มีข้อมูลมากกว่าหนึ่งล้านเรคคอร์ดและวัดประสิทธิภาพในโปรไฟล์โหลดที่แตกต่างกน
การกำหนดค่าฐานข้อมูล:
- PostgreSQL พร้อมข้อมูลมากกว่า 1 ล้านเรคอร์ด
- Hikari Connection Pool: 10 การเชื่อมต่อเริ่มต้น สามารถขยายได้ถึง 20
- External DigitalOcean Block Storage (ไม่ใช่ระบบไฟล์ในเครื่อง)
- ขีดจำกัดการเชื่อมต่อ PostgreSQL เริ่มต้น: ประมาณ 100 การเชื่อมต่อ
การกำหนดค่าการจัดเก็บฐานข้อมูลทำให้เกิดคำถาม
การตั้งค่าการทดสอบใช้ external block storage สำหรับฐานข้อมูลแทนที่จะใช้ local filesystem storage ซึ่งดึงดูดความสนใจจากนักพัฒนาหลายคน ตัวเลือกนี้ส่งผลกระทบต่อประสิทธิภาพอย่างมีนัยสำคัญเนื่องจาก block storage เพิ่ม network latency ให้กับทุกการทำงานของฐานข้อมูล สมาชิกในชุมชนชี้ให้เห็นว่าการใช้อะไรก็ตามนอกเหนือจาก local filesystem สำหรับฐานข้อมูลโดยทั่วไปไม่แนะนำสำหรับแอปพลิเคชันที่ต้องการประสิทธิภาพสูง
อย่างไรก็ตาม สภาพแวดล้อม cloud มักต้องการการแลกเปลี่ยนนี้ Block storage ให้ความน่าเชื่อถือและการคงอยู่ของข้อมูลเมื่อ instance อาจล้มเหลวได้ตลอดเวลา ในขณะที่ local storage ให้ประสิทธิภาพที่ดีกว่าแต่มีความเสี่ยงต่อการสูญเสียข้อมูล ความตึงเครียดพื้นฐานระหว่างประสิทธิภาพและความน่าเชื่อถือนี้มีอิทธิพลต่อการตัดสินใจด้านสถาปัตยกรรมหลายอย่างในแอปพลิเคชันสมัยใหม่
ข้อจำกัดของ Connection Pool เริ่มชัดเจน
การทดสอบเผยให้เห็นคอขวดในการจัดการ database connection โดยการตั้งค่าใช้ Hikari Connection Pool ที่กำหนดค่าสำหรับ 10 connection เริ่มต้นที่สามารถขยายได้ถึง 20 การวิเคราะห์ของชุมชนชี้ให้เห็นว่าขนาด connection pool ที่ค่อนข้างเล็กนี้น่าจะจำกัดประสิทธิภาพก่อนที่จะถึงขีดจำกัดของฮาร์ดแวร์จริง
ขีดจำกัด connection เริ่มต้นของ PostgreSQL ที่ประมาณ 100 concurrent connection ควรให้พื้นที่เพียงพอเมื่อมีการรวม pool อย่างเหมาะสม การอภิปรายเน้นย้ำว่าด้วยคำขอหลายพันครั้งต่อวินาทีที่เป็นไปได้ การกำหนดขนาด connection pool จึงมีความสำคัญต่อการหลีกเลี่ยงคอขวดเทียม
มุมมองฮาร์ดแวร์ท้าทายสมมติฐาน
การทดสอบอธิบายเครื่อง 8-CPU, 16GB RAM ว่าเป็นเครื่องขนาดใหญ่ ซึ่งได้รับการวิพากษ์วิจารณ์จากนักพัฒนาที่คุ้นเคยกับความสามารถของฮาร์ดแวร์สมัยใหม่ เครื่องผู้บริโภคระดับไฮเอนด์ในปัจจุบันสามารถรองรับ RAM 512GB ได้ ในขณะที่ระบบองค์กรสามารถขยายได้ถึง 20+ เทราไบต์ของหน่วยความจำและหลายร้อยคอร์
เครื่องขนาดใหญ่ในปัจจุบันมี RAM 20+ TB และหลายร้อยคอร์ แม้แต่เครื่องผู้บริโภคระดับท็อปเอนด์ก็สามารถมี RAM 512GB ได้!
ช่องว่างของมุมมองนี้ชี้ให้เห็นว่าแอปพลิเคชันหลายตัวสามารถขยายขนาดได้ไกลเกินกว่าสมมติฐานปัจจุบันโดยเพียงแค่อัปเกรดไปยังเครื่องเดียวที่มีประสิทธิภาพมากขึ้นแทนที่จะใช้สถาปัตยกรรมแบบกระจายที่ซับซ้อน
การกำหนดค่าเครื่องทดสอบ:
- เครื่องขนาดเล็ก: 4 CPU cores, 4 GiB memory
- เครื่องขนาดกลาง: 4 vCPU, 4 GiB memory
- เครื่องขนาดใหญ่: 8 vCPU, 4 GiB memory
- เครื่อง "ขนาดยักษ์": 8 CPUs, 16 GB memory
ข้อจำกัดของวิธีการทดสอบ
แนวทางการทดสอบโหลดใช้การจำกัดอัตราเทียมใน client code ซึ่งสมาชิกในชุมชนบางคนระบุว่าอาจทำให้ผลลัพธ์เบี่ยงเบนได้ การทดสอบจงใจจำกัดคำขอต่อวินาทีแทนที่จะวัด maximum sustainable throughput ทำให้ยากต่อการกำหนดขีดจำกัดประสิทธิภาพที่แท้จริง
นอกจากนี้ การรันทั้งแอปพลิเคชันและฐานข้อมูลบนเครื่องเดียวกันสร้างการแข่งขันทรัพยากรที่จะไม่เกิดขึ้นในการปรับใช้งานจริงทั่วไป แม้ว่าการทดสอบนี้จะทดสอบระบบทั้งหมดภายใต้ข้อจำกัดทรัพยากร แต่ก็ไม่ได้แยกประสิทธิภาพของเซิร์ฟเวอร์แอปพลิเคชันจากประสิทธิภาพของฐานข้อมูล
การทดลองแสดงให้เห็นว่าเครื่องเดียวสามารถจัดการโหลดที่มากได้ แต่ตัวเลขเฉพาะอาจไม่สะท้อนการกำหนดค่าที่เหมาะสมที่สุด สำหรับแอปพลิเคชันหลายตัวที่ใช้สถาปัตยกรรม microservices ที่ซับซ้อนในปัจจุบันเพื่อจัดการคำขอเพียงไม่กี่ครั้งต่อวินาที แม้แต่ผลลัพธ์ที่อนุรักษ์นิยมเหล่านี้ก็ชี้ให้เห็นว่าโซลูชันที่ง่ายกว่าอาจเพียงพอ
อ้างอิง: Load Testing: how many HTTP requests/second can a Single Machine handle?