คำตอบสั้น ๆ คือมีเพียงข้อมูลใหม่เท่านั้นที่ถูกส่งไปตามสาย นี่คือวิธีการทำงาน
มีสามส่วนที่สำคัญของเซิร์ฟเวอร์ Meteor ที่จัดการการสมัครสมาชิก ได้แก่ฟังก์ชันการเผยแพร่ซึ่งกำหนดตรรกะของข้อมูลที่การสมัครสมาชิกให้ ไดรเวอร์ Mongoซึ่งนาฬิกาฐานข้อมูลสำหรับการเปลี่ยนแปลง และกล่องผสานซึ่งรวมการสมัครสมาชิกที่ใช้งานอยู่ทั้งหมดของลูกค้าและส่งออกไปทางเครือข่ายไปยังไคลเอนต์
เผยแพร่ฟังก์ชัน
ทุกครั้งที่ลูกค้าดาวตกสมัครคอลเลกชันเซิร์ฟเวอร์ทำงาน
ฟังก์ชั่นเผยแพร่ งานของฟังก์ชันการเผยแพร่คือการหาชุดเอกสารที่ไคลเอ็นต์ควรมีและส่งคุณสมบัติเอกสารแต่ละรายการลงในกล่องผสาน จะทำงานหนึ่งครั้งสำหรับลูกค้าที่สมัครใหม่แต่ละราย คุณสามารถใส่ JavaScript ที่คุณต้องการในฟังก์ชันการเผยแพร่เช่นการควบคุมการเข้าถึงที่ซับซ้อนโดยพลการโดยใช้this.userId
. ฟังก์ชั่นการเผยแพร่ส่งข้อมูลลงในช่องผสานโดยการโทรthis.added
, และthis.changed
this.removed
ดู
เอกสารเผยแพร่ฉบับเต็มสำหรับรายละเอียดเพิ่มเติม
ฟังก์ชั่นเผยแพร่ส่วนใหญ่ไม่ได้โคลนรอบกับระดับต่ำ
added
, changed
และremoved
API แม้ว่า หากมีการเผยแพร่ผลตอบแทนการทำงานของเคอร์เซอร์ Mongo เซิร์ฟเวอร์ดาวตกจะเชื่อมต่อการส่งออกของไดรเวอร์ Mongo ( insert
, update
และremoved
เรียกกลับ) เพื่อป้อนข้อมูลของกล่องผสาน ( this.added
, this.changed
และthis.removed
) ค่อนข้างเรียบร้อยที่คุณสามารถตรวจสอบสิทธิ์ทั้งหมดได้ล่วงหน้าในฟังก์ชันการเผยแพร่จากนั้นเชื่อมต่อไดรเวอร์ฐานข้อมูลเข้ากับกล่องผสานโดยตรงโดยไม่ต้องใช้รหัสผู้ใช้ใด ๆ และเมื่อเปิดการเผยแพร่อัตโนมัติแม้เพียงเล็กน้อยนี้จะถูกซ่อนไว้: เซิร์ฟเวอร์จะตั้งค่าการสืบค้นสำหรับเอกสารทั้งหมดในแต่ละคอลเลกชั่นโดยอัตโนมัติและส่งไปยังกล่องผสาน
ในทางกลับกันคุณไม่ จำกัด เฉพาะการเผยแพร่การสืบค้นฐานข้อมูล ตัวอย่างเช่นคุณสามารถเขียนฟังก์ชันการเผยแพร่ที่อ่านตำแหน่ง GPS จากอุปกรณ์ภายใน a Meteor.setInterval
หรือสำรวจ REST API เดิมจากบริการเว็บอื่น ในกรณีที่คุณต้องการปล่อยเปลี่ยนแปลงกล่องผสานโดยการเรียกระดับต่ำadded
, changed
และremoved
DDP API
คนขับ Mongo
ไดรเวอร์ Mongo ของงานคือการดูฐานข้อมูล Mongo เพื่อให้การเปลี่ยนแปลงคำสั่งที่มีชีวิต คำสั่งเหล่านี้ทำงานอย่างต่อเนื่องและกลับไปปรับปรุงตลอดการเปลี่ยนแปลงผลโดยการโทรadded
, removed
และchanged
เรียกกลับ
Mongo ไม่ใช่ฐานข้อมูลแบบเรียลไทม์ ดังนั้นผู้ขับขี่จึงสำรวจ มันจะเก็บสำเนาของผลลัพธ์การสืบค้นล่าสุดไว้ในหน่วยความจำสำหรับแต่ละแบบสอบถามสดที่ใช้งานอยู่ ในแต่ละรอบการเลือกตั้งจะเปรียบเทียบผลการใหม่ที่มีผลการบันทึกไว้ก่อนหน้านี้การคำนวณกำหนดขั้นต่ำของadded
, removed
และchanged
เหตุการณ์ที่อธิบายถึงความแตกต่าง หากผู้โทรหลายรายลงทะเบียนการโทรกลับสำหรับการสืบค้นแบบสดเดียวกันไดรเวอร์จะดูสำเนาแบบสอบถามเพียงชุดเดียวโดยเรียกการโทรกลับที่ลงทะเบียนแต่ละครั้งด้วยผลลัพธ์เดียวกัน
ทุกครั้งที่เซิร์ฟเวอร์อัปเดตคอลเลกชันไดรเวอร์จะคำนวณคิวรีสดแต่ละรายการในคอลเล็กชันนั้นใหม่ (Meteor เวอร์ชันในอนาคตจะแสดง API การปรับขนาดเพื่อ จำกัด การสืบค้นที่ใช้งานจริงที่คำนวณใหม่ในการอัปเดต) นอกจากนี้ไดรเวอร์ยังสำรวจแบบสอบถามสดแต่ละรายการในเวลา 10 วินาทีเพื่อ ตรวจจับการอัปเดตฐานข้อมูลนอกวงที่ข้ามเซิร์ฟเวอร์ Meteor
กล่องผสาน
งานของกล่องผสานคือการรวมผล ( added
, changed
และremoved
สาย) ทั้งหมดของฟังก์ชั่นการใช้งานเผยแพร่ของลูกค้าเข้าไปในกระแสข้อมูลเดียว มีหนึ่งกล่องผสานสำหรับแต่ละไคลเอนต์ที่เชื่อมต่อ มันมีสำเนา minimongo cache ของลูกค้าที่สมบูรณ์
ในตัวอย่างของคุณที่มีการสมัครสมาชิกเพียงครั้งเดียวกล่องผสานจะเป็นการส่งผ่าน แต่แอปที่ซับซ้อนกว่านั้นสามารถมีการสมัครรับข้อมูลหลายรายการซึ่งอาจทับซ้อนกัน หากการสมัครรับข้อมูลสองรายการตั้งค่าแอตทริบิวต์เดียวกันในเอกสารเดียวกันกล่องผสานจะตัดสินใจว่าค่าใดที่มีลำดับความสำคัญและส่งเฉพาะค่านั้นไปยังไคลเอ็นต์ เรายังไม่ได้เปิดเผย API สำหรับการตั้งค่าลำดับความสำคัญการสมัครสมาชิก สำหรับตอนนี้ลำดับความสำคัญจะถูกกำหนดโดยลำดับที่ลูกค้าสมัครรับชุดข้อมูล การสมัครสมาชิกครั้งแรกที่ลูกค้าให้มีลำดับความสำคัญสูงสุดการสมัครสมาชิกครั้งที่สองจะสูงที่สุดถัดไปและอื่น ๆ
เนื่องจากกล่องผสานมีสถานะของไคลเอ็นต์จึงสามารถส่งจำนวนข้อมูลขั้นต่ำเพื่อให้ไคลเอ็นต์แต่ละรายทันสมัยอยู่เสมอไม่ว่าฟังก์ชันการเผยแพร่จะฟีดข้อมูลใดก็ตาม
เกิดอะไรขึ้นกับการอัปเดต
ตอนนี้เราได้กำหนดขั้นตอนสำหรับสถานการณ์ของคุณแล้ว
เรามีลูกค้าที่เชื่อมต่อ 1,000 ราย แต่ละคนสมัครรับข้อความค้นหา Mongo แบบสดเดียวกัน ( Somestuff.find({})
) เนื่องจากแบบสอบถามเหมือนกันสำหรับไคลเอ็นต์แต่ละตัวโปรแกรมควบคุมจึงเรียกใช้แบบสอบถามสดเพียงรายการเดียว มี 1,000 กล่องผสานที่ใช้งานอยู่ และแต่ละคนของลูกค้าเผยแพร่ฟังก์ชั่นการจดทะเบียนadded
, changed
และ
removed
บนว่าแบบสอบถามที่มีชีวิตที่ฟีดเป็นหนึ่งในกล่องผสาน ไม่มีสิ่งอื่นใดที่เชื่อมต่อกับกล่องผสาน
ก่อนอื่นคนขับ Mongo เมื่อไคลเอนต์รายใดรายหนึ่งแทรกเอกสารใหม่ลงในSomestuff
เครื่องจะทริกเกอร์การคำนวณใหม่ โปรแกรมควบคุม Mongo เรียกใช้แบบสอบถามสำหรับเอกสารทั้งหมดในSomestuff
อีกครั้งเปรียบเทียบผลลัพธ์กับผลลัพธ์ก่อนหน้านี้ในหน่วยความจำพบว่ามีเอกสารใหม่หนึ่งฉบับและเรียกการinsert
เรียกกลับที่ลงทะเบียนไว้ 1,000 รายการ
ถัดไปฟังก์ชั่นการเผยแพร่ มีน้อยมากที่เกิดขึ้นที่นี่: แต่ละ 1,000 เรียกกลับข้อมูลดันลงในช่องผสานโดยการเรียกinsert
added
สุดท้ายแต่ละช่องผสานจะตรวจสอบแอตทริบิวต์ใหม่เหล่านี้เทียบกับสำเนาแคชของไคลเอ็นต์ในหน่วยความจำ ในแต่ละกรณีพบว่าค่ายังไม่อยู่ในไคลเอนต์และไม่ได้บดบังค่าที่มีอยู่ ดังนั้นกล่องผสานจะDATA
แสดงข้อความDDP บนการเชื่อมต่อ SockJS ไปยังไคลเอนต์และอัปเดตสำเนาในหน่วยความจำฝั่งเซิร์ฟเวอร์
ต้นทุน CPU ทั้งหมดคือต้นทุนในการเปลี่ยนข้อความค้นหา Mongo หนึ่งรายการบวกค่าใช้จ่าย 1,000 กล่องผสานเพื่อตรวจสอบสถานะของลูกค้าและสร้างเพย์โหลดข้อความ DDP ใหม่ ข้อมูลเดียวที่ไหลผ่านสายคือออบเจ็กต์ JSON เดียวที่ส่งไปยังไคลเอ็นต์ 1,000 เครื่องซึ่งสอดคล้องกับเอกสารใหม่ในฐานข้อมูลพร้อมด้วยข้อความ RPC หนึ่งข้อความไปยังเซิร์ฟเวอร์จากไคลเอนต์ที่ทำการแทรกต้นฉบับ
การเพิ่มประสิทธิภาพ
นี่คือสิ่งที่เราวางแผนไว้อย่างแน่นอน
ไดรเวอร์ Mongo ที่มีประสิทธิภาพมากขึ้น เรา
ปรับไดรเวอร์ให้เหมาะสม
ใน 0.5.1 เพื่อเรียกใช้ผู้สังเกตการณ์เพียงคนเดียวต่อแบบสอบถามที่แตกต่างกัน
ไม่ใช่ทุกการเปลี่ยนแปลงฐานข้อมูลที่ควรทำให้เกิดการคำนวณใหม่ของแบบสอบถาม เราสามารถทำการปรับปรุงบางอย่างโดยอัตโนมัติได้ แต่แนวทางที่ดีที่สุดคือ API ที่ช่วยให้นักพัฒนาสามารถระบุได้ว่าต้องเรียกใช้คำค้นหาใดอีกครั้ง ตัวอย่างเช่นนักพัฒนาเห็นได้ชัดว่าการแทรกข้อความลงในห้องแชทหนึ่งไม่ควรทำให้การสืบค้นที่ใช้งานอยู่สำหรับข้อความในห้องที่สองเป็นโมฆะ
ไดรเวอร์ Mongo ฟังก์ชันการเผยแพร่และการผสานไม่จำเป็นต้องทำงานในกระบวนการเดียวกันหรือแม้แต่ในเครื่องเดียวกัน แอปพลิเคชันบางตัวเรียกใช้แบบสอบถามสดที่ซับซ้อนและต้องการ CPU มากขึ้นเพื่อดูฐานข้อมูล คนอื่น ๆ มีแบบสอบถามที่แตกต่างกันเพียงเล็กน้อย (ลองนึกภาพบล็อกเอ็นจิ้น) แต่อาจมีไคลเอนต์ที่เชื่อมต่อจำนวนมากซึ่งจำเป็นต้องใช้ CPU มากขึ้นสำหรับการผสานกล่อง การแยกส่วนประกอบเหล่านี้จะทำให้เราปรับขนาดแต่ละชิ้นได้อย่างอิสระ
ฐานข้อมูลจำนวนมากสนับสนุนทริกเกอร์ที่เริ่มทำงานเมื่อมีการอัปเดตแถวและระบุแถวเก่าและใหม่ ด้วยคุณสมบัติดังกล่าวโปรแกรมควบคุมฐานข้อมูลสามารถลงทะเบียนทริกเกอร์แทนการสำรวจการเปลี่ยนแปลง