Redis nhanh hơn bao nhiêu so với mongoDB?


204

Nó được đề cập rộng rãi rằng Redis là "Blazed Fast" và mongoDB cũng nhanh. Nhưng, tôi gặp khó khăn khi tìm số thực tế so sánh kết quả của hai. Với các cấu hình, tính năng và hoạt động tương tự (và có thể cho thấy hệ số thay đổi như thế nào với các cấu hình và hoạt động khác nhau), v.v., Redis có nhanh hơn gấp 10 lần, nhanh hơn gấp 2 lần không?

Tôi CHỈ nói về hiệu suất. Tôi hiểu rằng mongoDB là một công cụ khác và có bộ tính năng phong phú hơn. Đây không phải là cuộc tranh luận "Là mongoDB tốt hơn Redis". Tôi đang hỏi, bằng cách nào Redis vượt trội hơn mongoDB?

Tại thời điểm này, ngay cả điểm chuẩn giá rẻ vẫn tốt hơn so với không có điểm chuẩn.


10
Điểm chuẩn giá rẻ luôn tốt hơn so với không có điểm chuẩn. Cảm ơn bạn đã hỏi.
Maziyar

2
Nói chung, quan tâm đến sự khác biệt giữa 5.000 ops / giây và 10.000 ops / giây thường là một trường hợp tối ưu hóa sớm. Điều đó nói rằng, nó vẫn là một câu trả lời thú vị :)
Kevin

Câu trả lời:


238

Kết quả thô từ điểm chuẩn sau: viết 2x, đọc 3x .

Đây là một điểm chuẩn đơn giản trong python mà bạn có thể thích ứng với mục đích của mình, tôi đã xem xét mỗi cái sẽ thực hiện tốt như thế nào chỉ đơn giản là thiết lập / truy xuất các giá trị:

#!/usr/bin/env python2.7
import sys, time
from pymongo import Connection
import redis

# connect to redis & mongodb
redis = redis.Redis()
mongo = Connection().test
collection = mongo['test']
collection.ensure_index('key', unique=True)

def mongo_set(data):
    for k, v in data.iteritems():
        collection.insert({'key': k, 'value': v})

def mongo_get(data):
    for k in data.iterkeys():
        val = collection.find_one({'key': k}, fields=('value',)).get('value')

def redis_set(data):
    for k, v in data.iteritems():
        redis.set(k, v)

def redis_get(data):
    for k in data.iterkeys():
        val = redis.get(k)

def do_tests(num, tests):
    # setup dict with key/values to retrieve
    data = {'key' + str(i): 'val' + str(i)*100 for i in range(num)}
    # run tests
    for test in tests:
        start = time.time()
        test(data)
        elapsed = time.time() - start
        print "Completed %s: %d ops in %.2f seconds : %.1f ops/sec" % (test.__name__, num, elapsed, num / elapsed)

if __name__ == '__main__':
    num = 1000 if len(sys.argv) == 1 else int(sys.argv[1])
    tests = [mongo_set, mongo_get, redis_set, redis_get] # order of tests is significant here!
    do_tests(num, tests)

Kết quả với mongodb 1.8.1 và redis 2.2.5 và pymongo / redis-py mới nhất:

$ ./cache_benchmark.py 10000
Completed mongo_set: 10000 ops in 1.40 seconds : 7167.6 ops/sec
Completed mongo_get: 10000 ops in 2.38 seconds : 4206.2 ops/sec
Completed redis_set: 10000 ops in 0.78 seconds : 12752.6 ops/sec
Completed redis_get: 10000 ops in 0.89 seconds : 11277.0 ops/sec

Lấy kết quả với một hạt muối tất nhiên! Nếu bạn đang lập trình bằng ngôn ngữ khác, sử dụng các ứng dụng khách / triển khai khác, v.v. thì kết quả của bạn sẽ thay đổi. Chưa kể cách sử dụng của bạn sẽ hoàn toàn khác! Đặt cược tốt nhất của bạn là tự đánh giá chúng, chính xác theo cách bạn đang có ý định sử dụng chúng. Như một hệ quả tất yếu, bạn có thể sẽ tìm ra cách tốt nhất để sử dụng từng cái. Luôn luôn chuẩn cho chính mình!


