← กลับไปหน้าบทความ
ขั้นสูง (MarTech)

R2 เก็บไฟล์แบบไม่มีค่า Egress แต่ยังมีเงื่อนไขที่ต้องรู้ก่อนย้ายจาก S3

ทีมบรรณาธิการ linli12 ส.ค. 04:52อัปเดต 12 ส.ค. 04:52อ่าน 4 นาที
R2 เก็บไฟล์แบบไม่มีค่า Egress แต่ยังมีเงื่อนไขที่ต้องรู้ก่อนย้ายจาก S3
บทความนี้จัดทำเพื่อความรู้ ชื่อธุรกิจ ตัวเลข หรือบทสนทนาที่ไม่มีแหล่งอ้างอิงกำกับเป็นกรณีตัวอย่างเพื่ออธิบายแนวคิด ดูรายละเอียดที่ นโยบายกองบรรณาธิการ

สรุปสั้น ๆ

Cloudflare R2 เป็น object storage ที่ใช้ S3-compatible API และไม่คิดค่า Egress เวลาดึงข้อมูลออกจากระบบ ทำให้ประหยัดต้นทุนได้มากสำหรับงานที่มีการดาวน์โหลดไฟล์ถี่ แต่ก่อนย้ายจาก S3 ทั้งระบบต้องตรวจสอบว่า feature ที่ใช้อยู่เดิมรองรับใน R2 ครบหรือไม่ และวางแผน consistency ให้เหมาะกับลักษณะงาน

ทีมที่ดูแลระบบเก็บไฟล์บน Amazon S3 มักเจอบิลค่า Egress ที่สูงขึ้นเรื่อย ๆ ตามปริมาณการดาวน์โหลดไฟล์ของผู้ใช้ โดยเฉพาะแอปที่มีผู้ใช้ดาวน์โหลดไฟล์ขนาดใหญ่บ่อย เช่นวิดีโอ รูปภาพความละเอียดสูง หรือไฟล์ backup ที่ผู้ใช้ export ออกไปเป็นประจำ ค่า Egress ของ S3 มักกลายเป็นสัดส่วนใหญ่ในบิล cloud โดยที่หลายทีมไม่ทันสังเกต

Cloudflare R2 เข้ามาเป็นทางเลือกที่ถูกพูดถึงมากขึ้นเพราะไม่คิดค่า Egress เลย และใช้ API ที่เข้ากันได้กับ S3 เป็นส่วนใหญ่ ทำให้ย้ายโค้ดเดิมมาได้โดยไม่ต้องเขียนใหม่ทั้งหมด แต่คำว่า 'เข้ากันได้เป็นส่วนใหญ่' ก็หมายความว่ามีบางส่วนที่ไม่เหมือนกันเป๊ะ ซึ่งเป็นจุดที่ทีมมักพลาดถ้าไม่ตรวจสอบให้ละเอียดก่อนย้ายจริง

บทความนี้จะพาไปดูตั้งแต่การคำนวณความคุ้มค่าจริงของการไม่มีค่า Egress, ความต่างของ consistency model, ไปจนถึง feature ที่ S3 มีมานานแต่ R2 ยังไม่รองรับครบ เพื่อให้ตัดสินใจย้ายระบบได้อย่างมีข้อมูลรอบด้าน ไม่ใช่ย้ายเพราะเห็นแค่ตัวเลขค่า Egress เป็นศูนย์อย่างเดียว

R2 คืออะไร และจุดขายเรื่อง Zero Egress Fee

R2 คือบริการ object storage ของ Cloudflare สำหรับเก็บไฟล์แบบไม่มีโครงสร้าง (unstructured data) เช่นรูปภาพ วิดีโอ เอกสาร หรือไฟล์ backup หลักการทำงานคล้ายกับ S3 ของ AWS คือเก็บข้อมูลเป็น object ภายใน bucket แต่ละ object มี key เป็นตัวระบุตัวตนไม่ซ้ำกันภายใน bucket เดียวกัน

