MongoDB và bộ dữ liệu không phù hợp với RAM cho dù bạn có cố gắng thế nào


12

Điều này phụ thuộc rất nhiều vào hệ thống, nhưng rất có thể chúng ta sẽ vượt qua một số vách đá tùy ý và gặp rắc rối thực sự. Tôi tò mò không biết loại quy tắc ngón tay cái nào tồn tại cho tỷ lệ RAM trên không gian đĩa tốt. Chúng tôi đang lên kế hoạch cho các hệ thống tiếp theo của mình và cần đưa ra một số lựa chọn liên quan đến RAM, SSD và số lượng mỗi nút mới sẽ nhận được.

Nhưng bây giờ cho một số chi tiết hiệu suất!

Trong quy trình làm việc bình thường của một lần chạy dự án, MongoDB bị ảnh hưởng với tỷ lệ ghi rất cao (70-80%). Khi giai đoạn thứ hai của đường ống xử lý đạt, nó sẽ được đọc rất cao vì nó cần phải sao chép các bản ghi được xác định trong nửa đầu của quá trình xử lý. Đây là quy trình làm việc "giữ cho bộ làm việc của bạn trong RAM" được tạo ra và chúng tôi đang thiết kế xung quanh giả định đó.

Toàn bộ dữ liệu được liên tục nhấn với các truy vấn ngẫu nhiên từ các nguồn có nguồn gốc từ người dùng cuối; mặc dù tần số không đều, kích thước thường khá nhỏ (nhóm 10 tài liệu). Vì đây là hướng tới người dùng, nên các phản hồi cần phải ở dưới ngưỡng "chán bây giờ" là 3 giây. Mẫu truy cập này ít có khả năng nằm trong bộ đệm, do đó sẽ rất có thể phải chịu các lần truy cập đĩa.

Một quy trình xử lý thứ cấp là đọc nhiều các lần xử lý trước đó có thể là vài ngày, vài tuần hoặc thậm chí vài tháng và được chạy không thường xuyên nhưng vẫn cần phải nhanh chóng. Lên đến 100% tài liệu trong lần xử lý trước sẽ được truy cập. Tôi không nghi ngờ gì về việc làm ấm bộ đệm.

Kích thước tài liệu hoàn thành rất khác nhau, nhưng kích thước trung bình là khoảng 8K.

Phần đọc cao của xử lý dự án thông thường gợi ý mạnh mẽ việc sử dụng Bản sao để giúp phân phối lưu lượng Đọc. Tôi đã đọc ở nơi khác rằng 1:10 RAM-GB đến HD-GB là một quy tắc tốt cho các đĩa chậm, Vì chúng tôi đang cân nhắc nghiêm túc về việc sử dụng SSD nhanh hơn nhiều, tôi muốn biết liệu có quy tắc tương tự không của ngón tay cái cho đĩa nhanh.

Tôi biết chúng ta đang sử dụng Mongo theo cách mà bộ nhớ cache - mọi thứ thực sự sẽ không hoạt động, đó là lý do tại sao tôi đang tìm cách để thiết kế một hệ thống có thể tồn tại trong việc sử dụng như vậy. Các toàn bộ dữ liệu có thể sẽ nhất của một lao trong vòng nửa năm và liên tục tăng.


Một câu hỏi khó cũng được hỏi.
gWaldo

Có vẻ như bạn có thể sẽ gặp phải các vấn đề về khóa ghi trước khi bạn có thể điều chỉnh IO thật nhiều. Nếu bạn đập DB bằng cách ghi, bạn có thể sẽ giữ các khóa ghi đủ lâu để các truy vấn sẽ bị đình trệ bất kể IO cơ bản nhanh đến mức nào. Một cái gì đó như Fusion IO có thể cắt giảm khóa ghi một chút, nhưng nó chỉ cần mua một chút thời gian, nó không phải là một sửa chữa thực sự.
MrKurt

@MrKurt Một phần của những gì tôi đang cố gắng tìm ra là khi tôi cần phân đoạn, ngoài việc tôi có thể tạo ra các nút sao chép riêng lẻ như thế nào. Thông số tạm thời của tôi không có thẻ SSD dựa trên PCIe.
sysadmin1138

À, hiểu rồi Bạn có thể xem xét shending ngay từ đầu, chúng tôi làm một máy chủ duy nhất rất nhiều. Nó cho phép bạn đi xung quanh khóa ghi và ghi hiệu quả ghi vào tổng số lõi của bạn. Thêm vào đó, thật dễ dàng để di chuyển các mảnh vỡ xung quanh giữa các máy chủ sau đó.
MrKurt

Câu trả lời:


5

Đây sẽ là một loạt các điểm nhỏ. Đáng buồn là không có câu trả lời duy nhất cho câu hỏi của bạn, tuy nhiên.

MongoDB cho phép nhân hệ điều hành quản lý bộ nhớ. Ngoài việc ném càng nhiều RAM càng tốt vào vấn đề, chỉ có một số điều có thể được thực hiện để 'chủ động quản lý' Bộ công việc của bạn.

