Đối với những bạn mới sử dụng MongoDB, việc sử dụng dung lượng MongoDB có vẻ khá khó hiểu. Trong bài viết này, tôi sẽ giải thích cách MongoDB phân bổ không gian và cách diễn giải thông tin sử dụng không gian trong bảng điều khiển ObjectRocket của chúng tôi để đưa ra phán đoán về thời điểm bạn cần thu gọn cá thể của mình hoặc thêm một phân đoạn để tăng không gian có sẵn cho phiên bản của bạn.
Đầu tiên, hãy bắt đầu với một phiên bản Phương tiện hoàn toàn mới bao gồm một phân đoạn 5GB duy nhất. Tôi sẽ điền trường hợp này với một số dữ liệu thử nghiệm trong cơ sở dữ liệu có tên là “đại dương”. Đây là cách sử dụng không gian cho trường hợp này trông như thế nào sau khi thêm một số dữ liệu thử nghiệm và tạo một vài chỉ mục (cho mục đích của bài viết này, tôi đã cố tình thêm các chỉ mục bổ sung mà tôi biết sẽ có kích thước khá lớn so với tập dữ liệu thử nghiệm):
Làm thế nào mà 315MiB dữ liệu và 254MiB chỉ mục có nghĩa là chúng tôi đang sử dụng 2,1 GiB trong số 5 GiB của chúng tôi? Để giải thích, hãy bắt đầu với cách MongoDB lưu trữ dữ liệu trên đĩa dưới dạng một loạt các phạm vi. Bởi vì các phiên bản ObjectRocket của chúng tôi chạy với tùy chọn smallfiles, phạm vi đầu tiên được phân bổ là 16MB. Các phạm vi này tăng gấp đôi kích thước cho đến khi chúng đạt đến 512MB, sau đó mọi phạm vi được phân bổ dưới dạng tệp 512MB. Vì vậy, cơ sở dữ liệu ví dụ “đại dương” của chúng tôi có cấu trúc tệp như sau:
$ ls -lh ocean/
total 1.5G
-rw------- 1 mongodb mongodb 16M Aug 20 22:30 ocean.0
-rw------- 1 mongodb mongodb 32M Aug 20 20:44 ocean.1
-rw------- 1 mongodb mongodb 64M Aug 20 22:23 ocean.2
-rw------- 1 mongodb mongodb 128M Aug 20 22:30 ocean.3
-rw------- 1 mongodb mongodb 256M Aug 20 22:30 ocean.4
-rw------- 1 mongodb mongodb 512M Aug 20 22:30 ocean.5
-rw------- 1 mongodb mongodb 512M Aug 20 22:30 ocean.6
-rw------- 1 mongodb mongodb 16M Aug 20 22:30 ocean.ns
drwxr-xr-x 2 mongodb mongodb 4.0K Aug 20 22:30 _tmp
Các phạm vi này lưu trữ cả dữ liệu và chỉ mục cho cơ sở dữ liệu của chúng tôi. Với MongoDB, ngay sau khi bất kỳ dữ liệu nào được ghi vào một mức độ nào đó, mức độ logic tiếp theo sẽ được phân bổ. Do đó, với cấu trúc trên, có thể lúc này biển.6 không có dữ liệu, nhưng đã được phân bổ trước cho khi biển.5 đầy. Ngay sau khi bất kỳ dữ liệu nào được ghi vào Ocean.6, một phạm vi 512MB mới, Ocean.7, sẽ lại được phân bổ trước. Khi dữ liệu bị xóa khỏi cơ sở dữ liệu MongoDB, không gian sẽ không được giải phóng cho đến khi bạn thu gọn - do đó, theo thời gian, các tệp dữ liệu này có thể bị phân mảnh khi dữ liệu bị xóa (hoặc nếu tài liệu phát triển lâu hơn vị trí lưu trữ ban đầu vì các khóa bổ sung được thêm vào). Một nén phân mảnh các tệp dữ liệu này vì trong quá trình nén, dữ liệu được sao chép từ một thành viên khác của tập hợp bản sao và các tệp dữ liệu được tạo lại từ đầu.
Một tệp bổ sung 16MB lưu trữ không gian tên, đây là tệp Ocean.ns. Mẫu tương tự này xảy ra cho mỗi cơ sở dữ liệu trên một cá thể MongoDB. Bên cạnh cơ sở dữ liệu “đại dương” của chúng tôi, có hai cơ sở dữ liệu hệ thống bổ sung trên phân đoạn của chúng tôi:“quản trị viên” và “cục bộ”. Cơ sở dữ liệu “quản trị viên” lưu trữ thông tin người dùng cho tất cả người dùng cơ sở dữ liệu (trước 2.6.x, cơ sở dữ liệu này chỉ được sử dụng cho người dùng quản trị). Mặc dù cơ sở dữ liệu quản trị nhỏ, chúng tôi vẫn có mức 16MB, mức 32MB được phân bổ trước và tệp không gian tên 16MB cho cơ sở dữ liệu này.
Cơ sở dữ liệu hệ thống thứ hai là cơ sở dữ liệu “cục bộ”. Mỗi phân đoạn chúng tôi cung cấp tại ObjectRocket là một tập hợp bản sao ba thành viên. Để giữ cho các bản sao này được đồng bộ hóa, MongoDB duy trì một nhật ký, được gọi là oplog, của mỗi bản cập nhật. Điều này được giữ đồng bộ trên mỗi bản sao và được sử dụng để theo dõi những thay đổi cần được thực hiện trên các bản sao thứ cấp. Oplog này tồn tại dưới dạng một bộ sưu tập có giới hạn trong cơ sở dữ liệu "cục bộ". Tại ObjectRocket, chúng tôi định cấu hình kích thước của oplog thường là 10% kích thước phân đoạn - trong trường hợp phân đoạn 5GB của chúng tôi, oplog được định cấu hình là 500MB. Do đó, cơ sở dữ liệu "cục bộ" bao gồm mức 16 MB, mức 512 MB và tệp không gian tên 16 MB.
Cuối cùng, phân đoạn mẫu của chúng tôi chứa một khu vực dọn phòng nữa, tạp chí. Tạp chí là một tập hợp gồm 1-3 tệp có kích thước mỗi tệp khoảng 128MB. Bất cứ khi nào xảy ra ghi, MongoDB trước tiên sẽ ghi cập nhật tuần tự vào tạp chí. Sau đó, định kỳ một luồng nền sẽ gửi các bản cập nhật này vào các tệp dữ liệu thực tế (các phạm vi mà tôi đã đề cập trước đây), thường là 60 giây một lần. Lý do cho việc ghi hai lần này là việc ghi tuần tự vào nhật ký thường nhanh hơn rất nhiều so với việc tìm kiếm cần thiết để ghi vào các tệp dữ liệu thực tế. Bằng cách ghi các thay đổi ngay lập tức vào nhật ký, MongoDB có thể đảm bảo khôi phục dữ liệu trong trường hợp xảy ra sự cố mà không yêu cầu mọi lần ghi phải đợi cho đến khi thay đổi được ghi vào tệp dữ liệu. Trong trường hợp bản sao chính hiện tại của chúng tôi, tôi thấy chúng tôi có hai tệp tạp chí đang hoạt động:
$ ls -lh journal/
total 273M
-rw------- 1 mongodb mongodb 149M Aug 20 22:26 j._1
-rw------- 1 mongodb mongodb 124M Aug 20 22:30 j._2
MongoDB tự động xoay các tệp này tùy thuộc vào tần suất cập nhật so với tần suất chuyển nền vào đĩa.
Vì vậy, bây giờ tôi đã trình bày về cách MongoDB sử dụng không gian đĩa, điều này tương ứng với những gì được hiển thị trong thanh sử dụng dung lượng từ bảng điều khiển ObjectRocket mà tôi đã hiển thị trước đó?
- Giá trị NS, 48MB - tổng của ba tệp không gian tên 16MB cho ba cơ sở dữ liệu tôi đã đề cập, Ocean, admin và local.
- Giá trị dữ liệu, 315MiB - tổng giá trị được báo cáo cho dataSize trong
db.stats()
cho tất cả cơ sở dữ liệu (bao gồm cả cơ sở dữ liệu hệ thống). - Giá trị chỉ mục, 253,9MiB, - tổng giá trị được báo cáo cho indexSize trong
db.stats()
cho tất cả cơ sở dữ liệu (bao gồm cả cơ sở dữ liệu hệ thống). - Giá trị lưu trữ, 687,2MiB - tổng dữ liệu cộng với chỉ mục cho tất cả các cơ sở dữ liệu cộng với bất kỳ khoảng trống nào chưa được xác nhận do xóa.
- Tổng giá trị Tệp, 2.0 GiB - tổng dung lượng đĩa chúng tôi đang sử dụng trên bản sao chính. Ngoài không gian được bao phủ bởi giá trị Storage và giá trị NS, điều này còn bao gồm mọi phạm vi được phân bổ trước nhưng không bao gồm không gian được tạp chí sử dụng
Với những số liệu này, chúng tôi có thể thực hiện một số tính toán đơn giản để xác định xem liệu phiên bản này có đủ phân mảnh để cần nén hay không. Để tính toán không gian có thể bị mất do phân mảnh, hãy sử dụng như sau:
100% - (Dữ liệu + Chỉ mục) / Bộ nhớ
Trong trường hợp ví dụ của chúng tôi, điều này hoạt động đến 17% (100% - (315MiB Dữ liệu + 253,9MiB Chỉ mục) / 687,2MiB Storage =17%). Tôi khuyên bạn nên thu gọn phiên bản của mình khi sự phân mảnh đạt đến 20%.
Một phép tính khác mà chúng tôi có thể thực hiện là liệu chúng tôi có cần thêm một phân đoạn vào trường hợp này hay không dựa trên việc sử dụng không gian tổng thể của chúng tôi. Để tính toán việc sử dụng không gian tổng thể của bạn, hãy làm như sau:
(Tổng số tệp / (Kích thước gói * số phân đoạn)) * 100%
Đối với ví dụ ví dụ của chúng tôi, điều này hoạt động đến 40% ((2 GiB / 5 GiB * 1 phân đoạn) * 100% =40%). Thông thường, chúng tôi khuyên bạn nên thêm một phân đoạn khi mức sử dụng không gian tổng thể đạt đến 80%. Nếu bạn nhận thấy việc sử dụng dung lượng của mình đạt 80%, hãy liên hệ với bộ phận hỗ trợ và chúng tôi có thể giúp bạn thêm một phân đoạn vào phiên bản của mình.