จุดขายที่ทำให้ R2 ถูกพูดถึงมากที่สุดคือการไม่คิดค่า Egress เวลาดึงข้อมูลออกจากระบบไปยังอินเทอร์เน็ตภายนอก ซึ่งต่างจาก S3 ที่คิดค่า Egress ตามปริมาณข้อมูลที่ดาวน์โหลดออกไป ยิ่งแอปมีผู้ใช้ดาวน์โหลดไฟล์บ่อยเท่าไร ค่า Egress ของ S3 ก็ยิ่งเพิ่มขึ้นตามสัดส่วน ในขณะที่ R2 คิดค่าใช้จ่ายหลักจากพื้นที่จัดเก็บและจำนวน operation เท่านั้น

ข้อควรเข้าใจคือการไม่มีค่า Egress ไม่ได้แปลว่า R2 ฟรีทั้งหมด ยังมีค่าใช้จ่ายส่วนพื้นที่จัดเก็บ (storage) และค่า operation อย่างการ list, read, write ที่ต้องคำนวณตามปริมาณการใช้งานจริง ทีมที่มีปริมาณ operation สูงมากแต่ขนาดไฟล์เล็กอาจไม่ได้ประหยัดเท่าที่คาดถ้าเทียบกับ S3 ในบาง use case

R2 ใช้ S3-compatible API ได้จริงแค่ไหน

R2 ออกแบบ API ให้เข้ากันได้กับ S3 API ในระดับที่ SDK และเครื่องมือจำนวนมากที่เขียนไว้สำหรับ S3 สามารถเปลี่ยนแค่ endpoint แล้วใช้งานกับ R2 ได้ทันทีโดยไม่ต้องแก้โค้ด logic หลัก คำสั่งพื้นฐานอย่าง PutObject, GetObject, DeleteObject, ListObjects ทำงานได้ตรงตามมาตรฐาน S3 ทั่วไป

อย่างไรก็ตาม feature ขั้นสูงบางตัวของ S3 ที่สะสมมานานหลายปี เช่น S3 Select ที่ให้ query ข้อมูลภายในไฟล์โดยตรง, บาง lifecycle policy ที่ซับซ้อน, หรือ feature เฉพาะทางบางตัวของ AWS ecosystem อาจยังไม่รองรับครบใน R2 ทีมที่ใช้ feature เหล่านี้อยู่เดิมต้องตรวจสอบทีละตัวก่อนย้าย ไม่ใช่สมมติว่าเข้ากันได้ทั้งหมดเพราะชื่อ 'S3-compatible'

แนวทางที่ปลอดภัยกว่าคือทำ compatibility check list จาก feature ที่ระบบใช้งานจริงในปัจจุบัน แล้วทดสอบทีละตัวกับ R2 ก่อนวางแผนย้ายเต็มรูปแบบ แทนที่จะเชื่อคำว่า compatible แล้วย้ายทันทีทั้งระบบ

คำนวณค่า Egress จริงก่อนตัดสินใจย้าย

ก่อนตัดสินใจย้ายเพราะเห็นคำว่าไม่มีค่า Egress ควรคำนวณตัวเลขจริงของระบบตัวเองก่อน ตารางด้านล่างเป็นตัวอย่างกรอบคิดประกอบการตัดสินใจ ตัวเลขราคาจริงต้องตรวจจากหน้า pricing ล่าสุดของทั้งสองผู้ให้บริการเพราะเปลี่ยนแปลงได้ตามช่วงเวลา

ปัจจัยผลกระทบถ้า Egress สูงผลกระทบถ้า Egress ต่ำ
แอปที่ผู้ใช้ดาวน์โหลดไฟล์บ่อย เช่นวิดีโอสตรีมมิงย้ายมา R2 มักประหยัดชัดเจนในระยะยาวผลต่างอาจไม่มากพอจะคุ้มความเสี่ยงของการย้ายระบบ
แอปที่เก็บไฟล์เพื่อ backup อย่างเดียว แทบไม่ดาวน์โหลดออกค่า Egress เดิมของ S3 ก็ต่ำอยู่แล้วประโยชน์จาก R2 อยู่ที่ค่า storage มากกว่า Egress
ปริมาณ operation ต่อวินาทีสูงมาก แต่ไฟล์เล็กควรเทียบค่า operation คู่กับค่า Egress ที่ประหยัดได้อาจต้องคำนวณจุดคุ้มทุนให้ละเอียดกว่าดูแค่ Egress
ต้นทุนวิศวกรในการย้ายและทดสอบระบบควรนับเป็นต้นทุนจริงในการเปรียบเทียบถ้าระบบเล็กและย้ายง่าย ต้นทุนนี้อาจต่ำมาก

