MongoDB lưu trữ dữ liệu của nó như thế nào?

Để hiểu đúng cách thiết kế lược đồ tác động đến hiệu suất, điều quan trọng là phải hiểu cách thức hoạt động của MongoDB dưới vỏ bọc

Tệp ánh xạ bộ nhớ

MongoDB sử dụng các tệp ánh xạ bộ nhớ để lưu trữ dữ liệu của nó (Tệp ánh xạ bộ nhớ là một phân đoạn của bộ nhớ ảo đã được gán tương quan trực tiếp giữa từng byte với một số phần của tệp hoặc tệp)

MongoDB lưu trữ dữ liệu của nó như thế nào?

Các tệp ánh xạ bộ nhớ cho phép MongoDB ủy thác việc xử lý Bộ nhớ ảo cho hệ điều hành thay vì tự quản lý bộ nhớ một cách rõ ràng. Do Không gian địa chỉ ảo lớn hơn nhiều so với bất kỳ RAM vật lý nào (Bộ nhớ truy cập ngẫu nhiên) được cài đặt trong máy tính nên có sự tranh cãi về phần nào của Bộ nhớ ảo được lưu trong RAM tại bất kỳ thời điểm nào. Khi hệ điều hành hết RAM và một ứng dụng yêu cầu thứ gì đó hiện không có trong RAM, nó sẽ hoán đổi bộ nhớ sang đĩa để tạo khoảng trống cho dữ liệu mới được yêu cầu. Hầu hết các hệ điều hành sẽ thực hiện việc này bằng cách sử dụng chiến lược Ít được sử dụng gần đây nhất (LRU) trong đó dữ liệu cũ nhất được hoán đổi vào đĩa trước

Khi đọc trên MongoDB, rất có thể bạn sẽ bắt gặp từ “Working Set”. Đây là dữ liệu mà ứng dụng của bạn liên tục yêu cầu. Nếu tất cả “Working Set” của bạn đều nằm gọn trong RAM thì mọi truy cập sẽ nhanh chóng vì hệ điều hành sẽ không phải trao đổi nhiều từ đĩa. Tuy nhiên, nếu “Bộ làm việc” của bạn không vừa với RAM, bạn sẽ bị phạt về hiệu suất vì hệ điều hành cần hoán đổi một phần của “Bộ làm việc” của bạn sang đĩa để truy cập vào phần khác của nó

Xác định xem Working Set có lớn không

Bạn có thể nhận được dấu hiệu cho biết bộ làm việc của mình có vừa với bộ nhớ hay không bằng cách xem số lỗi trang theo thời gian. Nếu nó tăng nhanh, điều đó có nghĩa là Working Set của bạn không vừa với bộ nhớ

>   use mydb
>   db.serverStatus().extra_info.page_faults