Một điều mà bạn có thể làm để tối ưu hóa ghi là truy vấn đầu tiên cho bản ghi đó (đọc), để nó nằm trong bộ nhớ làm việc. Điều này sẽ tránh được các vấn đề về hiệu năng liên quan đến Khóa toàn cầu trên toàn quy trình (được cho là trở thành per-db trong phiên bản 2.2)

Không có quy tắc cứng và nhanh nào cho tỷ lệ RAM so với SSD, nhưng tôi nghĩ rằng IOPS thô của SSD sẽ cho phép bạn đi với tỷ lệ thấp hơn nhiều. Ngoài đỉnh đầu của tôi, 1: 3 có lẽ là mức thấp nhất bạn muốn đi cùng. Nhưng với chi phí cao hơn và năng lực thấp hơn, bạn có thể sẽ cần phải giữ tỷ lệ đó xuống.

Về 'Viết so với các giai đoạn Đọc', tôi có đọc chính xác rằng một khi bản ghi được viết, nó hiếm khi được cập nhật ("uperted") không? Nếu đó là trường hợp, nó có thể có giá trị để lưu trữ hai cụm; cụm ghi thông thường và cụm được tối ưu hóa đọc cho dữ liệu "đã cũ" chưa được sửa đổi trong [khoảng thời gian X] . Tôi chắc chắn sẽ cho phép đọc nô lệ trên cụm này. (Cá nhân, tôi sẽ quản lý điều đó bằng cách đưa giá trị được sửa đổi ngày vào tài liệu đối tượng db của bạn.)

Nếu bạn có khả năng kiểm tra tải trước khi vào Prod, hãy theo dõi hoàn hảo. MongoDB được viết với giả định rằng nó sẽ thường được triển khai trong các máy ảo (hệ thống tham chiếu của chúng ở EC2), vì vậy đừng ngại bỏ qua máy ảo.


Trong quá trình xử lý, một sơ khai tài liệu ban đầu được tạo và sau đó được cập nhật liên tục bởi các giai đoạn phụ khác nhau trong phần đầu tiên của quá trình xử lý. Chúng tôi đã cân nhắc khả năng thực hiện một số thao tác đệm tay trong lần tạo ban đầu để giảm số lượng gia hạn mà chúng tôi đang thực hiện, nhưng tỷ lệ khóa ghi hiện tại của chúng tôi rất thấp.
sysadmin1138

Lời khuyên để đọc một bản ghi trước khi viết cho nó để đưa nó vào RAM không phải là lời khuyên tốt. Kể từ 2.0 (giữa năm 2011) MongoDB đã cho năng suất nếu dữ liệu được truy cập không có trong RAM, do đó bạn chỉ gây ra thêm một lần đọc và thêm một chuyến đi tới máy chủ mà không có lý do chính đáng nếu bạn làm điều đó vì khóa sẽ không Dù sao cũng sẽ được tổ chức trong thời gian đó.
Asya Kamsky

13

Điều này được dự định như một phụ lục cho các câu trả lời khác được đăng ở đây, trong đó loại bỏ nhiều yếu tố liên quan được xem xét ở đây. Tuy nhiên, có một yếu tố khác, thường bị bỏ qua, khi nói đến việc sử dụng RAM hiệu quả trong một hệ thống loại truy cập ngẫu nhiên - readahead.

Bạn có thể kiểm tra các cài đặt hiện tại cho readahead (trên Linux) bằng cách chạy blockdev --report(thường yêu cầu đặc quyền sudo / root). Điều này sẽ in ra một bảng với một hàng cho mỗi thiết bị đĩa. Cột RA chứa giá trị cho readahead. Giá trị đó là số lượng các cung 512 byte (trừ khi kích thước cung không phải là mặc định - lưu ý rằng tại thời điểm viết bài này, ngay cả các đĩa có kích thước lớn hơn cũng được coi là các cung 512 byte) được đọc trên mọi truy cập đĩa.

Bạn có thể đặt cài đặt đọc cho một thiết bị đĩa nhất định bằng cách chạy:

blockdev --setra <value> <device name>

Khi sử dụng hệ thống RAID dựa trên phần mềm, đảm bảo đặt chế độ đọc trên mỗi thiết bị đĩa cũng như trên thiết bị tương ứng với bộ điều khiển RAID.

Sao nó lại quan trọng? Chà, readahead sử dụng cùng một tài nguyên mà MongoDB đang cố sử dụng để tối ưu hóa các lần đọc của bạn để truy cập tuần tự - RAM. Khi bạn thực hiện đọc tuần tự trên đĩa quay (hoặc thiết bị hoạt động giống như đĩa quay - EBS tôi đang nhìn bạn), việc tải dữ liệu gần đó vào RAM có thể tăng hiệu suất một cách ồ ạt, tiết kiệm cho bạn khi tìm kiếm và cài đặt chế độ đọc cao môi trường phù hợp có thể giúp bạn có một số kết quả ấn tượng.