Consistency Model และพฤติกรรมหลังอัปโหลดไฟล์

R2 ให้ strong consistency สำหรับ operation พื้นฐานอย่างการอ่านไฟล์หลังเขียนเสร็จ (read-after-write) ภายใน region เดียวกัน หมายความว่าเมื่ออัปโหลดไฟล์เสร็จแล้ว การอ่านไฟล์นั้นทันทีควรเห็นข้อมูลล่าสุดโดยไม่ต้องรอ ต่างจากระบบ storage แบบกระจายบางตัวที่มี eventual consistency ซึ่งอาจเห็นข้อมูลเก่าอยู่ชั่วขณะหลังเขียนใหม่

อย่างไรก็ตาม เมื่อพูดถึงการเข้าถึงผ่าน CDN หรือ cache layer ที่วางไว้หน้า R2 พฤติกรรมจะต่างออกไป เพราะ cache มีอายุของตัวเองที่ต้องตั้งค่าแยก ทีมที่เห็นว่าไฟล์ที่เพิ่งอัปเดตยังแสดงผลเป็นเวอร์ชันเก่าผ่าน URL สาธารณะ ส่วนใหญ่ไม่ใช่ปัญหาของ R2 เอง แต่เป็นเรื่องของ cache-control header หรือ CDN cache ที่ต้อง invalidate ให้ถูกต้อง

ทีมที่ทำระบบอัปโหลดไฟล์ที่ผู้ใช้ต้องเห็นผลทันที เช่นระบบอัปโหลดรูปโปรไฟล์ ควรทดสอบ flow เต็มตั้งแต่อัปโหลดจนถึงแสดงผลบนหน้าเว็บจริง เพื่อยืนยันว่าไม่มี cache layer ใดในระบบที่ทำให้ผู้ใช้เห็นข้อมูลเก่าโดยไม่ตั้งใจ

จัดการสิทธิ์เข้าถึงและ Public Bucket อย่างปลอดภัย

R2 รองรับทั้ง bucket แบบ private ที่ต้องผ่านการยืนยันตัวตนก่อนเข้าถึง และแบบ public ที่เปิดให้เข้าถึงไฟล์ผ่าน URL ได้โดยตรง การตั้งค่าผิดพลาดระหว่างสองแบบนี้เป็นสาเหตุอันดับต้น ๆ ของข้อมูลรั่วไหลในระบบ object storage ทั่วไป ไม่ใช่เฉพาะ R2 เท่านั้น ทีมจึงควรตรวจสอบการตั้งค่า access control ทุกครั้งที่สร้าง bucket ใหม่

แนวทางที่ปลอดภัยกว่าคือเก็บไฟล์ที่มีข้อมูลอ่อนไหวไว้ใน private bucket แล้วสร้าง signed URL ที่มีอายุจำกัดสำหรับให้ผู้ใช้เข้าถึงเฉพาะเวลาที่จำเป็น แทนที่จะเปิด public bucket ตรง ๆ เพราะ signed URL ให้ทีมควบคุมได้ว่าใครเข้าถึงไฟล์ได้ในช่วงเวลาใด และสามารถ revoke สิทธิ์ได้เมื่อจำเป็น

สำหรับไฟล์ที่ต้องการให้เข้าถึงสาธารณะจริง เช่นรูปภาพสินค้าในเว็บอีคอมเมิร์ซ การตั้ง public bucket พร้อมผูกกับ custom domain และ cache-control header ที่เหมาะสมจะช่วยให้ทั้งประสิทธิภาพและการจัดการ URL ทำได้สะดวกกว่าการสร้าง signed URL ทุกครั้งที่มีคนเข้าดู

ย้ายข้อมูลจาก S3 มา R2 แบบไม่ให้บริการสะดุด

