Điều gì xảy ra nếu có quá nhiều phần chèn trong MongoDB? Làm thế nào để đảm bảo tất cả dữ liệu được lưu trữ?


24

Tôi sử dụng MongoDB để lưu trữ các giá trị đo định kỳ. Mỗi ~ 100 ms một loạt các giá trị được chèn dưới dạng tài liệu. Nó hoạt động tốt, nhưng tôi lo lắng về các vấn đề hiệu suất. (Tôi sử dụng các chèn an toàn, có vẻ như trong PyMongo, đây là mặc định.)

Điều gì xảy ra nếu có nhiều chèn mỗi giây hơn mongod có thể lưu vào đĩa cứng? Sẽ có bất kỳ cảnh báo hay đơn giản là nó sẽ thất bại trong âm thầm?

Có phương pháp nào để theo dõi tải ghi không? Tôi chỉ tìm thấy db.serverStatus().writeBacksQueuedcái luôn được đặt thành false khi tôi gọi nó. Làm thế nào tôi có thể kiểm tra bao nhiêu dữ liệu tôi phải chèn để điền vào hàng đợi ghi?

mongostathiển thị ổ khóa. Đây có phải là điều tôi nên lo lắng?

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
  *117     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:6.5%          0       0|0     0|0   124b     6k     2  SLV   09:58:10 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:0.8%          0       0|0     0|0   124b     6k     2  SLV   09:58:11 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:4.2%          0       0|0     0|0   124b     6k     2  SLV   09:58:1

Tôi có phải lo lắng về khóa viết không? Điều gì xảy ra với một chèn trong khoảng thời gian ghi bị khóa? Có phải nó được xếp hàng và lưu trữ sau này không?

Tôi đang suy nghĩ về một thiết lập sao chép đơn giản bằng cách sử dụng một chủ và một nô lệ. Đồng bộ hóa ban đầu hoặc quá trình đồng bộ hóa có khóa cơ sở dữ liệu không?

(Tôi đang sử dụng phiên bản 2.4.3.)

Cập nhật: Tôi nghĩ rằng đã phần nào trả lời câu hỏi của riêng tôi. Tôi đã quản lý để có được tới 12.000 lần chèn mỗi giây bằng cách sử dụng một vòng lặp đơn giản trong khi chèn một tài liệu thử nghiệm nhỏ. Nhưng qr | qw vẫn cho thấy rằng có hàng đợi đọc và ghi vẫn trống:

insert  query update delete getmore command flushes mapped  vsize    res faults       locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
 11234     *0      2     *0    1563     1|0       1  21.9g  44.3g  1.22g      0    testdb:58.9%          0       1|0     1|1   797k   980k     6  PRI   10:26:32 
 12768     *0      2     *0    1284     1|0       0  21.9g  44.3g  1.22g      0    testdb:58.0%          0       0|0     0|1   881k     1m     6  PRI   10:26:33 
 12839     *0      2     *0    1231     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.3%          0       0|0     0|1   883k     1m     6  PRI   10:26:34 
 12701     *0      2     *0     910     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   858k     1m     6  PRI   10:26:35 
 12241     *0      2     *0    1206     1|0       0  21.9g  44.3g  1.22g      0    testdb:56.7%          0       0|0     0|0   843k     1m     6  PRI   10:26:36 
 11581     *0      2     *0    1406     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   811k     1m     6  PRI   10:26:37 
  8719     *0      2     *0    1210     1|0       0  21.9g  44.3g  1.22g      0    testdb:43.8%          0       0|0     0|1   618k   762k     6  PRI   10:26:38 
 11429     *0      2     *0    1469     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.6%          0       0|0     0|1   804k   993k     6  PRI   10:26:39 
 12779     *0      2     *0    1092     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.2%          0       1|0     0|1   872k     1m     6  PRI   10:26:40 
 12757     *0      2     *0     436     1|0       0  21.9g  44.3g  1.22g      0    testdb:59.7%          0       0|0     0|1   838k   432k     6  PRI   10:26:41 

Tôi cho rằng điều này có nghĩa là việc chèn một mình sẽ không gây ra nhiều rắc rối: "Hàng đợi sẽ có xu hướng tăng đột biến nếu bạn thực hiện nhiều thao tác ghi cùng với các thao tác ghi nặng khác, chẳng hạn như xóa khoảng cách lớn." (tìm thấy ở đây ]

Câu hỏi mở của tôi: Điều gì xảy ra với dữ liệu của tôi nếu hàng đợi ghi tăng lên trong dài hạn?

Câu trả lời:


25

Bạn đã trả lời một số câu hỏi của riêng bạn ở đây, cụ thể là bạn có một ý tưởng hay về khía cạnh khóa ghi của phương trình - 12.000 chèn / giây giúp bạn đạt ~ 60% khóa ghi. Đó là mức hợp lý để có được hiệu suất ổn định - bạn sẽ có một số tranh cãi, và một số op sẽ chậm hơn một chút, nhưng bạn thực sự muốn bắt đầu lo lắng ở khoảng 80% - giống như rất nhiều thứ, khi bạn bắt đầu vượt quá 80% năng lực bạn sẽ bắt đầu đánh các vấn đề thường xuyên hơn nhiều.

Xét về các tắc nghẽn khác và cụ thể là bạn có thể ghi vào đĩa nhanh như thế nào - điều này có thể gây ra sự cố, nhưng để xem các số liệu thống kê có liên quan theo thời gian, tôi khuyên bạn nên cài đặt MMS với plugin nút munin để cung cấp cho bạn số liệu thống kê về phần cứng và IO ngoài các số liệu thống kê MongoDB.