3
Thật đáng để nhận xét rằng MongoDB và Redis có các cấu trúc bền vững khác nhau và Redis chỉ hỗ trợ một lược đồ dữ liệu có thể phù hợp với bộ nhớ. Mặc dù ram rẻ, nhưng nếu bạn cần sử dụng / lưu trữ hơn 12-16GB dữ liệu, tôi sẽ thấy các tùy chọn máy chủ của bạn trông như thế nào.
Tracker1

53
@sivann bài đăng này đi từ không có điểm chuẩn đến điểm chuẩn "thô" được nêu rõ ràng. Đừng trở thành một kẻ troll với "điểm chuẩn là sai lầm" vô nghĩa. Tất nhiên các điều kiện khác nhau có thể thay đổi kết quả. Thay vào đó, hãy đóng góp lại và gửi điểm chuẩn của bạn để kiểm tra trường hợp của bạn và liên kết từ bài đăng này, sau đó tất cả chúng ta sẽ được hưởng lợi từ ý kiến ​​"đã kiểm tra" của bạn.
Homer6

2
@sivann Cấu hình (giao hàng) mặc định là những gì điểm chuẩn này đã được kiểm tra. IMHO, cấu hình mặc định xác định phía nào của hàng rào fsync mà gói nằm ở. Đối với Redis, nó được quảng cáo là máy chủ bộ nhớ khuyến khích mọi người sử dụng các lựa chọn thay thế khác khi cơ sở dữ liệu lớn hơn tổng bộ nhớ hệ thống. Đối với MongoDB, nó được quảng cáo là cơ sở dữ liệu. Postgres sẽ không bao giờ tắt fsync vì rõ ràng họ đang ở trong trại kiên trì. Hầu hết mọi người không sửa đổi cấu hình, vì vậy điểm chuẩn này có phần chính xác cho những trường hợp đó.
Homer6

4
Tôi đồng ý với @sivann, điểm chuẩn bạn đã đăng là thiếu sót nghiêm trọng . MongoDB là đa luồng và Redis thì không. Nếu điểm chuẩn của bạn là đa luồng, bạn sẽ thấy MongoDb thực sự có thông lượng cao hơn trên máy đa lõi.
ColinM

2
@ Homer6 ngay cả đối với DB hướng bộ nhớ, bạn nên kiểm tra với tính năng WriteConcern được bật (mặc định bị tắt). Kiểm tra mà không thực sự vô nghĩa đối với bất kỳ loại điểm chuẩn. Tương tự cho reddis. Các DB không đồng bộ hóa trên đĩa tất cả các giao dịch, duy trì sự an toàn bằng cách sao chép dữ liệu vào ít nhất 2 máy chủ. Điều đó có nghĩa là ghi của bạn không chờ đồng bộ hóa đĩa, nhưng để sao chép mạng trước khi quay lại. Không chờ lỗi là điều không bao giờ được thực hiện trên prod. như không phát hiện nếu cáp mạng được kết nối khi ghi vào mạng.
sivann

18

Vui lòng kiểm tra bài đăng này về phân tích hiệu suất chèn Redis và MongoDB:

Lên đến 5000 mục mongodb $ đẩy nhanh hơn ngay cả khi so sánh với Redis RPUSH, sau đó nó trở nên cực kỳ chậm, có lẽ kiểu mảng mongodb có thời gian chèn tuyến tính và do đó nó trở nên chậm hơn và chậm hơn. mongodb có thể đạt được một chút hiệu suất bằng cách hiển thị loại danh sách chèn thời gian không đổi, nhưng ngay cả với loại mảng thời gian tuyến tính (có thể đảm bảo tra cứu thời gian liên tục), nó có các ứng dụng cho các bộ dữ liệu nhỏ.


15

Điểm chuẩn tốt và đơn giản

Tôi đã cố gắng tính toán lại các kết quả một lần nữa bằng cách sử dụng các phiên bản hiện tại của redis (2.6.16) và mongo (2.4.8) và đây là kết quả

Completed mongo_set: 100000 ops in 5.23 seconds : 19134.6 ops/sec
Completed mongo_get: 100000 ops in 36.98 seconds : 2703.9 ops/sec
Completed redis_set: 100000 ops in 6.50 seconds : 15389.4 ops/sec
Completed redis_get: 100000 ops in 5.59 seconds : 17896.3 ops/sec

Ngoài ra bài đăng blog này so sánh cả hai nhưng sử dụng node.js. Nó cho thấy hiệu quả của việc tăng số lượng mục trong cơ sở dữ liệu cùng với thời gian.


8

