2013-03-01 33 views
24

Đây là câu hỏi đầu tiên chính thức của tôi ở đây; Tôi hoan nghênh bất kỳ/tất cả những lời chỉ trích của bài viết của tôi để tôi có thể tìm hiểu làm thế nào để trở thành một công dân SO tốt hơn.So sánh MongoDB và Hiệu ứng Chèn số lượng lớn RethinkDB

Tôi đang kiểm tra DBMS phi quan hệ để lưu trữ danh sách chọn không tham gia email có khả năng lớn, nghiêng về MongoDB hoặc RethinkDB, sử dụng thư viện máy khách Python tương ứng. Điểm đau của ứng dụng của tôi là hiệu suất chèn số lượng lớn, vì vậy tôi đã thiết lập hai kịch bản Python để chèn 20.000 bản ghi theo lô 5.000 vào cả một MongoDB và một bộ sưu tập RethinkDB.

Các MongoDB python script mongo_insert_test.py:

NUM_LINES = 20000 
BATCH_SIZE = 5000 

def insert_records(): 
    collection = mongo.recips 
    i = 0 
    batch_counter = 0 
    batch = [] 
    while i <= NUM_LINES: 
     i += 1 
     recip = { 
      'address': "test%[email protected]%d.com" % (i, i) 
     } 
     if batch_counter <= BATCH_SIZE: 
      batch.append(recip) 
      batch_counter += 1 
     if (batch_counter == BATCH_SIZE) or i == NUM_LINES: 
      collection.insert(batch) 
      batch_counter = 0 
      batch = [] 

if __name__ == '__main__': 
    insert_records() 

Các gần như giống hệt RethinkDB python script rethink_insert_test.py:

NUM_LINES = 20000 
BATCH_SIZE = 5000 

def insert_records(): 
    i = 0 
    batch_counter = 0 
    batch = [] 
    while i <= NUM_LINES: 
     i += 1 
     recip = { 
      'address': "test%[email protected]%d.com" % (i, i) 
     } 
     if batch_counter <= BATCH_SIZE: 
      batch.append(recip) 
      batch_counter += 1 
     if (batch_counter == BATCH_SIZE) or i == NUM_LINES: 
      r.table('recip').insert(batch).run() 
      batch_counter = 0 
      batch = [] 

if __name__ == '__main__': 
    insert_records() 

Trong môi trường dev của tôi, kịch bản MongoDB chèn 20.000 bản ghi trong dưới một thứ hai:

$ time python mongo_insert_test.py 
real 0m0.618s 
user 0m0.400s 
sys  0m0.032s 

Trong cùng một môi trường, R tập lệnh ethinkDB hoạt động chậm hơn nhiều, chèn 20.000 bản ghi trong hơn 2 phút:

$ time python rethink_insert_test.py 
real 2m2.502s 
user 0m3.000s 
sys  0m0.052s 

Tôi có thiếu thứ gì đó lớn ở đây liên quan đến cách hai DBMS này hoạt động không? Tại sao RethinkDB hoạt động quá tệ với thử nghiệm này?

Máy tính của tôi có bộ nhớ khả dụng khoảng 1,2 GB cho các thử nghiệm này.

+5

Tiêu đề nói tất cả;) http://www.rethinkdb.com/blog/the-benchmark-youre-reading-is-probably-wrong/ –

+0

@FabianoPS, tôi đã không thực sự nhắm đến bất kỳ điều gì khoa học ở đây ; chỉ cần tự hỏi tại sao nó mất một đơn đặt hàng của cường độ nhiều thời gian hơn để làm các hoạt động tương tự trong suy nghĩ lại như MongoDB. Tôi không tin rằng độ trễ mạng/đĩa đóng nhiều vai trò (nếu có). Suy nghĩ lại đã xuất bản bản cập nhật giải quyết vấn đề này theo cách có ý nghĩa (không hời hợt). – njyunis

+0

Hi @njyunis, bài viết này rất thú vị trong thông điệp cốt lõi của nó: có rất nhiều giải thích tốc độ viết, đây không phải là câu trả lời –

Trả lời

46

RethinkDB hiện đang thực hiện chèn hàng loạt bằng cách thực hiện chèn một lần tại một thời điểm trên máy chủ. Kể từ khi suy nghĩ lại tuôn ra mỗi bản ghi vào đĩa (vì nó được thiết kế với sự an toàn đầu tiên trong tâm trí), điều này có tác động thực sự xấu đến khối lượng công việc như thế này.

Chúng tôi đang làm hai việc đến địa chỉ này:

  1. chèn số lượng lớn sẽ được thực hiện thông qua một thuật toán chèn số lượng lớn trên máy chủ để tránh làm một chèn vào một thời điểm.
  2. Chúng tôi sẽ cung cấp cho bạn tùy chọn để thư giãn các hạn chế về độ bền để cho phép bộ nhớ cache hấp thụ chèn thông lượng cao nếu bạn muốn (để đổi lấy việc không đồng bộ hóa với đĩa thường xuyên).

Điều này hoàn toàn sẽ được sửa trong 4-12 tuần (và nếu bạn cần ASAP này, vui lòng gửi email cho tôi tới [email protected] và tôi sẽ xem chúng tôi có thể tái cấp phép) hay không.

