Khóa MongoDB là khác nhau
Khóa trong MongoDB không hoạt động giống như khóa trong RDBMS, vì vậy cần giải thích một chút. Trong các phiên bản trước của MongoDB, chỉ có một chốt người đọc / người viết toàn cầu. Bắt đầu với MongoDB 2.2, có một chốt người đọc / người viết cho mỗi cơ sở dữ liệu.
Chốt người đọc-người viết
Điểm mấu chốt là nhiều người đọc, một người viết và là người tham gia viết lách. Điều này có nghĩa là:
- Có thể có số lượng không giới hạn người đọc đồng thời trên cơ sở dữ liệu
- Mỗi lần chỉ có thể có một người viết trên bất kỳ bộ sưu tập nào trong một cơ sở dữ liệu bất kỳ (sẽ nói thêm về điều này một chút)
- Nhà văn chặn người đọc
- Theo "nhà văn tham lam", ý tôi là khi có yêu cầu viết, tất cả người đọc sẽ bị chặn cho đến khi quá trình viết hoàn tất (sẽ nói thêm về điều này sau)
Lưu ý rằng tôi gọi đây là "chốt" chứ không phải là "khóa". Điều này là do nó nhẹ và trong một lược đồ được thiết kế phù hợp, khóa ghi được giữ theo thứ tự hàng chục hoặc hơn micro giây. Xem tại đây để biết thêm về khóa người viết-người viết.
Trong MongoDB, bạn có thể chạy nhiều truy vấn đồng thời tùy thích:miễn là dữ liệu có liên quan nằm trong RAM, tất cả chúng đều sẽ hài lòng mà không bị khóa xung đột.
Cập nhật tài liệu nguyên tử
Nhớ lại rằng trong MongoDB, mức độ giao dịch là một tài liệu duy nhất. Tất cả các cập nhật cho một tài liệu duy nhất là Nguyên tử. MongoDB đạt được điều này bằng cách giữ chốt ghi chỉ trong thời gian cần thiết để cập nhật một tài liệu duy nhất trong RAM. Nếu có bất kỳ hoạt động nào chạy chậm (cụ thể là nếu tài liệu hoặc mục nhập chỉ mục cần được phân trang từ đĩa), thì hoạt động đó sẽ mang lại chốt ghi. Khi thao tác đưa ra chốt, thì thao tác được xếp hàng đợi tiếp theo có thể tiến hành.
Điều này có nghĩa là việc ghi vào tất cả các tài liệu trong một cơ sở dữ liệu duy nhất sẽ được tuần tự hóa. Đây có thể là một vấn đề nếu bạn có thiết kế giản đồ kém và quá trình ghi của bạn mất nhiều thời gian, nhưng trong một lược đồ được thiết kế phù hợp, khóa không phải là vấn đề.
Nhà văn-Tham lam
Một vài lời nói thêm về sự tham lam của nhà văn:
Chỉ một nhà văn có thể giữ chốt tại một thời điểm; nhiều đầu đọc có thể giữ chốt cùng một lúc. Trong một cách triển khai ngây thơ, người viết có thể chết đói vô thời hạn nếu chỉ có một độc giả hoạt động. Để tránh điều này, trong triển khai MongoDB, khi bất kỳ luồng nào đơn lẻ thực hiện yêu cầu ghi cho một chốt cụ thể
- Tất cả những người đọc tiếp theo cần chốt đó sẽ chặn
- Người viết đó sẽ đợi cho đến khi tất cả người đọc hiện tại hoàn thành
- Người viết sẽ có được chốt ghi, thực hiện công việc của nó và sau đó nhả chốt ghi
- Giờ đây, tất cả những người đọc đã xếp hàng đợi sẽ tiếp tục
Hành vi thực tế rất phức tạp, vì hành vi tham lam của người viết này tương tác với việc thu lợi theo những cách có thể không rõ ràng. Nhớ lại rằng, bắt đầu với bản phát hành 2.2, có một riêng biệt chốt cho từng cơ sở dữ liệu, vì vậy việc ghi vào bất kỳ tập hợp nào trong cơ sở dữ liệu 'A' sẽ nhận được một chốt riêng biệt hơn là ghi vào bất kỳ tập hợp nào trong cơ sở dữ liệu 'B'.
Câu hỏi cụ thể
Về các câu hỏi cụ thể:
- Các khóa (thực ra là các chốt) do hạt nhân MongoDB giữ trong thời gian cần thiết để cập nhật một tài liệu duy nhất
- Nếu bạn có nhiều kết nối đến MongoDB và mỗi kết nối trong số chúng đang thực hiện một loạt các lần ghi, chốt sẽ được giữ trên cơ sở từng cơ sở dữ liệu miễn là quá trình ghi đó hoàn tất
- Nhiều kết nối đang thực hiện ghi (cập nhật / chèn / xóa) tất cả sẽ được xen kẽ nhau
Mặc dù điều này nghe có vẻ là một mối quan tâm lớn về hiệu suất, nhưng trên thực tế, nó không làm mọi thứ chậm lại. Với lược đồ được thiết kế phù hợp và khối lượng công việc điển hình, MongoDB sẽ bão hòa dung lượng I / O của đĩa - ngay cả đối với SSD - trước khi tỷ lệ khóa trên bất kỳ cơ sở dữ liệu nào vượt quá 50%.
Cụm MongoDB dung lượng cao nhất mà tôi biết hiện đang thực hiện 2 triệu lần ghi mỗi giây.