Các con số sẽ khó tìm thấy vì cả hai không hoàn toàn trong cùng một không gian. Câu trả lời chung là Redis nhanh hơn 10 - 30% khi bộ dữ liệu vừa với bộ nhớ làm việc của một máy. Khi lượng dữ liệu đó bị vượt quá, Redis thất bại. Mongo sẽ chậm lại với số lượng tùy thuộc vào loại tải. Đối với loại tải chỉ chèn, một người dùng gần đây đã báo cáo sự chậm lại từ 6 đến 7 đơn hàng cường độ (10.000 đến 100.000 lần) nhưng báo cáo đó cũng thừa nhận rằng có vấn đề về cấu hình và đây là tải làm việc rất không điển hình. Bình thường đọc tải nặng giai thoại chậm khoảng 10 lần khi một số dữ liệu phải được đọc từ đĩa.

Kết luận: Redis sẽ nhanh hơn nhưng không nhiều.


7

Dưới đây là một bài viết tuyệt vời về hiệu suất phiên trong khung Tornado khoảng 1 tuổi. Nó có một so sánh giữa một vài triển khai khác nhau, trong đó bao gồm Redis và MongoDB. Biểu đồ trong bài viết nói rằng Redis đứng sau MongoDB khoảng 10% trong trường hợp sử dụng cụ thể này.

Redis đi kèm với một điểm chuẩn tích hợp sẽ phân tích hiệu suất của máy bạn đang sử dụng. Có rất nhiều dữ liệu thô từ nó tại wiki Điểm chuẩn cho Redis. Nhưng bạn có thể phải nhìn xung quanh một chút cho Mongo. Giống như ở đây , ở đây và một số số đánh bóng ngẫu nhiên (nhưng nó cung cấp cho bạn một điểm khởi đầu để tự chạy một số điểm chuẩn MongoDB).

Tôi tin rằng giải pháp tốt nhất cho vấn đề này là tự mình thực hiện các bài kiểm tra trong các loại tình huống bạn mong đợi.


Các điểm chuẩn Tornado phù hợp tốt với các thử nghiệm của riêng tôi khi sử dụng Redis và MongoDb làm phụ trợ Zend_Cache. Chức năng phong phú hơn của MongoDb cho phép bạn sử dụng ít yêu cầu hơn và quy mô thiết kế đa luồng tốt hơn nhiều so với quy trình Redis duy nhất không đa luồng. Kết luận là MongoDb quy mô cao hơn. Ngoài ra, Redis không còn hỗ trợ bộ nhớ ảo.
ColinM

3

Trong trường hợp của tôi, yếu tố quyết định trong so sánh hiệu năng, là MongoDb WriteConcern được sử dụng. Hầu hết các trình điều khiển mongo hiện nay sẽ đặt WriteConcern mặc định thành ACKNOWLEDGED, có nghĩa là 'được ghi vào RAM' ( Mongo2.6.3-WriteConcern ), về mặt đó, nó rất giống với redis cho hầu hết các hoạt động ghi.

Nhưng thực tế là tùy thuộc vào nhu cầu ứng dụng của bạn và thiết lập môi trường sản xuất, bạn có thể muốn thay đổi mối quan tâm này thành WriteConcern.JOURNALED (được ghi vào oplog) hoặc WriteConcern.FSYNCED (ghi vào đĩa) hoặc thậm chí được ghi vào bộ sao chép (sao lưu) Nếu cần thiết.

Sau đó, bạn có thể bắt đầu thấy một số hiệu suất giảm. Các yếu tố quan trọng khác cũng bao gồm, cách tối ưu hóa các mẫu truy cập dữ liệu của bạn, chỉ số bỏ qua% (xem bộ điều chỉnh ) và các chỉ mục nói chung.


0

Tôi nghĩ rằng 2-3X trên điểm chuẩn hiển thị là sai lệch, vì nếu bạn cũng phụ thuộc vào phần cứng bạn chạy nó - theo kinh nghiệm của tôi, máy 'càng mạnh' thì khoảng cách càng lớn (nghiêng về Redis) sẽ, có lẽ bởi thực tế là điểm chuẩn đạt đến giới hạn bộ nhớ khá nhanh.

Đối với dung lượng bộ nhớ - điều này đúng một phần, vì cũng có nhiều cách để giải quyết vấn đề đó, có những sản phẩm (thương mại) ghi lại dữ liệu Redis vào đĩa và cả các giải pháp cụm (đa phân đoạn) vượt qua kích thước bộ nhớ hạn chế.

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.