Đối với một hệ thống như MongoDB, nơi truy cập của bạn thường là truy cập ngẫu nhiên trên một tập dữ liệu, điều này chỉ gây lãng phí bộ nhớ được sử dụng tốt hơn ở nơi khác. Hệ thống, như đã đề cập ở nơi khác cũng quản lý bộ nhớ cho MongoDB, sẽ phân bổ một đoạn bộ nhớ để đọc khi được yêu cầu và do đó để lại ít RAM hơn cho MongoDB sử dụng hiệu quả.

Chọn kích thước đọc chính xác là khó khăn và phụ thuộc vào phần cứng của bạn, cấu hình, kích thước khối, kích thước sọc và chính dữ liệu. Nếu bạn chuyển sang SSD chẳng hạn, bạn sẽ muốn có cài đặt thấp, nhưng mức độ thấp sẽ phụ thuộc vào dữ liệu.

Để giải thích: bạn muốn chắc chắn rằng readahead đủ cao để lấy một tài liệu đầy đủ và không phải quay lại đĩa. Hãy lấy kích thước trung bình được đề cập của bạn là 8k - vì các cung trên đĩa thường là 512 byte, nên sẽ có 16 lượt truy cập đĩa để đọc trong toàn bộ tài liệu mà không cần đọc. Nếu bạn có 16 trang đọc trở lên, bạn sẽ đọc trong toàn bộ tài liệu chỉ với một chuyến vào đĩa.

Trên thực tế, vì các nhóm chỉ mục MongoDB là 8k, nên bạn sẽ không bao giờ muốn đặt readahead dưới 16, hoặc sẽ mất 2 lần truy cập đĩa để đọc trong một nhóm chỉ mục. Một thực hành tốt chung là bắt đầu với cài đặt hiện tại của bạn, giảm một nửa, sau đó đánh giá lại mức sử dụng RAM và IO của bạn và tiếp tục từ đó.


1
Thông tin có giá trị chắc chắn sẽ có ích khi chúng ta có một số phần cứng trong nhà. Cảm ơn!
sysadmin1138

3

Bạn nên cân nhắc sử dụng bản sao cho các truy vấn của người dùng cuối và thực hiện quy trình công việc của bạn trên các máy khác.

Sử dụng quy tắc 1:10 của bạn, bạn đang xem xét khoảng 128 GB RAM cho 1TB dung lượng đĩa; Mặc dù một số ổ SSD giá cả phải chăng ngày nay tuyên bố đạt> 60K IOPS, số lượng trong thế giới thực có thể khác nhau đôi chút, cũng như việc bạn có sử dụng RAID với ổ SSD của mình hay không, và nếu bạn có, thì thẻ RAID cũng cực kỳ quan trọng .

Tại thời điểm của bài đăng này, việc chuyển từ 128GB ram DDR3 ECC sang 256GB dường như là thêm khoảng 2000 đô la trên máy chủ Intel 1U và điều này sẽ mang lại cho bạn tỷ lệ 1: 5 với 1TB dữ liệu, mà tôi cảm thấy sẽ là một tỷ lệ thậm chí tốt hơn. Nếu bạn cần khối lượng công việc của mình hoàn thành nhanh nhất có thể, nhiều RAM hơn chắc chắn sẽ giúp ích, nhưng nó có thực sự cấp bách không?

Bạn cũng sẽ cần thực hiện một số điều chỉnh hệ thống tệp, chẳng hạn như "noatime, data = writBack, nobarrier" trên ext4 và bạn có thể cần thực hiện một số điều chỉnh cài đặt kernel cũng như để giảm hiệu suất cao nhất bạn có thể hệ thống.

Nếu bạn đang sử dụng RAID, RAID-10 sẽ là một lựa chọn khá tốt và với bộ điều khiển RAID thích hợp sẽ mang lại hiệu suất khá cao, nhưng giảm một nửa không gian có sẵn của bạn. Bạn cũng có thể xem xét RAID50 nếu bạn muốn tăng hiệu suất tốt mà không giảm một nửa dung lượng có sẵn. Rủi ro của việc chạy RAID là bạn không còn có quyền truy cập vào TRIM trên các ổ đĩa của mình, điều đó có nghĩa là thỉnh thoảng bạn cần di chuyển dữ liệu của mình ra, phá vỡ RAID, TRIM các ổ đĩa và tạo lại RAID.

Cuối cùng, bạn cần quyết định mức độ phức tạp bạn muốn, số tiền bạn muốn chi tiêu và mức độ nhanh chóng bạn muốn khối lượng công việc của bạn được xử lý. Tôi cũng sẽ đánh giá xem MongoDB có phải là cơ sở dữ liệu lý tưởng để sử dụng hay không, vì bạn vẫn có thể sử dụng Mongo cho các truy vấn của người dùng cuối cần phản hồi nhanh, nhưng sử dụng một cái gì đó khác để xử lý dữ liệu của bạn, không cần phải sẵn sàng trong vài giây và nó cũng có thể cho phép bạn phân bổ khối lượng công việc của mình trên nhiều máy dễ dàng hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.