1 คะแนน โดย GN⁺ 2024-07-28 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ติ๊ก 650,000,000 ช่องทำเครื่องหมาย: รับมือกับความนิยมที่เกินคาด

วันที่ 26 มิถุนายน 2024 ได้เปิดตัวเว็บไซต์ One Million Checkboxes (OMCB)
  • เว็บไซต์ที่มีช่องทำเครื่องหมายแบบโกลบอล 1 ล้านช่อง โดยเมื่อมีการติ๊กช่องใด การเปลี่ยนแปลงจะสะท้อนให้ผู้ใช้ทุกคนเห็นทันที
  • หลังเปิดตัวเพียง 30 นาที มีผู้ใช้หลายพันคนช่วยกันติ๊กช่องทำเครื่องหมายไปแล้วหลายล้านครั้ง
  • มีผู้ใช้ไหลเข้ามาจาก Hacker News, /r/InternetIsBeautiful, Mastodon, Twitter และที่อื่น ๆ
  • ถูกนำเสนอใน Washington Post และ New York Times ด้วย
  • วันแรกมีการติ๊กช่องทำเครื่องหมายมากกว่า 50 ล้านครั้ง
  • ก่อนปิดเว็บไซต์ในอีก 2 สัปดาห์ถัดมา มีการติ๊กช่องทำเครื่องหมายรวมมากกว่า 650 ล้านครั้ง

สถาปัตยกรรมเดิม

  • สถานะของช่องทำเครื่องหมายถูกเก็บเป็น 1 ล้านบิต (125KB)
  • ฝั่งไคลเอนต์ใช้บิตเซ็ตเพื่อเรนเดอร์ช่องทำเครื่องหมาย และแจ้งสถานะการติ๊กไปยังเซิร์ฟเวอร์
  • เซิร์ฟเวอร์ใช้ Redis อัปเดตบิตและบรอดแคสต์ไปยังไคลเอนต์ทั้งหมด
  • ให้บริการคอนเทนต์แบบสแตติกผ่าน nginx และใช้เซิร์ฟเวอร์ Flask สำหรับจัดการสถานะบิตเซ็ตและการเชื่อมต่อ WebSocket
  • Redis ทำหน้าที่ทั้งเก็บสถานะและเป็นคิวข้อความ

หลักการในการขยายระบบ

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

วันแรก: ความนิยมระเบิดขึ้นอย่างรวดเร็ว

  • ภายใน 30 นาที ภาระบนเซิร์ฟเวอร์พุ่งสูงมาก
  • สปินอัปเซิร์ฟเวอร์เพิ่มเพื่อกระจายโหลด
  • นำการอัปเดตแบบแบตช์มาใช้เพื่อแก้ปัญหาการเชื่อมต่อ Redis
  • อัปเกรดอินสแตนซ์ Redis แบบจัดการให้ของ Digital Ocean

ไม่มีแผนสำหรับทั้งคืน

  • วางแผนระหว่างไปออกบูธเกม Pacman จดจำใบหน้าที่แคมป์ ITP
  • พก iPad ไปด้วยเพื่อสปินอัปเซิร์ฟเวอร์
  • พัฒนากติกาการตั้งชื่อเซิร์ฟเวอร์ไปพร้อมกับรัน worker VM จำนวน 8 เครื่อง
  • ลดจำนวนโปรเซส Flask และเพิ่มขนาดแบตช์ของการอัปเดตเพื่อลดโหลด

ปัญหาแบนด์วิดท์

  • ไม่ได้คำนึงถึงราคาค่าแบนด์วิดท์ของ Digital Ocean
  • ลดความถี่ของสแนปช็อตสถานะ และลดขนาดของข้อมูลอัปเดต
  • ใช้ยูทิลิตี tc เพื่อจำกัดปริมาณข้อมูลที่ส่งต่อวินาที

วันที่สอง: ยังเติบโตต่อเนื่อง

  • เว็บไซต์ล่มเพราะทำ input validation ไม่รัดกุมพอ
  • เพิ่ม Redis replica เพื่อช่วยกระจายโหลด
  • โปรเซส Flask ล่มต่อเนื่องจนต้องเขียนสคริปต์รีสตาร์ตอัตโนมัติ

ปัญหาอัปเดตเก่า

  • เกิดปัญหาที่ไคลเอนต์นำอัปเดตเก่ามาใช้ ทำให้แสดงสถานะผิด
  • เพิ่ม timestamp เพื่อรับประกันลำดับของอัปเดต

เขียนใหม่ด้วย Go

  • ร่วมกับเพื่อนที่เป็นวิศวกรประสิทธิภาพ เขียนแบ็กเอนด์ใหม่ด้วย Go
  • ประสิทธิภาพดีขึ้นอย่างมาก
  • ป้องกันการโจมตี DDOS ผ่าน CloudFlare

การปิดเว็บไซต์

  • เปลี่ยนให้ช่องทำเครื่องหมายเข้าสู่สถานะแช่แข็งหากไม่มีการยกเลิกการติ๊กอย่างรวดเร็วพอ
  • ใช้ Redis จัดการสถานะแช่แข็ง
  • ปิดเว็บไซต์หลังจากนั้น 2 สัปดาห์

