Câu trả lời ngắn gọn là chỉ có dữ liệu mới được gửi xuống dây. Đây là cách nó hoạt động.
Có ba phần quan trọng của máy chủ Meteor quản lý đăng ký: chức năng xuất bản , xác định logic cho dữ liệu mà đăng ký cung cấp; các tài xế Mongo , mà đồng hồ cơ sở dữ liệu cho những thay đổi; và hộp hợp nhất , kết hợp tất cả các đăng ký đang hoạt động của khách hàng và gửi chúng qua mạng cho khách hàng.
Xuất bản các chức năng
Mỗi khi máy khách Meteor đăng ký một bộ sưu tập, máy chủ sẽ chạy
chức năng xuất bản . Công việc của chức năng xuất bản là tìm ra tập hợp các tài liệu mà ứng dụng khách của nó phải có và gửi từng thuộc tính tài liệu vào hộp phối. Nó chạy một lần cho mỗi khách hàng đăng ký mới. Bạn có thể đặt bất kỳ JavaScript nào bạn muốn vào chức năng xuất bản, chẳng hạn như sử dụng điều khiển truy cập phức tạp tùy ý this.userId
. Các công bố chức năng gửi dữ liệu vào ô merge bằng cách gọi this.added
, this.changed
và
this.removed
. Xem
tài liệu xuất bản đầy đủ để biết thêm chi tiết.
Hầu hết các công bố chức năng không cần phải làm việc nhiều với mức độ thấp
added
, changed
và removed
API, mặc dù. Nếu một công bố chức năng trả về một con trỏ Mongo, máy chủ Meteor tự động kết nối đầu ra của người lái xe Mongo ( insert
, update
và removed
callbacks) đến đầu vào của hộp merge ( this.added
, this.changed
và this.removed
). Khá gọn gàng là bạn có thể thực hiện tất cả các kiểm tra quyền trước trong một chức năng xuất bản và sau đó kết nối trực tiếp trình điều khiển cơ sở dữ liệu với hộp hợp nhất mà không cần bất kỳ mã người dùng nào. Và khi tự động xuất bản được bật, ngay cả một chút này cũng bị ẩn đi: máy chủ tự động thiết lập truy vấn cho tất cả tài liệu trong mỗi bộ sưu tập và đẩy chúng vào hộp hợp nhất.
Mặt khác, bạn không bị giới hạn trong việc xuất bản các truy vấn cơ sở dữ liệu. Ví dụ: bạn có thể viết một hàm xuất bản đọc vị trí GPS từ một thiết bị bên trong một Meteor.setInterval
hoặc thăm dò một API REST kế thừa từ một dịch vụ web khác. Trong những trường hợp, bạn sẽ phát ra thay đổi đối với hộp kết hợp bằng cách gọi ở mức độ thấp added
, changed
và removed
DDP API.
Người lái xe Mongo
Công việc của trình điều khiển Mongo là xem cơ sở dữ liệu Mongo để biết các thay đổi đối với các truy vấn trực tiếp. Các truy vấn này chạy liên tục và trở về bản cập nhật như sự thay đổi kết quả bằng cách gọi added
, removed
và changed
callbacks.
Mongo không phải là cơ sở dữ liệu thời gian thực. Vì vậy, người lái xe thăm dò ý kiến. Nó giữ một bản sao trong bộ nhớ của kết quả truy vấn cuối cùng cho mỗi truy vấn trực tiếp đang hoạt động. Trên mỗi chu kỳ bỏ phiếu, nó sẽ so sánh kết quả mới với kết quả đã lưu trước đó, tính toán các thiết lập tối thiểu added
, removed
và changed
các sự kiện mô tả sự khác biệt. Nếu nhiều người gọi đăng ký các lệnh gọi lại cho cùng một truy vấn trực tiếp, trình điều khiển chỉ xem một bản sao của truy vấn, gọi mỗi lệnh gọi lại đã đăng ký với cùng một kết quả.
Mỗi khi máy chủ cập nhật một bộ sưu tập, trình điều khiển sẽ tính toán lại từng truy vấn trực tiếp trên bộ sưu tập đó (Các phiên bản tương lai của Meteor sẽ hiển thị API điều chỉnh tỷ lệ để giới hạn các truy vấn trực tiếp được tính toán lại khi cập nhật.) Trình điều khiển cũng thăm dò từng truy vấn trực tiếp trên bộ hẹn giờ 10 giây để bắt các bản cập nhật cơ sở dữ liệu ngoài băng tần đã bỏ qua máy chủ Meteor.
Hộp hợp nhất
Công việc của hộp kết hợp là kết hợp các kết quả ( added
, changed
và removed
cuộc gọi) của tất cả các công bố các chức năng hoạt động của khách hàng vào một dòng dữ liệu duy nhất. Có một hộp hợp nhất cho mỗi máy khách được kết nối. Nó chứa một bản sao hoàn chỉnh của bộ nhớ cache minimongo của khách hàng.
Trong ví dụ của bạn chỉ với một đăng ký duy nhất, hộp hợp nhất về cơ bản là một chuyển tiếp. Nhưng một ứng dụng phức tạp hơn có thể có nhiều đăng ký có thể trùng lặp. Nếu cả hai đăng ký đều đặt cùng một thuộc tính trên cùng một tài liệu, hộp hợp nhất sẽ quyết định giá trị nào được ưu tiên và chỉ gửi giá trị đó cho máy khách. Chúng tôi chưa tiết lộ API để đặt mức độ ưu tiên đăng ký. Hiện tại, mức độ ưu tiên được xác định bởi thứ tự khách hàng đăng ký tập dữ liệu. Đăng ký đầu tiên mà khách hàng thực hiện có mức độ ưu tiên cao nhất, đăng ký thứ hai có mức độ ưu tiên cao nhất tiếp theo, v.v.
Vì hộp hợp nhất giữ trạng thái của khách hàng, nó có thể gửi số lượng dữ liệu tối thiểu để giữ cho từng ứng dụng được cập nhật, bất kể chức năng xuất bản cung cấp cho nó là gì.
Điều gì xảy ra trên bản cập nhật
Vì vậy, bây giờ chúng tôi đã tạo tiền đề cho kịch bản của bạn.
Chúng tôi có 1.000 khách hàng được kết nối. Mỗi người được đăng ký vào cùng một truy vấn Mongo trực tiếp ( Somestuff.find({})
). Vì truy vấn giống nhau cho mỗi máy khách, trình điều khiển chỉ chạy một truy vấn trực tiếp. Có 1.000 hộp hợp nhất đang hoạt động. Và mỗi khách hàng của công bố chức năng đăng ký một added
, changed
và
removed
trên đó truy vấn trực tiếp rằng thức ăn vào một trong các hộp merge. Không có gì khác được kết nối với các hộp hợp nhất.
Đầu tiên là trình điều khiển Mongo. Khi một trong các máy khách chèn một tài liệu mới vào Somestuff
, nó sẽ kích hoạt tính toán lại. Trình điều khiển Mongo chạy lại truy vấn cho tất cả các tài liệu trong Somestuff
, so sánh kết quả với kết quả trước đó trong bộ nhớ, nhận thấy rằng có một tài liệu mới và gọi mỗi trong số 1.000 lệnh insert
gọi lại đã đăng ký .
Tiếp theo, các chức năng xuất bản. Có rất ít điều xảy ra ở đây: mỗi 1.000 lệnh insert
gọi lại đẩy dữ liệu vào hộp hợp nhất bằng cách gọi added
.
Cuối cùng, mỗi hộp hợp nhất sẽ kiểm tra các thuộc tính mới này so với bản sao trong bộ nhớ của bộ nhớ cache của khách hàng của nó. Trong mỗi trường hợp, nó nhận thấy rằng các giá trị chưa có trên máy khách và không phủ bóng giá trị hiện có. Vì vậy, hộp hợp nhất phát ra một DATA
thông báo DDP trên kết nối SockJS tới máy khách của nó và cập nhật bản sao trong bộ nhớ phía máy chủ của nó.
Tổng chi phí CPU là chi phí để khác biệt một truy vấn Mongo, cộng với chi phí của 1.000 hộp hợp nhất kiểm tra trạng thái của khách hàng của họ và xây dựng trọng tải thông báo DDP mới. Dữ liệu duy nhất truyền qua dây là một đối tượng JSON duy nhất được gửi đến từng máy khách trong số 1.000 máy khách, tương ứng với tài liệu mới trong cơ sở dữ liệu, cộng với một thông báo RPC tới máy chủ từ máy khách đã thực hiện chèn ban đầu.
Tối ưu hóa
Đây là những gì chúng tôi chắc chắn đã lên kế hoạch.
Trình điều khiển Mongo hiệu quả hơn. Chúng tôi đã
tối ưu hóa trình điều khiển
trong 0.5.1 để chỉ chạy một trình quan sát duy nhất cho mỗi truy vấn riêng biệt.
Không phải mọi thay đổi DB đều nên kích hoạt tính toán lại một truy vấn. Chúng tôi có thể thực hiện một số cải tiến tự động, nhưng cách tiếp cận tốt nhất là một API cho phép nhà phát triển chỉ định truy vấn nào cần chạy lại. Ví dụ: rõ ràng đối với một nhà phát triển rằng việc chèn một tin nhắn vào một phòng trò chuyện sẽ không làm mất hiệu lực của một truy vấn trực tiếp cho các tin nhắn trong phòng thứ hai.
Trình điều khiển Mongo, chức năng xuất bản và hộp hợp nhất không cần phải chạy trong cùng một quy trình hoặc thậm chí trên cùng một máy. Một số ứng dụng chạy các truy vấn trực tiếp phức tạp và cần nhiều CPU hơn để xem cơ sở dữ liệu. Những người khác chỉ có một số truy vấn riêng biệt (hãy tưởng tượng một công cụ blog), nhưng có thể có nhiều máy khách được kết nối - những máy khách này cần nhiều CPU hơn cho các hộp hợp nhất. Việc tách các thành phần này sẽ cho phép chúng tôi chia tỷ lệ từng phần một cách độc lập.
Nhiều cơ sở dữ liệu hỗ trợ trình kích hoạt kích hoạt khi một hàng được cập nhật và cung cấp các hàng cũ và mới. Với tính năng đó, trình điều khiển cơ sở dữ liệu có thể đăng ký trình kích hoạt thay vì bỏ phiếu cho các thay đổi.