วิธีการประมาณค่าใช้จ่าย cloud infrastructure แบบบ้าน ๆ
การประมาณ (estimate) ค่าใช้จ่ายในการใช้งาน infrastructure บน cloud มีความสำคัญสำหรับธุรกิจและองค์กรไม่ว่าจะเล็กหรือใหญ่ แม้ว่าการเลือกใช้ cloud มีความสะดวกสบายและยืดหยุ่น แต่ก็ต้องพิจารณาค่าใช้จ่ายอย่างรอบคอบ เพื่อให้การใช้งานเป็นไปอย่างมีประสิทธิภาพและเหมาะสมกับทรัพยากรทางการเงินขององค์กร โดยการคำนวนต้นทุนของ software หลังจากนำไปรวมกับต้นทุนแฝงด้านคนและงานบริการจะต้องสอดคล้องกับ pricing model เพื่อให้ software ตอบโจทย์ business ในการสร้างกำไรได้
มาดูกันว่าขั้นตอนแบบบ้าน ๆ ในการประมาณ cloud infrastructure ในบทความนี้มีอะไรบ้าง
หมายเหตุ
ค่าใช้จ่ายที่เกิดขึ้นจากการคำนวณตามบทความนี้เป็นเพียงแค่การประมาณเท่านั้น ค่าใช้จ่ายจริงอาจจะเปลี่ยนไปตามปัจจัยต่าง ๆ อาทิเช่น configurationในแต่ละ resource, network และ traffic ที่เกิดขึ้น, ลักษณะการใช้งานของ user เป็นต้น
1. เข้าใจลักษณะของ cloud ที่เราจะใช้
ขั้นตอนแรกคือการเก็บข้อมูล ยิ่งเรามีข้อมูล cloud และ resources ที่จะใช้มากเท่าไร การพิจารณาเลือกใช้ cloud provider ก็จะทำได้อย่างเหมาะสมมากขึ้นเท่านั้น โดยสิ่งที่เราควรจะรู้ ศึกษาและเข้าใจก่อนก็อย่างเช่น
- เราใช้ private cloud (on-premise) หรือ public cloud
- Budget ของเรามีประมาณเท่าไร
- Component ของระบบมีอะไรบ้าง เช่น web app, database, networking, authentication, observability เป็นต้น
- ต้องมี license หรือ subscription อะไรบ้าง ค่าใช้จ่ายเท่าไร
- ความคุ้มค่าของทีมในการ maintain resource เองเมื่อเทียบกับการ managed service เป็นอย่างไร
- Cloud provider เจ้าไหนมี service ที่ตอบโจทย์ระบบเรา รวมถึง ทั้ง functional และ cross-functional requirement
- ความคุ้มค่าของทีมในการวางแผนกรณีที่จะต้องย้าย cloud ไปอีกเจ้า
2. เข้าใจ cross-functional requirement ของระบบ
หลังจากเลือก cloud provider ได้แล้วต่อมาคือประมาณการใช้งานของระบบโดยแต่ละ resource ก็มีวิธีคิดค่าใช้จ่ายตามการใช้งานที่แตกต่างกันไป แต่โดยรวมแล้วจะมีสิ่งที่คล้าย ๆ กัน เช่น
- Resource ที่ใช้ต้องตั้งอยู่ใน region ไหนบ้าง เพื่อตอบโจทย์ด้าน cost และ availability ที่ต้องการ
- Resource สามารถ share กับคนอื่นได้ไหมในประเด็นด้าน data policy เนื่องจากการใช้ resource ใน cloud ไม่ได้หมายความว่าเราใช้อยู่คนเดียว
- ขนาดของ data ที่ใช้ประมวลผล (ทั้งแบบ compressed และไม่ compressed) เช่นดูผ่าน API request body, จำนวน record ใน local database กับ storage ที่กินไป เป็นต้น
- Service ในระบบเน้นการใช้งาน CPU (data processing, video encoding) หรือว่า memory (databases, caching) เป็นหลัก
- โดยปกติแล้วระบบอยากจะรับ request/sec ได้เฉลี่ยประมาณเท่าไร
- มี traffic ที่ peak ช่วงไหน เป็นระยะเวลาเท่าไร
- SLA และ uptime requirement เป็นอย่างไร เช่น การจัดการ redundancy และ disaster recovery plan สำหรับ 99.5% กับ 99.9% แตกต่างกันพอสมควร
- หากระบบต้อง scale ต้องทำแบบ horizontal หรือ vertical (โดยปกติแล้ว horizontal จะถูกกว่าแต่ถ้า resource เป็น stateful ตอนรวมข้อมูลเข้ามาจะใช้ effort จัดการได้ยากขึ้น เช่น database)
- ในกรณีที่ resource ที่มีมากกว่า 1 อัน เช่น compute instance ให้คำนวณราคาโดยคิดเป็นต่อ 1 ตัว และแบ่งเลยว่า ขั้นต่ำ-ปกติ-สูงสุด จะต้องใช้ instance ไม่เกินกี่อัน เพื่อให้เราสามารถเห็นภาพมากขึ้นถ้าต้องปรับจำนวนขึ้น-ลงในอนาคต
- ใช้ระบบในระยะสั้นหรือระยะยาว (เกิน 3 ปี) เพราะ resource บางตัวมี saving plan เพื่อให้เราซื้อแบบเหมาไปเลย 3 ปีโดยจ่ายถูกกว่า pay-as-you-go
- ใน 1–2 ปีข้างหน้า คาดว่าจะมีลูกค้าเพิ่มขึ้นมากี่เท่า แล้ว architecture ส่วนไหนจำเป็นต้องเปลี่ยนบ้างเพื่อรองรับ scale เหล่านั้น
ผลลัพธ์คือเราจะสามารถเลือก spec ของ resource ได้ใกล้เคียงกับการใช้งานจริงประมาณนึง
Tips
บางคนอาจจะเริ่มต้นไม่ถูกว่าตัวเลขที่เหมาะสมคืออะไร ให้ลองคิดกลับกันว่า “ระบบเราจะใช้ไม่มีทางเกินเท่าไร” เป็นจุดตั้งต้นแล้วค่อยปรับไปตามความเหมาะสมทีหลังเพื่อให้การประมาณครั้งถัด ๆ ไปแม่นยำมากขึ้น
3. ใช้ calculator ของ cloud provider
ถ้าต้องการจะประหยัดแรงในการคำนวณ แนะนำให้ใช้ calculator ของ cloud provider เจ้าที่ต้องการเพราะเราสามารถกรอก specใน form แล้วก็จะได้ราคาออกมาเลย นอกจากนั้นยังสามารถ export ออกมาดูเป็น format ที่นำไป present ได้ เช่น CSV, PDF เป็นจ้น และสามารถประมาณค่าใช้จ่ายเป็นรายปีซึ่งเหมาะสำหรับองค์กรที่ต้องขอ budget สำหรับทั้งปี เช่น
หมายเหตุ: จากประสบการณ์ใช้งานจริง การคิดเงินของบาง resource ที่อยู่ใน calculator อาจจะไม่ตรงกับ resource จริง แนะนำให้สุ่ม check resource ที่กินเงินเยอะที่สุดเพื่อความมั่นใจอีกที
4. Monitor ค่าใช้จ่ายอย่างสม่ำเสมอ
หลังจากเราใช้งาน cloud ไปสักระยะนึงแล้วกลับมาดูค่าใช้จ่ายจะพบว่ามันยากมาก ๆ นะที่จะประมาณได้แบบเป๊ะ ๆ ตั้งแต่ครั้งแรก เราขอแนะนำว่าจะง่ายกว่าถ้าเรา monitor ค่าใช้จ่ายแล้วปรับ tune ให้เหมาะสมไปเรื่อย ๆ (optimise) จนเข้าที่เข้าทาง โดยขั้นตอนคร่าว ๆ ในการ monitor และ optimise มีดังนี้
- เลือก resource ที่เราต้องการจะ optimise หากเลือกไม่ถูกให้เลือกจากอันที่กินเงินเยอะที่สุด
- เข้าไปดู monitoring ของ resource นั้น ๆ เช่น CPU, memory, storage, data transfer เป็นต้น หากไม่มีให้ติดตั้งทันที เลือกระยะเวลาที่ต้องการจะเก็บข้อมูล เป็นรายชั่วโมง-วัน-เดือน ซึ่งอันนี้ก็แล้วแต่ว่า resource เราคิดเงินยังไง
- นำข้อมูลที่ได้มาทำการคำนวณและ optimise ต่อ โดยจะแบ่ง resource ออกเป็น 2 ส่วนหลัก ๆ ได้แก่ส่วน data transfer กับส่วน compute instance & data storage
4.1 ส่วน data transfer
หากเราเข้าไปดูค่าใช้จ่ายใน cloud หลายครั้งจะพบว่า ค่าใช้จ่ายส่วนนี้มักจะสูงกว่าส่วนอื่น ๆ เนื่องจากระบบต้อง communicate ข้าม network boundary กันผ่าน resource อย่าง API gateway, NAT gateway หรือแม้กระทั่ง file storage เป็นต้น ถึงแม้เราอาจจะเลี่ยงการใช้งาน resource เหล่านี้ไม่ได้ แต่เราก็สามารถ optimise ระบบในเชิง architecture ได้อยู่ มีขั้นตอนดังนี้
- ระบุข้อมูล data transfer ทั้งขาเข้าและขาออก (inbound และ bound) ออกมา
- ทำการลด data transfer ลงให้ได้มากที่สุดเท่าที่จะเป็นไปได้ ซึ่งก็มีด้วยกันหลายวิธี เช่น ใช้ Content Delivery Network (CDN), การทำ data compression และหรือ caching, การใช้ batch processing ในกรณีที่ไม่ต้องการข้อมูลแบบ real-time
- เมื่อเวลาผ่านไปสักระยะให้กลับมา monitor เพื่อดูว่าค่าใช้จ่ายลดลงไหม และอย่าลืมนำค่าใช้จ่ายที่เกิดขึ้นจาก resource ใหม่มาคำนวณด้วย
4.2 ส่วน compute instance &data storage
- ระบุข้อมูลการใช้งานสูงสุด (maximum utilisation) ออกมา เช่น ดูว่าใช้ CPU, memory ในช่วง peak time ไปเท่าไรหรือกี่หน่วย
- ทำการ normalise ค่าใช้จ่ายโดยสูตร cost / maximum utilisation ก็จะได้ออกมาเป็น ราคาต่อ 100% utilisation หรือ ราคาต่อ measurement unit เช่น MB เป็นต้น
- ใช้ cloud provider calculator คำนวณราคาใหม่ โดยปรับ spec ให้เหมาะสมตามต้องการ และใส่ input ด้วย utilisation ปัจจุบัน หากเป็น % อย่าลืมปัญญัติไตรยางค์ก่อน
- ทำการ normalise ค่าใช้จ่ายอีกครั้ง
- เปรียบเทียบค่าที่ได้ 2 อันด้วยกัน แล้วสังเกตอาการผิดปกติที่เกิดขึ้นว่า provision ขาดหรือเกินความต้องการ
- ปรับ tune spec ที่เลือกแล้ว monitor เพื่อดูว่าดีขึ้นไหม
ยกตัวอย่าง
สมมติว่ามี compute resource อยู่ตัวนึง เราพบว่าในเดือนแรก
- ค่าใช้จ่ายของ resource: 1000 บาท
- Peak CPU utilisation: 90%
- Peak memory utilisation: 600MB
คำนวณ normalised cost โดยสูตร cost / maximum utilisation จะออกมาเป็น
- CPU: 1000 บาท/90% = 1111.11 บาทต่อการใช้งานเต็ม 100%
- Memory: 1000 บาท/600 MB = 1.66 บาทต่อ MB
พอวิเคราะห์ดูแล้วพบว่า CPU ใช้ไป 90% ก็มีโอกาสสูงที่ resource จะ underprovision อาจจะเกิดปัญหา performance ได้ จึงลองปรับ spec แล้วลอง monitor ดูอีกครั้งในเดือนถัดไปได้ประมาณนี้
- ค่าใช้จ่ายของ resource: 1200 บาท
- Peak CPU utilisation: 70%
- Peak memory utilisation: 800MB
คำนวณ normalised cost จะออกมาเป็น
- CPU: 1200/70% = 1714.28 บาทต่อการใช้งานเต็ม 100%
- Memory: 1200/800MB = 1.5 บาทต่อ MB
พอวิเคราะห์ดูแล้วจะพบว่าถึงแม้ spec ใหม่จะแพงกว่า 200 บาท แต่ก็ลดความเสี่ยงของปัญหา performance ลงได้ และความคุ้มค่าในการใช้ memory ก็ดีกว่าแบบแรก
Tips
บางคนอาจจะมองว่าการ optimise มันซับซ้อนเกินไป ให้เริ่มต้นจากการทำตามคำแนะนำของ cloud provider ผ่านเครื่องมือต่าง ๆ เช่น AWS Compute Optimizer, Microsoft Cost Management, GCP Active Assist เป็นต้น
เรามีบทความที่พูดถึงเรื่องนี้ในหัวข้อ Practical cost-saving automation for AWS accounts ด้วย
5. ทำ projection ราคาออกไปอีกสัก 3 ปี (optional)
หลังจากเราคำนวณราคาพร้อมกับ spec ออกมาได้แล้ว ให้ลองคาดการณ์ว่าในอีก 3 ปี แนวโน้มของค่าใช้จ่ายเพิ่มขึ้นมากแค่ไหนเพื่อให้ทุกคนเห็นภาพต้นทุนที่กำลังจะเกิดขึ้นในอนาคต เช่น
- เริ่มต้นมี user อยู่ 1,000 คน ค่าใช้จ่ายทั้งหมด 10,000 บาท แปลว่าค่าใช้จ่ายต่อ user อยู่ที่ 10,000/1,000 = 10 บาทต่อ user
- ปีที่ 2 มี user อยู่ 10,000 คน ค่าใช้จ่ายทั้งหมด 75,000 บาท แปลว่าค่าใช้จ่ายต่อ user อยู่ที่ 75,000/10,000 = 7.5 บาทต่อ user
- ปีที่ 3 มี user อยู่ 50,000 คน ค่าใช้จ่ายทั้งหมด 200,000 บาท แปลว่าค่าใช้จ่ายต่อ user อยู่ที่ 200,000/50,000 = 4 บาทต่อ user
จะสังเกตว่ายิ่งเวลาผ่านไป ค่าใช้จ่ายต่อ user จะน้อยลงไปเรื่อย ๆ แต่ถ้าเรายังเก็บตังค์จาก user ต่อคนเท่าเดิม แปลว่าเรามีโอกาสที่จะทำกำไรได้มากขึ้นนั่นเอง ทั้งนี้ทั้งนั้นมันก็เป็นแค่การประมาณคร่าว ๆ เนื่องจากว่าท่านี้มันต้องตั้ง assumption เยอะพอสมควร เช่น
- มีจำนวน feature เท่าเดิมหรือถ้ามีใหม่ก็ต้องไม่มีผลต่อค่าใช้จ่ายมาก
- พฤติกรรมการใช้งานของ user หน้าเก่าไม่เปลี่ยนไปจนมีผลต่อค่าใช้จ่ายอย่างมีนัยสำคัญ
วิธีการเริ่มต้นคือให้คาดการณ์จำนวน user ในแต่ละปี แล้วปรับ spec ที่สามารถรองรับได้ไปเรื่อย ๆ
ตัวอย่างใน compute resource
ในช่วงเริ่มต้นเรามี user อยู่ 100 คน จากการคำนวณและ monitor แล้วพบว่า
- เราใช้ compute resource อยู่ 5 instance
- โดยเฉลี่ยเราใช้ CPU อยู่แค่ 20% (ดูจะ overprovision อยู่)
- มีการตั้ง autoscale ไว้ในกรณีที่ CPU usage เกิน 70% ขึ้นไป
โจทย์คือแล้วถ้า user เพิ่มขึ้นเป็น 10,000 คนล่ะจะต้องใช้กี่ instance
ก่อนอื่นให้เราแยก CPU usage 20% นั้นออกมาเป็น 2 ส่วนคือ
- ส่วน baseline ก็คือ CPU และ memory ที่ใช้เมื่อ service ไม่ได้มี traffic เข้ามาและตั้งทิ้งไว้เฉย ๆ
- ส่วนการใช้งานจริงใน app
เพื่อที่เราจะได้นำเฉพาะส่วนการใช้งานจริงใน app เท่านั้นไปคำนวณต่อ
ทีนี้จากการ monitor เราพบว่า 20% นั้นเกิดจาก baseline 5% และการใช้งานจริง 15% ละกัน
นั่นหมายความว่า user 1 คน จะใช้ CPU ไปโดยเฉลี่ย 15%/100 users = 0.15% ต่อ 1 user
ทีนี้เราก็สามารถคำนวณได้แล้วว่าใน 1 instance มันสามารถรับได้สูงสุดได้กี่ user ที่ CPU limit (ในโจทย์เราตั้ง autoscaler ไว้ที่ 70%) โดยใช้สูตร
(maxCPU — baseline) / CPU per user
ก็จะได้ผลลัพธ์เป็น (70%–5%) / 0.15% ~= 433 user
ถ้ามี user 10,000 คนจะต้องใช้ 10,000 users/433 users ~= 23 กว่า ๆ ~= 24 instance จากเดิม 5 instance เราก็จะได้ส่วนต่าง (24–5 = 19 instance ที่เพิ่มขึ้น) มาคำนวณต่อได้ละ
อีกตัวอย่างใน database
ปัจจุบันระบบเรามี database ซึ่งมี storage อยู่ที่ 50GB ในแต่ละเดือนจะมี order เพิ่มเข้ามาใน database 2 ล้าน records ต่อเดือน
โจทย์คือแล้ว storage เราจะอยู่ได้นานเท่าไรก่อนจะเต็ม
เราจะต้องรู้ก่อนว่า order แต่ละ record โดยเฉลี่ยมีขนาดเท่าไร ซึ่งแต่ละ database ก็จะมีเครื่องมือในการวัด table size ต่างกันไป เช่นใน PostgreSQL เราสามารถเรียกใช้คำสั่ง SQL เพื่อวัดค่า 2 ค่าดังนี้
SELECT pg_size_pretty(pg_total_relation_size('"<schema>"."<table>"'));
- Storage size ของ table ที่สร้างขึ้นมาโดยไม่มี record ใด ๆ (วิธีง่าย ๆ ก็สร้าง database บน local แล้วสร้าง schema/table ขึ้นมา)
- Storage size ของ table ที่มี 1 record insert เข้าไป (สามารถคิดเผื่อโดยหยิบเอา record ที่ใหญ่ที่สุดก็เคยมีอยู่มาก็ได้)
นำผลลัพธ์ทั้งสองมาลบกัน ผลที่ได้คือ Storage size ของ 1 record โดยประมาณ (สมมติว่าได้ 1KB = 0.000001GB)
คราวนี้เราก็จะแล้วว่า order 2 ล้าน record จะกิน storage ไปเท่าไรโดยใช้สูตร
Storage size ของ table ที่สร้างขึ้นมาโดยไม่มี record ใด ๆ + (Storage size ของ 1 record * จำนวน record ที่กะไว้)
สมมติว่าผลออกมาประมาณ 2GB ต่อเดือน ก็จะได้ข้อสรุปว่า database ที่มี storage 50GB เราจะอยู่ได้ 50GB/2GB = 25 เดือน ~= 2 ปีก่อนจะเต็ม
ซึ่ง ณ จุดนี้เราสามารถเลือกที่จะ scale storage ขึ้นเองหรือจะใช้ managed service เพื่อทำ autoscale ก็ได้ไม่ว่ากัน แต่ราคาก็จะขยับขึ้นแน่ ๆ
TL;DR
การประมาณ (estimate) ค่าใช้จ่ายในการใช้งาน infrastructure บน cloud แบบบ้าน ๆ มีขั้นตอนดังนี้
- เข้าใจลักษณะของ cloud ที่เราจะใช้ เพื่อให้เราเลือกใช้ cloud provider ได้อย่างเหมาะสมมากขึ้น
- เข้าใจ cross-functional requirement ของระบบ เพื่อกะ spec ของ resource ได้ใกล้เคียงกับการใช้งานจริงประมาณนึง
- ใช้ calculator ของ cloud provider เพื่อทุ่นแรงในการคำนวณ
- Monitor ค่าใช้จ่ายอย่างสม่ำเสมอ แล้ว optimise ไปเรื่อย ๆ เพื่อให้การประมาณครั้งถัด ๆ ไปแม่นยำมากขึ้น
- ทำ projection ราคาออกไปอีกสัก 3 ปี (optional) เพื่อให้ทุกคนเห็นภาพต้นทุนที่กำลังจะเกิดขึ้นในอนาคต
ขอย้ำอีกทีตามหมายเหตุข้างบน ค่าใช้จ่ายที่เกิดขึ้นจากการคำนวณตามบทความนี้เป็นเพียงแค่การประมาณเท่านั้น ค่าใช้จ่ายจริงอาจจะเปลี่ยนไปตามปัจจัยต่าง ๆ เราเพียงต้องการประมาณเพื่อที่จะกะต้นทุนคร่าว ๆ ให้ทาง business นำไปพิจารณาว่าการลงทุนที่กำลังจะเกิดขึ้นนั้นมันคุ้มกับ business values ที่จะเกิดขึ้นมากน้อยแค่ไหน
นอกจากเรื่องเกี่ยวกับ cloud และ infrastructure แล้ว ขอฝากบทความอื่น ๆ ให้ติดตามกันได้ทั้งภาษาไทยและอังกฤษด้วยนะ ขอบคุณที่เข้ามาอ่านกันครับ