Khi bạn có điều đó, các số liệu bạn sẽ muốn để mắt đến là:

  • Thời gian xả trung bình (đây là thời gian đồng bộ hóa định kỳ vào đĩa của MongoDB)
  • Các IOStats trong tab phần cứng (đặc biệt là IOWait)
  • Lỗi trang (nếu đĩa của bạn bận ghi và bạn cần đọc dữ liệu, chúng sẽ cạnh tranh để có nguồn tài nguyên khan hiếm)

Sau đó thì hơi phức tạp, nhưng đây là một ý tưởng cơ bản:

  • Khi thời gian xả trung bình bắt đầu tăng, hãy lo lắng
  • Nếu nó rơi vào phạm vi nhiều giây, có lẽ bạn đang ở giới hạn (mặc dù điều này phụ thuộc vào khối lượng dữ liệu được ghi và tốc độ đĩa)
  • Nếu nó đạt đến 60 giây, bạn sẽ thấy hiệu suất giảm sút nghiêm trọng (việc xả nước diễn ra cứ sau 60 giây, do đó về cơ bản họ sẽ xếp hàng)
  • IOWait cao cũng sẽ cản trở hiệu suất, đặc biệt là nếu bạn phải đọc từ đĩa bất cứ lúc nào
  • Do đó, nhìn vào mức độ lỗi trang cũng sẽ rất quan trọng

Một mảnh khác của câu đố này, mà chúng tôi chưa đề cập, là tạp chí. Đó cũng sẽ là dữ liệu lưu vào đĩa (theo mặc định cứ sau 100ms) và do đó, nó sẽ được thêm vào tải của đĩa nếu nó ở cùng một ổ đĩa. Do đó, nếu bạn đang thấy mức độ sử dụng đĩa cao, thì việc chuyển tạp chí sang đĩa khác sẽ là một ý kiến ​​hay.

Không có "số ma thuật" thực sự nào ở dưới, trong hầu hết các trường hợp đều là tương đối, vì vậy hãy có một đường cơ sở tốt cho lưu lượng truy cập bình thường của bạn, kiểm tra xem liệu mọi thứ có đang có xu hướng không và có thể tải thử nghiệm để xem giới hạn của bạn là gì và khi nào mọi thứ bắt đầu xuống cấp và bạn sẽ ở trong tình trạng tốt

Sau tất cả những điều đó, trước một số câu hỏi của bạn:

Điều gì xảy ra nếu có nhiều chèn mỗi giây hơn mongod có thể lưu vào đĩa cứng? Sẽ có bất kỳ cảnh báo hay đơn giản là nó sẽ thất bại trong âm thầm?

Nếu bạn bắt đầu nhấn mạnh đĩa đến các mức được mô tả ở trên, cuối cùng mọi thứ sẽ chậm lại và đến một lúc nào đó (và điều này sẽ phụ thuộc vào thời gian chờ, phần cứng của bạn mạnh như thế nào, cách bạn xử lý ngoại lệ) việc ghi của bạn sẽ thất bại - nếu bạn đang sử dụng một phiên bản gần đây của pymongo thì bạn sẽ sử dụng ghi an toàn theo mặc định và sau đó chúng sẽ thất bại. Nếu bạn muốn hoang tưởng hơn một chút, đôi khi bạn có thể thực hiện một mối quan tâm bằng văn bản của j: true sẽ chờ để trả lại OK cho đến khi ghi được ghi vào nhật ký (tức là trên đĩa). Tất nhiên, điều này sẽ chậm hơn so với ghi an toàn thông thường, nhưng nó sẽ là dấu hiệu tức thời cho các vấn đề liên quan đến dung lượng ổ đĩa và bạn có thể sử dụng nó để chặn / xếp hàng các hoạt động khác và về cơ bản hoạt động như một bộ điều tiết để ngăn chặn cơ sở dữ liệu của bạn choáng ngợp.

Tôi đang suy nghĩ về một thiết lập sao chép đơn giản bằng cách sử dụng một chủ và một nô lệ. Đồng bộ hóa ban đầu hoặc quá trình đồng bộ hóa có khóa cơ sở dữ liệu không?

Tôi nghĩ rằng tôi đã bao gồm khóa tổng thể khi bắt đầu, nhưng để trả lời cụ thể phần này: Đầu tiên, hãy chắc chắn rằng bạn đang sử dụng một bộ bản sao , không phải chủ / nô lệ. Việc thực hiện chủ / nô lệ không được chấp nhận và không được khuyến khích sử dụng nói chung. Đối với đồng bộ hóa ban đầu sẽ thêm một số tải vào chính về mặt đọc, nhưng không phải về mặt ghi, vì vậy bạn sẽ ổn về mặt khóa.

Điều gì xảy ra với dữ liệu của tôi nếu hàng đợi ghi tăng lên trong dài hạn?

Như bạn có thể nói từ lời giải thích ở trên, câu trả lời phụ thuộc rất nhiều vào cách bạn viết đơn, cách bạn chọn để bài viết của bạn được công nhận và bạn có bao nhiêu năng lực. Về cơ bản, bạn có thể an toàn như bạn muốn khi ghi vào đĩa trên MongoDB, nhưng có một sự đánh đổi hiệu năng, như đã đề cập với j:truecuộc thảo luận ở trên.

Nói chung, bạn muốn tìm ra yếu tố giới hạn của mình - có thể là khóa, tốc độ ổ đĩa, v.v.

Một điều cuối cùng, db.serverStatus().writeBacksQueuedthực sự là một số liệu sẽ chỉ là khác không trong môi trường bị phân mảnh, và nó phải làm với việc đảm bảo rằng việc ghi vào một đoạn trong quá trình di chuyển được xử lý một cách thích hợp (được xử lý bởi người nghe viết lại ). Do đó về cơ bản nó là cá trích đỏ ở đây - không liên quan gì đến khối lượng ghi chung.

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.