การย้าย object storage ที่มีระบบใช้งานจริงอยู่แล้วต้องวางแผนละเอียดกว่าการย้ายฐานข้อมูล เพราะไฟล์อาจมีจำนวนมากและมี URL ที่ผู้ใช้บันทึกไว้แล้วในหลายที่ ทำตามลำดับต่อไปนี้ช่วยลดความเสี่ยงที่บริการจะสะดุดระหว่างย้าย

  1. ทำ compatibility check list ของ feature S3 ที่ระบบใช้งานจริงในปัจจุบัน แล้วทดสอบทีละตัวกับ R2 ก่อนวางแผนย้ายเต็มรูปแบบ
  2. ตั้งระบบ sync ข้อมูลจาก S3 ไป R2 แบบต่อเนื่อง (ไม่ใช่ copy ครั้งเดียว) เพื่อให้ไฟล์ใหม่ที่เข้ามาระหว่างช่วงย้ายถูกซิงก์ไปด้วย
  3. เปลี่ยนโค้ดฝั่ง write ให้เขียนไฟล์ใหม่ไปที่ R2 โดยตรงก่อน ในขณะที่โค้ดฝั่ง read ยังอ่านจากทั้งสองแหล่งชั่วคราวเพื่อรองรับไฟล์เก่าที่ยังไม่ถูกย้าย
  4. เมื่อ sync ไฟล์เก่าทั้งหมดเสร็จสมบูรณ์แล้ว ค่อยสลับโค้ดฝั่ง read ให้อ่านจาก R2 เป็นหลัก แล้วเก็บ S3 ไว้เป็น fallback อีกช่วงเวลาหนึ่งก่อนปิดถาวร
  5. ตรวจสอบ URL ที่ผู้ใช้อาจบันทึกไว้ในระบบภายนอก เช่นอีเมลที่ส่งลิงก์ไฟล์ไปแล้ว แล้ววางแผน redirect หรือคงลิงก์เดิมให้ใช้งานได้ต่อเนื่องในช่วงเปลี่ยนผ่าน

งานแบบไหนที่ R2 เหมาะและไม่เหมาะ

R2 เหมาะกับงานที่มีการดาวน์โหลดไฟล์บ่อยและปริมาณมาก เช่นการเก็บไฟล์สื่อสำหรับเว็บไซต์ที่มีผู้เข้าชมสูง ระบบ CDN สำหรับไฟล์ static, การเก็บไฟล์ export ที่ผู้ใช้ดาวน์โหลดเป็นประจำ หรือระบบที่ใช้ Workers เป็น backend อยู่แล้วและต้องการให้ทั้ง compute กับ storage อยู่ใน ecosystem เดียวกัน

ในทางกลับกัน งานที่ต้องพึ่ง feature เฉพาะทางของ AWS ecosystem อย่างหนัก เช่นการ integrate กับ AWS Lambda โดยตรง, การใช้ S3 Select query ข้อมูลในไฟล์, หรือ compliance requirement ที่ระบุ AWS โดยเฉพาะ อาจยังไม่เหมาะกับการย้ายมา R2 ทั้งหมดในตอนนี้ ควรประเมิน feature ที่จำเป็นจริงก่อนตัดสินใจ

ทีมที่วางแผนใช้ R2 คู่กับ D1 หรือ Workers ควรอ่านเรื่อง การเลือกฐานข้อมูล SQL แบบ serverless ประกอบด้วย เพราะการวางสถาปัตยกรรมทั้ง storage และฐานข้อมูลให้อยู่ใน ecosystem เดียวกันมักให้ประโยชน์ด้าน latency และความง่ายในการดูแลระบบมากกว่าการผสมหลายผู้ให้บริการ

ทำแบบนี้แล้วพัง เพราะมองข้าม Feature ที่ S3 มีแต่ R2 ยังไม่มี

ทีมที่ย้ายระบบโดยเชื่อคำว่า S3-compatible แบบเต็มร้อยเปอร์เซ็นต์ มักเจอปัญหาตอน production เมื่อโค้ดที่เรียกใช้ feature เฉพาะทางบางตัวของ S3 ล้มเหลวแบบไม่คาดคิด เพราะ SDK อาจไม่ throw error ชัดเจนว่า feature นั้นไม่รองรับ แต่กลับคืนค่าผิดพลาดที่ debug ยาก

อีกอาการที่พบคือทีมลืมตรวจสอบ lifecycle policy เดิมที่ตั้งไว้ใน S3 เช่นการย้ายไฟล์เก่าไป storage tier ราคาถูกกว่าโดยอัตโนมัติหลังผ่านไปกี่วัน ถ้า R2 ยังไม่รองรับ policy แบบเดียวกัน ทีมต้องคิดหาวิธีจัดการวงจรชีวิตของไฟล์เองแทน ไม่ใช่คาดหวังว่าระบบจะทำงานเหมือนเดิมทุกอย่างหลังย้าย