Dưới đây là những vấn đề có liên quan github:

https://github.com/rethinkdb/rethinkdb/issues/207

https://github.com/rethinkdb/rethinkdb/issues/314

Hope this helps. Xin đừng ngần ngại gửi cho chúng tôi nếu bạn cần trợ giúp.

+0

Cảm ơn @coffeemug, câu trả lời này cho câu hỏi của tôi. Tôi sẽ theo dõi github vì vậy tôi biết khi nào điều này đã được giải quyết, vì tôi rất vui khi thử lại Rethink. – njyunis

+4

@njyunis: 1.5 gần đây đã xuất hiện với chèn số lượng lớn nhanh hơn: http://rethinkdb.com/blog/1.5-release/. –

6

Gác lại những gì coffemug gửi:

  1. tùy thuộc vào những gì phiên bản bạn đang dùng driver và cách bạn cấu hình các kết nối đến MongoDB, những chèn có thể thậm chí không được công nhận bởi các máy chủ. Nếu bạn đang sử dụng phiên bản mới nhất của trình điều khiển Python, các hoạt động đó đang chờ đợi một xác nhận nhận từ máy chủ (điều đó không có nghĩa là dữ liệu đó đã được ghi vào bộ nhớ). Để biết thêm chi tiết về những gì tôi đang đề cập đến, hãy xem Mongodb write concern setting

  2. bạn có thể tăng tốc độ trong trường hợp Rethinkdb bằng cách song song các phụ trang. Về cơ bản nếu bạn chạy nhiều quy trình/chủ đề, bạn sẽ thấy tốc độ tăng lên. Trong trường hợp của Mongo, do các khóa liên quan, song song sẽ không giúp đỡ.

Điều đó đang được nói, RethinkDB có thể cải thiện tốc độ ghi.

PS: Tôi đang làm việc để suy nghĩ lại, nhưng các điểm trên được dựa trên kiến ​​thức không thiên vị của tôi về cả hai hệ thống.

+0

Song song với pymongo cũng nên có một số cải tiến khi thời gian trên dây sẽ chặn ít hơn. – Ross

+1

Tôi sẽ cập nhật kịch bản thử nghiệm mongo của mình để sử dụng MongoClient thay vì giải quyết vấn đề này. Tôi sẽ chỉnh sửa bài đăng của mình khi tôi đã có cơ hội thực hiện việc này. – njyunis

4

Nhà phát triển Pymongo ở đây - chỉ trong trường hợp bạn không làm như vậy, hãy đảm bảo rằng bạn đang sử dụng phiên bản pymongo mới nhất và MongoClient hoặc MongoRepicaSetClient để ghi của bạn được ghi nhận và không kích hoạt. Như @ Alex nói, họ sẽ rất có thể là những gì bạn yêu cầu.

Các cân nhắc khác tôi có thể là: đây có phải là trường hợp sử dụng chính cho cơ sở dữ liệu hay chỉ là điểm đau lõi? Bạn có thể muốn xem xét các mẫu dữ liệu khác, truy vấn dữ liệu, dễ sử dụng và bảo trì trước khi đưa ra quyết định của mình.

+1

Vâng, tôi nhận ra rằng sau khi tôi đã làm bài kiểm tra mà tôi đã sử dụng một máy khách mong muốn khá lạc hậu; cảm ơn vì đã chỉ ra điều đó. Tôi đang sử dụng một Postgres db cho các công cụ quan hệ Django và nosql để lưu trữ danh sách email, với việc nhập (chèn số lượng lớn) và chà (một số loại bản đồ/giảm so sánh danh sách) là hai trường hợp sử dụng chính cho db nosql. – njyunis

0

Hãy tha thứ cho sự tương tự - tuy nhiên nó làm cho điểm của tôi trở nên rõ ràng.

Không tốn nhiều thời gian để khóa một thứ có giá trị trong két an toàn, nhưng hãy thực hiện hàng nghìn lần theo ý muốn. Thay vào đó, nếu bạn đăng lên hầm của ngân hàng, hãy xem xét thời gian bạn có giá trị không an toàn trong chuyến đi đến ngân hàng của bạn; bưu kiện đó có lẽ sẽ được chất đống với nhiều bưu kiện khác - từ người gửi tiền có cùng tư duy. Một người nào đó sẽ nhận được vòng để mở bưu kiện của bạn, và sau đó chồng nó với những thứ khác được đặt trong một hầm an toàn.

Trong đó có sự khác biệt giữa các cam kết thông thường của dữ liệu vào đĩa và trộn hoặc ghi dữ liệu lười biếng vào đĩa. Đó là một sự cân bằng giữa tính toàn vẹn dữ liệu cao hơn và cải thiện hiệu suất ghi. Nếu mất dữ liệu không quan trọng quá nhiều, thì nó hoàn toàn chấp nhận được để đồng bộ với đĩa ít thường xuyên hơn, hàng loạt hoặc lười biếng viết cập nhật. Làm cho sự lựa chọn sai sẽ cắn bạn trong bum một ngày, do đó, chọn một cách khôn ngoan!

Các vấn đề liên quan