Đây thường là dấu hiệu cho thấy đã đến lúc cân nhắc tăng dung lượng RAM trong máy của bạn hoặc phân tách hệ thống MongoDB của bạn để có thể lưu nhiều “Working Set” hơn trong bộ nhớ (sharding chia “Working Set” của bạn thành nhiều RAM máy

đệm

Một khía cạnh quan trọng khác cần hiểu với MongoDB là cách các tài liệu phát triển về mặt vật lý trong cơ sở dữ liệu. Hãy lấy ví dụ tài liệu đơn giản dưới đây

{
  "hello": "world"
}

Nếu chúng ta thêm một trường mới có tên vào tài liệu

{
  "hello": "world",
  "name": "Christian"
}

Tài liệu sẽ tăng kích thước. Nếu MongoDB được triển khai một cách ngây thơ thì bây giờ nó sẽ cần chuyển tài liệu sang một không gian mới lớn hơn vì nó sẽ phát triển vượt quá không gian được phân bổ ban đầu

Tuy nhiên, MongoDB đã lưu trữ tài liệu gốc, nó đã thêm một chút khoảng trống ở cuối tài liệu do đó được gọi là phần đệm. Lý do cho phần đệm này là MongoDB muốn tài liệu tăng kích thước theo thời gian. Miễn là phần mở rộng tài liệu này nằm trong không gian đệm bổ sung, MongoDB không cần di chuyển tài liệu sang một không gian mới lớn hơn, do đó tránh được chi phí sao chép byte trong bộ nhớ và trên đĩa

MongoDB lưu trữ dữ liệu của nó như thế nào?

Theo thời gian, hệ số đệm chi phối lượng không gian bổ sung được thêm vào tài liệu được chèn vào MongoDB sẽ thay đổi khi cơ sở dữ liệu cố gắng tìm sự cân bằng giữa kích thước cuối cùng của tài liệu và không gian không sử dụng được chiếm bởi phần đệm. Tuy nhiên, nếu sự phát triển của các tài liệu riêng lẻ là ngẫu nhiên thì MongoDB sẽ không thể Phân bổ trước chính xác mức đệm phù hợp và cơ sở dữ liệu có thể sẽ mất nhiều thời gian để sao chép tài liệu trong bộ nhớ và trên đĩa thay vì thực hiện công việc cụ thể của ứng dụng gây ra

Cách xác định hệ số đệm

Bạn có thể xác định hệ số đệm cho một bộ sưu tập cụ thể theo cách sau

>   use mydb
>   db.my_collection.stats()

Kết quả trả về chứa trường paddingFactor. Giá trị cho bạn biết lượng đệm được thêm vào. Giá trị 1 có nghĩa là không có phần đệm thêm giá trị 2 có nghĩa là phần đệm có cùng kích thước với kích thước tài liệu

Hệ số đệm bằng 1 thường là dấu hiệu cho thấy cơ sở dữ liệu đang dành phần lớn thời gian để ghi dữ liệu mới vào bộ nhớ và đĩa thay vì di chuyển dữ liệu hiện có. Đã nói rằng người ta phải tính đến quy mô của các hoạt động viết. Nếu bạn chỉ có 1000 tài liệu trong một bộ sưu tập thì có thể không có vấn đề gì nếu hệ số đệm của bạn gần bằng 2. Mặt khác, nếu bạn đang ghi một lượng lớn dữ liệu chuỗi thời gian, tác động của việc di chuyển tài liệu trong bộ nhớ và trên đĩa có thể ảnh hưởng nghiêm trọng đến hiệu suất của bạn

sự phân mảnh

Khi tài liệu di chuyển xung quanh hoặc bị loại bỏ, chúng sẽ để lại lỗ hổng. MongoDB cố gắng sử dụng lại các lỗ hổng này cho các tài liệu mới bất cứ khi nào có thể, nhưng theo thời gian, nó sẽ dần dần nhận thấy rằng mình có rất nhiều lỗ hổng không thể sử dụng lại được vì các tài liệu không thể vừa với chúng. Hiệu ứng này được gọi là phân mảnh và phổ biến trong tất cả các hệ thống cấp phát bộ nhớ bao gồm cả hệ điều hành của bạn

MongoDB lưu trữ dữ liệu của nó như thế nào?

Ảnh hưởng của phân mảnh là lãng phí không gian. Do MongoDB sử dụng các tệp được ánh xạ bộ nhớ, mọi phân mảnh trên đĩa cũng sẽ được phản ánh trong phân mảnh trong RAM. Điều này có tác dụng làm cho “Working Set” vừa với RAM ít hơn và gây ra nhiều sự hoán đổi vào đĩa hơn

Cách xác định độ phân mảnh

Bạn có thể nhận được một dấu hiệu tốt về sự phân mảnh bằng cách

>   use mydb
>   var s = db.my_collection.stats()
>   var frag = s.storageSize / (s.size + s.totalIndexSize)

Giá trị phân mảnh lớn hơn 1 cho biết một số mức độ phân mảnh

Có ba cách chính để tránh hoặc hạn chế phân mảnh cho dữ liệu MongoDB của bạn

Cách đầu tiên là sử dụng lệnh compact trên MongoDB để ghi lại dữ liệu và do đó loại bỏ phân mảnh. Thật không may kể từ ngày 2. 6 compact là một hoạt động ngoại tuyến có nghĩa là cơ sở dữ liệu phải ngừng sản xuất trong suốt thời gian hoạt động của compact

Tùy chọn thứ hai là sử dụng tùy chọn usePowerOf2Sizes để MongoDB phân bổ bộ nhớ ở mức 2. Vì vậy, thay vì phân bổ bộ nhớ để phù hợp với một tài liệu cụ thể, MongoDB chỉ phân bổ theo lũy thừa 2 (128 byte, 256 byte, 512 byte, 1024 byte, v.v.). Điều này có nghĩa là ít có khả năng một lỗ không được sử dụng lại vì nó sẽ luôn có kích thước tiêu chuẩn. Tuy nhiên, nó làm tăng khả năng lãng phí không gian vì một tài liệu dài 257 byte sẽ chiếm một phân bổ lớn 512 byte

kể từ 2. 6 usePowerOf2Sizes là chiến lược phân bổ mặc định cho các bộ sưu tập

Tùy chọn thứ ba và hơi khó hơn là xem xét sự phân mảnh trong thiết kế lược đồ của bạn. Ứng dụng có thể mô hình hóa các tài liệu của nó để giảm thiểu sự phân mảnh bằng cách thực hiện những việc như phân bổ trước kích thước tối đa của tài liệu và đảm bảo việc tăng kích thước tài liệu được quản lý chính xác. Một số mẫu trong cuốn sách này sẽ thảo luận về các khía cạnh của

MongoDB có lưu trữ dữ liệu trong bộ nhớ không?

MongoDB không phải là cơ sở dữ liệu trong bộ nhớ . Mặc dù nó có thể được cấu hình để chạy theo cách đó. Nhưng nó sử dụng bộ đệm một cách tự do, nghĩa là các bản ghi dữ liệu được lưu giữ trong bộ nhớ để truy xuất nhanh, trái ngược với trên đĩa.

MongoDB lưu trữ dữ liệu trên đĩa như thế nào?

MongoDB lưu trữ dữ liệu trên đĩa dưới dạng BSON trong thư mục đường dẫn dữ liệu của bạn, thường là /data/db . Nên có hai tệp cho mỗi bộ sưu tập ở đó, bộ sưu tập. 0, lưu trữ dữ liệu (và số nguyên đó sau đó được tăng lên khi cần) và bộ sưu tập. ns lưu trữ siêu dữ liệu không gian tên cho bộ sưu tập.