อาการที่สามที่ร้ายแรงกว่าคือการย้าย public bucket โดยไม่ตรวจสอบ access control ให้ตรงกับของเดิม ทำให้ไฟล์ที่เคย private กลายเป็น public โดยไม่ตั้งใจ หรือกลับกันคือไฟล์ที่เคย public กลับเข้าถึงไม่ได้จนกระทบผู้ใช้จริง จึงควรทำรายการตรวจสอบเปรียบเทียบ permission ของทุก bucket ก่อนสลับ traffic จริงไปที่ R2 เสมอ

สรุป

การไม่มีค่า Egress ของ R2 เป็นจุดขายที่น่าสนใจจริง แต่ไม่ควรเป็นเหตุผลเดียวในการตัดสินใจย้ายระบบทั้งหมด ทีมควรคำนวณต้นทุนรวมทั้งค่า storage ค่า operation และต้นทุนวิศวกรในการย้ายระบบ เทียบกับความคุ้มค่าที่จะได้รับจริงในระยะยาว

สิ่งที่สำคัญไม่แพ้ตัวเลขค่าใช้จ่ายคือการตรวจสอบว่า feature ที่ระบบใช้งานอยู่เดิมรองรับใน R2 ครบหรือไม่ โดยเฉพาะ lifecycle policy และ feature เฉพาะทางของ AWS ที่อาจยังไม่มีในตอนนี้ การทำ compatibility check list ก่อนย้ายช่วยลดความเสี่ยงที่จะเจอปัญหาหลังขึ้น production ได้มาก

  • R2 ไม่คิดค่า Egress แต่ยังคิดค่า storage และ operation ตามการใช้งานจริง
  • S3-compatible API ใช้ได้กับคำสั่งพื้นฐาน แต่ feature ขั้นสูงบางตัวอาจยังไม่รองรับครบ
  • read-after-write consistency แข็งแรง แต่ cache layer หน้า R2 ยังต้องจัดการแยกต่างหาก
  • ควรใช้ private bucket กับ signed URL สำหรับไฟล์อ่อนไหว แทนการเปิด public bucket ตรง ๆ
  • วางแผนย้ายแบบ sync คู่ขนานก่อนสลับ traffic แทนการย้ายครั้งเดียวทั้งระบบ

คำถามที่พบบ่อย

R2 คิดค่าใช้จ่ายจากอะไรบ้างถ้าไม่มีค่า Egress

คิดจากพื้นที่จัดเก็บ (storage) ตามปริมาณข้อมูลที่เก็บไว้ และค่า operation อย่างการอ่าน เขียน หรือ list object ตามจำนวนครั้งที่เรียกใช้งานจริง ทีมควรประเมินทั้งสองส่วนนี้ ไม่ใช่ดูแค่ว่าไม่มีค่า Egress แล้วสรุปว่าประหยัดกว่าเสมอ

ย้ายจาก S3 มา R2 ต้องเขียนโค้ดใหม่ทั้งหมดไหม

ส่วนใหญ่ไม่ต้อง เพราะ R2 ใช้ S3-compatible API ที่ SDK เดิมส่วนมากทำงานได้โดยเปลี่ยนแค่ endpoint แต่ควรตรวจ feature เฉพาะทางที่ระบบใช้อยู่เดิมก่อน เพราะบางส่วนอาจยังไม่รองรับครบและต้องแก้โค้ดเฉพาะจุด

R2 รองรับ lifecycle policy แบบย้าย storage tier อัตโนมัติเหมือน S3 ไหม

ความสามารถด้านนี้อาจแตกต่างจาก S3 ในรายละเอียด ควรตรวจสอบเอกสารล่าสุดของ R2 ก่อนวางแผน หากยังไม่รองรับ policy แบบเดียวกัน ทีมอาจต้องเขียน job แยกจัดการวงจรชีวิตของไฟล์เอง

ทำไฟล์ที่เพิ่งอัปโหลดหายไปจากหน้าเว็บชั่วคราวเกิดจากอะไร

