แอปพลิเคชันออนไลน์ขนาดใหญ่มีมานานแล้วในช่วงสองทศวรรษที่ผ่านมา นวัตกรรมเหล่านี้ได้เปลี่ยนการรับรู้ของเราในการพัฒนาซอฟต์แวร์ ตัวอย่างเช่น Facebook, Instagram และ Twitter เป็นแพลตฟอร์มที่ปรับขนาดได้ทั้งหมด
ระบบเหล่านี้ต้องสร้างขึ้นเพื่อจัดการปริมาณการใช้งานและข้อมูลจำนวนมหาศาล เนื่องจากผู้คนหลายพันล้านคนใช้งานพร้อมกันทั่วโลก นี่คือเมื่อ การออกแบบระบบ เข้าสู่ภาพ
กระบวนการสร้างสถาปัตยกรรม อินเทอร์เฟซ และข้อมูลสำหรับระบบที่ตรงตามเกณฑ์บางอย่างเรียกว่าการออกแบบระบบ การออกแบบระบบที่ตอบสนองความต้องการของธุรกิจหรือองค์กรของคุณผ่านระบบที่เหนียวแน่นและมีประสิทธิภาพ
เมื่อบริษัทหรือองค์กรของคุณกำหนดเกณฑ์แล้ว คุณสามารถเริ่มรวมเข้ากับการออกแบบระบบจริงที่ตรงกับความต้องการของผู้บริโภคของคุณ
ไม่ว่าคุณจะเลือกการพัฒนาตามสั่ง โซลูชันเชิงพาณิชย์ หรือทั้งสองอย่างรวมกัน วิธีการออกแบบระบบของคุณจะกำหนดวิธีสร้างระบบของคุณ
เราจะดูรายละเอียดเกี่ยวกับการออกแบบระบบของไทม์ไลน์ของ Twitter ในโพสต์นี้ พร้อมด้วยบทช่วยสอน มาเริ่มกันเลย.
ขั้นตอนที่ 1: สรุปกรณีการใช้งานและข้อจำกัด
ใช้กรณี
- ผู้ใช้อัปโหลดทวีต
- บริการส่งการแจ้งเตือนแบบพุชและอีเมลไปยังผู้ติดตามทวีต
- มีการดูไทม์ไลน์ของผู้ใช้ (กิจกรรมจากผู้ใช้)
- ผู้ใช้ดูไทม์ไลน์ที่บ้าน (กิจกรรมจากบุคคลที่ผู้ใช้ติดตาม)
- คีย์เวิร์ดถูกค้นหาโดยผู้ใช้
- บริการสามารถเข้าถึงได้จริงๆ
ออกจากขอบเขต
- ทวีตจะถูกส่งไปยัง Twitter Firehose และสตรีมอื่นๆ โดยใช้บริการนี้
- บริการจะลบทวีตตามการตั้งค่าการมองเห็นของผู้ใช้
- หากผู้ใช้ไม่ได้ติดตามบุคคลที่ได้รับการตอบกลับด้วย ให้ซ่อนการตอบกลับ
- สังเกตตัวเลือก 'ซ่อนรีทวีต'
- บทวิเคราะห์
ข้อจำกัดและสมมติฐาน
สมมติฐานของรัฐ
- การสัญจรไม่กระจัดกระจาย
- การส่งทวีตควรเป็นเรื่องง่าย
- หากคุณไม่มีผู้ติดตามหลายล้านคน การส่งทวีตถึงผู้ติดตามทุกคนควรรวดเร็ว
- มีผู้ใช้งาน 100 ล้านคน
- 15 พันล้านทวีตต่อเดือนหรือ 500 ล้านทวีตทุกวัน
- ทวีตแต่ละรายการมีการส่งโดยเฉลี่ย 10 รายการ
- ทุกๆ วัน fanout ส่งทวีตถึง 5 พันล้านทวีต
- Fanout ส่ง 150 พันล้านทวีตทุกเดือน
- คำขออ่านเดือนละ 250 พันล้านครั้ง
- การค้นหา 10 พันล้านครั้งต่อเดือน
ปฏิบัติการ
- ไทม์ไลน์ควรใช้งานง่าย
- Twitter เป็นมากกว่าการอ่านมากกว่าการเขียน
- ปรับให้เหมาะสมสำหรับการอ่านทวีตอย่างรวดเร็ว
- การบริโภคทวีตนั้นใช้เวลานาน
ค้นหา
- ขั้นตอนการค้นหาควรรวดเร็ว
- ใช้เวลานานในการค้นหา
คำนวณการใช้งาน
ขนาดทวีตแต่ละอัน:
- 8 ไบต์ทวีต id
- รหัสผู้ใช้ 32 ไบต์
- ข้อความ 140 ไบต์
- สื่อ – เฉลี่ย 10 KB
- รวม: ~10 KB
ทุกเดือนจะมีการสร้างเนื้อหาทวีตใหม่ 150 TB
- * 500 ล้านทวีตทุกวัน * 30 วันต่อเดือน * 10 KB ต่อทวีต
- ในสามปีมีเนื้อหาทวีตใหม่ 5.4 PB
มีคำขออ่าน 100,000 รายการต่อวินาที
- * (400 คำขอต่อวินาที / 1 พันล้านคำขอต่อเดือน) 250 พันล้านคำขออ่านในแต่ละเดือน
มี 6,000 ทวีตต่อวินาที
- * (400 คำขอต่อวินาที / 1 พันล้านคำขอต่อเดือน) 15 พันล้านทวีตทุกเดือน
ใน fanout จะมีการส่งทวีต 60 ทุกวินาที
- Fanout ส่ง 150 พันล้านทวีตในแต่ละเดือน* (400 คำขอต่อวินาที / 1 พันล้านคำขอต่อเดือน)
4,000 คำขอข้อมูลทุกวินาที
- * (400 คำขอต่อวินาที / 1 พันล้านคำขอต่อเดือน) 10 พันล้านคำค้นหาในแต่ละเดือน
การแปลงที่มีประโยชน์บางอย่าง
- ทุกเดือน 2.5 ล้านวินาทีผ่านไป
- 2.5 ล้านคำขอต่อเดือนที่ 1 คำขอต่อวินาที
- 100 ล้านคำขอต่อเดือน x 40 คำขอต่อวินาที
- 1 พันล้านคำขอต่อเดือน = 400 คำขอต่อวินาที
ขั้นตอนที่ 2: ไดอะแกรมระดับสูง
ขั้นตอนที่ 3: อธิบายส่วนประกอบหลัก
เราสามารถบันทึกทวีตของผู้ใช้เองเพื่อเติมไทม์ไลน์ของผู้ใช้ (กิจกรรมจากผู้ใช้) ในฐานข้อมูลเชิงสัมพันธ์หากพวกเขาส่งทวีต การส่งทวีตและพัฒนาไทม์ไลน์ที่บ้านยากกว่า (กิจกรรมจากบุคคลที่ผู้ใช้ติดตาม)
ฐานข้อมูลเชิงสัมพันธ์ทั่วไปจะถูกครอบงำโดยการส่งทวีตไปยังผู้ติดตามทั้งหมด (ส่งทวีต 60 รายการในแต่ละวินาที) เราอาจต้องการใช้พื้นที่จัดเก็บข้อมูลแบบเขียนเร็ว เช่น ฐานข้อมูล NoSQL หรือ Memory Cache
การอ่าน 1 MB ตามลำดับจากหน่วยความจำใช้เวลาประมาณ 250 ไมโครวินาที แต่การอ่านจาก SSD ใช้เวลานานกว่า 4 เท่า และการอ่านจากดิสก์ใช้เวลานานกว่า 80 เท่า
สามารถใช้ Object Store เพื่อจัดเก็บข้อมูล เช่น รูปภาพและวิดีโอ
- เว็บเซิร์ฟเวอร์ซึ่งทำหน้าที่เป็น reverse proxy ได้รับทวีตจากลูกค้า
- คำขอจะถูกส่งไปยังเซิร์ฟเวอร์ Write API โดยเว็บเซิร์ฟเวอร์
- Write API บันทึกทวีตไปยังฐานข้อมูล SQL ในไทม์ไลน์ของผู้ใช้
บริการ Fan-Out ได้รับการติดต่อจาก Write API และดำเนินการดังต่อไปนี้
- ค้นหาผู้ติดตามของผู้ใช้ในแคชหน่วยความจำโดยการสอบถามบริการกราฟผู้ใช้
- ในแคชหน่วยความจำ ทวีตจะถูกบันทึกไว้ในไทม์ไลน์หลักของผู้ติดตามของผู้ใช้
- ผู้ติดตาม 1,000 คน = การค้นหาและแทรก 1,000 รายการ = การดำเนินการ O(n)
- ทวีตจะถูกบันทึกไว้ใน Search Index Service เพื่อการค้นหาอย่างรวดเร็ว
- Object Store ใช้สำหรับจัดเก็บสื่อ
- ส่งการแจ้งเตือนแบบพุชไปยังผู้ติดตามผ่านบริการแจ้งเตือน
- หากต้องการส่งการแจ้งเตือนแบบอะซิงโครนัส จะใช้คิว
เราสามารถใช้รายการ Redis ดั้งเดิมที่มีโครงสร้างต่อไปนี้หากแคชหน่วยความจำของเราคือ Redis:
ไทม์ไลน์หลักของผู้ใช้จะได้รับการอัปเดตด้วยทวีตใหม่ ซึ่งจะถูกเก็บไว้ใน Memory Cache เราจะใช้ REST API สาธารณะต่อไปนี้:
ผู้ใช้ดูไทม์ไลน์ของผู้ใช้
- เว็บเซิร์ฟเวอร์ได้รับคำขอไทม์ไลน์ของผู้ใช้จากลูกค้า
- คำขอจะถูกส่งไปยังเซิร์ฟเวอร์ Read API โดยเว็บเซิร์ฟเวอร์
- Read API สืบค้นฐานข้อมูล SQL สำหรับกรอบเวลาของผู้ใช้
REST API จะทำงานคล้ายกับไทม์ไลน์หลัก ยกเว้นว่าทวีตทั้งหมดจะมาจากผู้ใช้มากกว่าคนที่พวกเขาติดตาม
ผู้ใช้ค้นหาคำสำคัญ:
- เว็บเซิร์ฟเวอร์ได้รับคำขอค้นหาจากลูกค้า
- คำขอถูกส่งไปยังเซิร์ฟเวอร์ Search API โดยเว็บเซิร์ฟเวอร์
ขั้นตอนที่ 4: ไทม์ไลน์ของ Twitter
การสร้างไทม์ไลน์เป็นงานที่ยาก จำเป็นต้องมีเซิร์ฟเวอร์สร้างไทม์ไลน์ที่เชื่อมโยงไปยังเว็บหรือเซิร์ฟเวอร์แอปพลิเคชัน
ทุกครั้งที่ผู้ใช้ลงชื่อเข้าใช้ บริการไทม์ไลน์จะติดตามทวีตใหม่ล่าสุดจากผู้ใช้ในตารางของผู้ติดตามและอัปเดตหรือรีเฟรชไทม์ไลน์ของผู้ใช้
เราไม่ได้ใช้ระบบการจัดอันดับใด ๆ ที่นี่ แต่เราคิดว่าทวีต 5 อันดับแรกจากผู้ติดตามของผู้ใช้จะแสดงในไทม์ไลน์ตามลำดับเวลาที่สร้าง เราสามารถรักษาการรีเฟรช 50 ทวีตได้ เรายังคงหยุดรีเฟรชหรือสร้างไทม์ไลน์หลังจากถึงเกณฑ์นั้น จนกว่าผู้ใช้จะรีเฟรชหน้า
ความกังวลเรื่องเวลาแฝงและประสิทธิภาพที่สูงจะมาจากการสร้างฟีดผู้ใช้แบบสด การสร้างสตรีมแบบออฟไลน์ที่สามารถนำเสนอได้ทันทีเป็นวิธีที่ดีที่สุดในการปรับปรุงประสิทธิภาพแทน เรียกใช้เซิร์ฟเวอร์ไทม์ไลน์เฉพาะที่ ping แอปพลิเคชันเซิร์ฟเวอร์เป็นประจำเพื่อรีเฟรชฟีดตามเวลาที่สร้างขึ้น
อัลกอริทึมการจัดอันดับควรคำนึงถึงสัญญาณที่สำคัญและให้น้ำหนักเพื่อรับประกันว่าไทม์ไลน์ของผู้ใช้จะไม่ถูกครอบงำด้วยเนื้อหาจากบัญชีอย่างน้อยหนึ่งบัญชีที่พวกเขาติดตาม
แม่นยำยิ่งขึ้น เราสามารถเลือกคุณสมบัติที่เกี่ยวข้องกับความเกี่ยวข้องของรายการฟีดใดๆ เช่น จำนวนการชอบ ความคิดเห็น การแชร์ และเวลาอัปเดต ควรใช้เกณฑ์แต่ละข้อเหล่านี้ในการให้คะแนนทวีต จากนั้นจึงควรใช้อันดับนั้นเพื่อแสดงทวีตบนไทม์ไลน์
เราควรแจ้งเตือนผู้ใช้อย่างต่อเนื่องเมื่อมีเนื้อหาใหม่สำหรับฟีดข่าวของพวกเขาหรือไม่ ผู้ใช้จะพบว่ามีประโยชน์ที่จะได้รับการแจ้งเตือนเมื่อมีข้อมูลใหม่ อย่างไรก็ตาม สำหรับอุปกรณ์พกพา เมื่อการใช้ข้อมูลค่อนข้างแพง ก็อาจทำให้แบนด์วิดท์เสียเปล่า
ด้วยเหตุนี้ เราจึงสามารถเลือกที่จะไม่ส่งข้อมูลไปยังอุปกรณ์เคลื่อนที่ และอนุญาตให้ผู้ใช้ "ดึงเพื่อรีเฟรช" สำหรับการโพสต์ใหม่แทน
ขั้นตอนที่ 5: การออกแบบมาตราส่วน
ปัญหาคอขวดที่อาจเกิดขึ้นคือบริการ Fanout ผู้ใช้ Twitter ที่มีผู้ติดตามหลายล้านคนจะต้องรอหลายนาทีกว่าที่ทวีตจะเผยแพร่ ซึ่งอาจทำให้เกิดการแข่งขันที่มีการตอบกลับทวีต ซึ่งเราสามารถหลีกเลี่ยงได้โดยการจัดลำดับทวีตใหม่ในช่วงเวลาให้บริการ
นอกจากนี้เรายังสามารถป้องกันการแพร่กระจายทวีตจากผู้ที่มีผู้ติดตามจำนวนมาก เราอาจทำการค้นหาทวีตจากบุคคลที่ติดตามอย่างสูง ผสานผลการค้นหากับผลลัพธ์ไทม์ไลน์ที่บ้านของผู้ใช้ แล้วจึงจัดลำดับทวีตใหม่ในเวลาที่ให้บริการ
การปรับปรุงเพิ่มเติม ได้แก่ :
- เก็บทวีตเพียงไม่กี่ร้อยรายการใน Memory Cache สำหรับแต่ละไทม์ไลน์ที่บ้าน
- ในแคชหน่วยความจำ จะบันทึกเฉพาะข้อมูลไทม์ไลน์ที่บ้านของผู้ใช้ที่ใช้งานอยู่
- เราสามารถสร้างลำดับเหตุการณ์ใหม่ได้จากฐานข้อมูล SQL หากผู้ใช้ไม่ได้ใช้งานในช่วง 30 วันก่อนหน้า
- หากต้องการทราบว่าผู้ใช้เป็นใคร ให้ใช้บริการกราฟผู้ใช้
- เพิ่มทวีตไปยังแคชหน่วยความจำโดยดึงข้อมูลจากฐานข้อมูล SQL
- บริการข้อมูลทวีตสามารถบันทึกทวีตได้เพียงหนึ่งเดือนเท่านั้น
- ใน User Info Service จะบันทึกเฉพาะผู้ใช้ที่ใช้งานอยู่เท่านั้น
- เพื่อให้มีเวลาแฝงต่ำ Search Cluster มักจะต้องรักษาทวีตไว้ในหน่วยความจำ
สรุป
แม้ว่า Twitter จะเป็นองค์กรขนาดใหญ่ แต่ก็มีข้อดีมากกว่า ความเข้าใจในการออกแบบระบบ. ฉันพยายามอย่างเต็มที่เพื่อให้คุณเห็นภาพรวมระดับสูงของไทม์ไลน์ของ Twitter
ฉันหวังว่าคุณจะได้รับข้อมูลที่เป็นประโยชน์จากมันและนำไปใช้ให้เกิดประโยชน์
เขียนความเห็น