สิ่งที่ได้เรียนรู้

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

สรุปโดย GN⁺

  • บทความนี้เล่าถึงปัญหาทางเทคนิคและกระบวนการแก้ไขที่เกิดจากความนิยมเกินคาดของเว็บไซต์
  • แสดงให้เห็นว่าแม้ใช้สถาปัตยกรรมเรียบง่ายที่อาศัย Redis และ nginx ก็ยังรองรับทราฟฟิกขนาดใหญ่ได้
  • อธิบายวิธีแก้ปัญหาและทำให้เว็บไซต์เสถียรได้อย่างรวดเร็วด้วยแนวทางระยะสั้น
  • ครอบคลุมความท้าทายทางเทคนิคหลายด้าน เช่น การเขียนใหม่ด้วย Go และการป้องกัน DDOS ผ่าน CloudFlare
  • โครงการที่มีลักษณะคล้ายกันมี เช่น /r/Place ของ Reddit ซึ่งเป็นโปรเจกต์ความร่วมมือขนาดใหญ่

1 ความคิดเห็น

 
GN⁺ 2024-07-28
ความคิดเห็นบน Hacker News
  • ได้เรียนรู้บทเรียนและเกร็ดประวัติศาสตร์มากมาย

    • ครอบคลุมการสะดุดและจุดล้มเหลวสารพัดแบบ แต่ไม่ได้พูดถึงปัญหาเรื่องพื้นที่จัดเก็บ
    • ไม่เคยรู้มาก่อนว่า Redis ใช้ Lua ได้ และทำให้สนใจจะใช้มันเป็น state store สำรอง
    • ปัญหาแบนด์วิดท์ของบริการคลาวด์เป็นหนึ่งในเรื่องที่น่าหงุดหงิดที่สุด เพราะไม่มี hard limit สำหรับกันไม่ให้ค่าใช้จ่ายบานปลาย
  • เป็นบทความที่ยอดเยี่ยมมาก! ขอแสดงความยินดีกับเว็บไซต์ด้วย แต่ตัวบทความเองคือส่วนที่ควรภูมิใจที่สุด

  • การสร้างเว็บนี้ภายในสองวันเป็นการตัดสินใจที่ดี

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

    • "One Million Checkboxes" - ลิงก์ - มิถุนายน 2024 (305 ความคิดเห็น)
  • เป็นโปรเจกต์ที่น่าสนุก

    • เมื่อ 6 ปีก่อน ฉันเปิดตัวแอปแก้ไขพิกเซลแบบร่วมมือกันชื่อ Pixmap บน Android
    • ใช้คิวเพื่อนำแต่ละอีเวนต์ไปปรับกับภาพ PNG และไคลเอนต์จะโหลด PNG ตั้งต้นเมื่อเชื่อมต่อ
    • อีเวนต์การวาดพิกเซลแต่ละครั้งจะถูกส่งไปยังไคลเอนต์เป็นออบเจ็กต์ขนาดเล็ก
    • ตอนโหลดครั้งแรกก็อาศัยการบีบอัดภาพ และชุดการเปลี่ยนแปลงก็มีขนาดเล็กมาก
    • เพราะแต่ละอีเวนต์ถูกเก็บไว้ในล็อก จึงสามารถ "กรอกลับ" ภาพได้
    • ลิงก์เดโม
  • เป็นบทความที่ยอดเยี่ยมมาก — อยากรู้ว่ามีค่าใช้จ่ายเท่าไร

  • ยิ่งทำให้เชื่อว่าผู้คนโหยหาปฏิสัมพันธ์แบบนิรนามที่มีข้อจำกัด

  • ในฐานะมือใหม่ด้านแบ็กเอนด์ ฉันสงสัยว่ามีสถาปัตยกรรมทางเลือกที่เรียบง่ายกว่านี้สำหรับโปรเจกต์นี้ไหม

    • อยากให้มีวิธีที่ง่ายกว่าสำหรับโฮสต์สถานะหนึ่งล้านรายการและซิงก์กับไคลเอนต์
    • โซลูชันบางส่วนในบทความเข้าใจได้ยาก
    • ขอชื่นชมผู้เขียน — โปรเจกต์นี้ยอดเยี่ยมมาก
  • เจ๋งมาก!

    • สงสัยว่าบทความถัดไปจะเป็นการวิเคราะห์สถิติของเช็กบ็อกซ์หรือเปล่า
    • จำได้ว่ารู้สึกเศร้าเพราะเช็กบ็อกซ์ที่ฉันเลือกถูกเอาเครื่องหมายออกแทบจะทันที
  • สงสัยว่าเกมนี้ยังออนไลน์อยู่ไหม

    • ตอนเข้าไปที่ One Million Checkboxes ไม่มีอะไรถูกติ๊กไว้เลย และใน JS console มีเพียงข้อความต่อไปนี้
    • {"total":0,"totalGold":0,"totalRed":0,"totalGreen":0,"totalPurple":0,"totalOrange":0,"recentlyChecked":false}