ส่วนใหญ่ไม่ใช่ปัญหา consistency ของ R2 เอง แต่เกิดจาก cache layer หรือ CDN ที่วางอยู่หน้า R2 มีอายุ cache ที่ยังไม่หมด ควรตรวจสอบ cache-control header และวิธี invalidate cache ของระบบก่อนสรุปว่าเป็นปัญหาของ storage

ควรใช้ public bucket หรือ signed URL สำหรับไฟล์ที่มีข้อมูลอ่อนไหว

ควรใช้ private bucket ร่วมกับ signed URL ที่มีอายุจำกัดเสมอสำหรับไฟล์ที่มีข้อมูลอ่อนไหว เพราะให้ทีมควบคุมได้ว่าใครเข้าถึงได้ในช่วงเวลาใด และสามารถ revoke สิทธิ์ได้เมื่อจำเป็น ต่างจาก public bucket ที่เปิดให้ทุกคนเข้าถึงตราบใดที่รู้ URL

ย้ายระบบตอนไหนถึงจะปลอดภัยที่สุด ต้องปิดบริการชั่วคราวไหม

ไม่จำเป็นต้องปิดบริการถ้าวางแผนแบบ sync ต่อเนื่องคู่ขนานไปกับระบบเดิม แล้วค่อยสลับ traffic ทีละส่วนหลังยืนยันว่าไฟล์ทั้งหมดถูกย้ายครบและ permission ตรงกับของเดิมแล้ว วิธีนี้ใช้เวลานานกว่าการสลับทันทีแต่ลดความเสี่ยงที่ผู้ใช้จะเจอปัญหา

วัด Conversion LINE ทุกแบรนด์ รวมศูนย์ที่เดียว

องค์กรที่มีหลายแบรนด์ หลายสาขา หลาย LINE OA — linli รวม Tracking และส่ง Conversion กลับทุกแพลตฟอร์ม พร้อม Custom Limit เริ่มฟรี 14 วัน

ติดต่อทีม Sales

บทความที่เกี่ยวข้อง

เขียน query เดิมทุกอย่าง แต่ทำไม Workers ต่อ Postgres ถึงช้าเป็นวินาที

เขียน query เดิมทุกอย่าง แต่ทำไม Workers ต่อ Postgres ถึงช้าเป็นวินาที

Worker ที่รันใกล้ผู้ใช้แต่ยังต้องเปิดการเชื่อมต่อใหม่ไปหา Postgres ที่อยู่ไกลทุกครั้ง ทำให้ query เดิมที่เคยเร็วบน server กลายเป็นช้าเป็นวินาที Hyperdrive แก้ปัญหานี้ด้วยการ pool connection และแคชเส้นทางให้แทน
ทีมขนาดไหนควรแยก Agent เฉพาะทาง และทีมไหนยังไม่จำเป็นต้องลงทุน

ทีมขนาดไหนควรแยก Agent เฉพาะทาง และทีมไหนยังไม่จำเป็นต้องลงทุน

หลายทีมได้ยินเรื่อง Custom Agent สำหรับ Frontend, Backend หรือ Security แล้วรีบสร้างตามทันที ทั้งที่ยังไม่แน่ใจว่าทีมตัวเองจำเป็นแค่ไหน บทความนี้อธิบายว่า GitHub Copilot Custom Agents คืออะไร สร้างยังไง และเงื่อนไขแบบไหนที่บอกว่าถึงเวลาต้องแยกจริง ๆ หรือยังไม่ต้องรีบ
จะให้ Copilot ไปอ่านข้อมูลจาก Jira หรือ Database ได้อย่างไรโดยไม่ต้อง Copy มาวางเอง

จะให้ Copilot ไปอ่านข้อมูลจาก Jira หรือ Database ได้อย่างไรโดยไม่ต้อง Copy มาวางเอง

Agent เขียนโค้ดเก่ง แต่พอถามเรื่องที่อยู่นอกโค้ด เช่นสถานะ Ticket ใน Jira หรือข้อมูลจริงใน Database มันตอบไม่ได้ บทความนี้อธิบายว่า MCP คืออะไร และทำให้ GitHub Copilot ต่อกับข้อมูลภายนอกได้อย่างไรโดยไม่ต้อง Copy-paste เอง