Trong bài đăng này, chúng tôi sẽ so sánh hai trong số các cơ sở dữ liệu NoSQL phổ biến nhất:Redis (trong bộ nhớ) và MongoDB (công cụ lưu trữ bộ nhớ Percona).
Redis là một kho lưu trữ cấu trúc cơ sở dữ liệu trong bộ nhớ phổ biến và rất nhanh, chủ yếu được sử dụng làm bộ nhớ đệm hoặc môi giới thông báo. Ở trong bộ nhớ, đó là nơi lưu trữ dữ liệu được lựa chọn khi thời gian phản hồi vượt trội so với mọi thứ khác.
MongoDB là một kho lưu trữ tài liệu trên đĩa cung cấp giao diện JSON cho dữ liệu và có ngôn ngữ truy vấn rất phong phú. Được biết đến với tốc độ, hiệu quả và khả năng mở rộng, nó hiện là cơ sở dữ liệu NoSQL phổ biến nhất được sử dụng hiện nay. Tuy nhiên, là cơ sở dữ liệu trên đĩa, nó không thể so sánh thuận lợi với cơ sở dữ liệu trong bộ nhớ như Redis về hiệu suất tuyệt đối. Tuy nhiên, với sự sẵn có của các công cụ lưu trữ trong bộ nhớ cho MongoDB, việc so sánh trực tiếp hơn trở nên khả thi.
Công cụ bộ nhớ Percona cho MongoDB
Bắt đầu từ phiên bản 3.0, MongoDB cung cấp một API để cắm vào công cụ lưu trữ mà bạn chọn. Công cụ lưu trữ, từ ngữ cảnh MongoDB, là thành phần của cơ sở dữ liệu chịu trách nhiệm quản lý cách dữ liệu được lưu trữ, cả trong bộ nhớ và trên đĩa. MongoDB hỗ trợ công cụ lưu trữ trong bộ nhớ, tuy nhiên, công cụ này hiện chỉ giới hạn ở phiên bản Enterprise của sản phẩm. Vào năm 2016, Percona đã phát hành một công cụ trong bộ nhớ mã nguồn mở cho MongoDB Community Edition được gọi là Percona Memory Engine cho MongoDB. Giống như công cụ trong bộ nhớ MonogDB, nó cũng là một biến thể của công cụ lưu trữ WiredTiger, nhưng không có tính ổn định đối với đĩa.
Với công cụ lưu trữ MongoDB trong bộ nhớ, chúng ta có một sân chơi bình đẳng giữa Redis và MongoDB. Vì vậy, tại sao chúng ta cần phải so sánh hai? Hãy xem xét những ưu điểm của từng giải pháp trong số chúng như một giải pháp lưu vào bộ nhớ đệm.
Trước tiên, hãy xem Redis.
Ưu điểm của Redis as a Cache
- Một giải pháp lưu vào bộ nhớ đệm nổi tiếng vượt trội.
- Redis không phải là một giải pháp bộ nhớ cache đơn thuần - nó có cấu trúc dữ liệu nâng cao cung cấp nhiều cách mạnh mẽ để lưu và truy vấn dữ liệu mà không thể đạt được với bộ nhớ cache khóa-giá trị vani.
- Redis khá đơn giản để thiết lập, sử dụng và học hỏi.
- Redis cung cấp sự bền bỉ mà bạn có thể chọn thiết lập, vì vậy, việc làm nóng bộ nhớ cache trong trường hợp xảy ra sự cố sẽ không gặp rắc rối gì.
Nhược điểm của Redis:
- Nó không có mã hóa sẵn có trên dây.
- Không có kiểm soát tài khoản dựa trên vai trò (RBAC).
- Không có một giải pháp phân nhóm hoàn thiện và liền mạch.
- Có thể là một khó khăn khi triển khai trong các triển khai đám mây quy mô lớn.
Ưu điểm của MongoDB làm bộ nhớ đệm
- MongoDB là cơ sở dữ liệu truyền thống hơn với các tính năng thao tác dữ liệu nâng cao (tổng hợp suy nghĩ và thu nhỏ bản đồ) và ngôn ngữ truy vấn phong phú.
- Tích hợp sẵn SSL, RBAC và mở rộng quy mô.
- Nếu bạn đã sử dụng MongoDB làm cơ sở dữ liệu chính, thì chi phí vận hành và phát triển của bạn sẽ giảm xuống vì bạn chỉ có một cơ sở dữ liệu để tìm hiểu và quản lý.
Hãy xem bài đăng này của Peter Zaitsev về nơi mà công cụ trong bộ nhớ MongoDB có thể phù hợp.
Nhược điểm của MongoDB:
- Với công cụ trong bộ nhớ, nó không có tính bền bỉ cho đến khi nó được triển khai dưới dạng một tập hợp bản sao với độ bền được định cấu hình trên (các) bản sao đã đọc.
Trong bài đăng này, chúng tôi sẽ tập trung vào việc định lượng sự khác biệt về hiệu suất giữa Redis và MongoDB . So sánh định tính và sự khác biệt trong hoạt động sẽ được đề cập trong các bài viết tiếp theo.
Redis so với MongoDB trong bộ nhớ
Hiệu suất
- Redis hoạt động tốt hơn đáng kể khi đọc cho tất cả các loại khối lượng công việc và tốt hơn cho việc ghi khi khối lượng công việc tăng lên.
- Mặc dù MongoDB sử dụng tất cả các lõi của hệ thống, nó vẫn bị ràng buộc bởi CPU tương đối sớm. Mặc dù nó vẫn có sẵn máy tính, nhưng nó viết tốt hơn Redis.
- Cả hai cơ sở dữ liệu cuối cùng đều bị ràng buộc tính toán. Mặc dù Redis là một luồng, nhưng nó (hầu hết) làm được nhiều việc hơn khi chạy trên một lõi so với MongoDB làm trong khi bão hòa tất cả các lõi.
- Redis , đối với các tập dữ liệu không tầm thường, sử dụng nhiều RAM hơn so với MongoDB để lưu trữ cùng một lượng dữ liệu.
Cấu hình
Chúng tôi đã sử dụng YCSB để đo hiệu suất và đã sử dụng nó để so sánh và đánh giá hiệu suất của MongoDB trên các nhà cung cấp và cấu hình đám mây khác nhau trong quá khứ. Chúng tôi giả định hiểu cơ bản về khối lượng công việc và các tính năng của YCSB trong phần mô tả giàn thử nghiệm.
- Loại phiên bản cơ sở dữ liệu: AWS EC2 c4.xlarge có 4 lõi, bộ nhớ 7,5 GB và mạng nâng cao để đảm bảo chúng tôi không gặp phải bất kỳ sự cố nghẽn mạng nào.
- Máy khách: AWS EC2 c4.xlarge trong cùng một đám mây riêng ảo (VPC) như các máy chủ cơ sở dữ liệu.
- Redis: Phiên bản 3.2.8 với AOF và RDB bị tắt. Độc lập.
- MongoDB: Percona Memory Engine dựa trên MongoDB phiên bản 3.2.12. Độc lập.
- Thông lượng mạng :Được đo qua iperf theo khuyến nghị của AWS:
Test Complete. Summary Results: [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-60.00 sec 8.99 GBytes 1.29 Gbits/sec 146 sender [ 4] 0.00-60.00 sec 8.99 GBytes 1.29 Gbits/sec receiver
- Chi tiết Khối lượng Công việc
- Chèn Khối lượng Công việc: 100% ghi - 2,5 triệu bản ghi
- Khối lượng công việc A: Cập nhật khối lượng công việc nặng - 50% / 50% Đọc / Viết - 25 triệu thao tác
- Khối lượng công việc B: Đọc phần lớn khối lượng công việc - 95% / 5% Đọc / Viết - 25 triệu thao tác
- Tải của Khách hàng: Thông lượng và độ trễ được đo qua các tải tăng dần được tạo ra từ máy khách. Điều này được thực hiện bằng cách tăng số luồng tải ứng dụng khách YCSB, bắt đầu từ 8 và tăng lên theo bội số của 2
Kết quả
Hiệu suất khối lượng công việc B
Vì trường hợp sử dụng chính cho cơ sở dữ liệu trong bộ nhớ là bộ nhớ đệm, trước tiên hãy xem xét Khối lượng công việc B.
Dưới đây là các con số về thông lượng / độ trễ từ khối lượng công việc 25 triệu hoạt động và tỷ lệ đọc / ghi là 95% / 5%. Đây sẽ là khối lượng công việc đọc bộ nhớ cache đại diện:
Lưu ý:Thông lượng được vẽ dựa trên trục chính (trái), trong khi độ trễ được vẽ dựa trên trục phụ (phải).
Quan sát trong quá trình chạy Khối lượng công việc B:
- Đối với MongoDB, CPU đã bão hòa bởi 32 luồng trở đi. Sử dụng nhiều hơn 300% với tỷ lệ phần trăm nhàn rỗi là một chữ số.
- Đối với Redis, việc sử dụng CPU chưa bao giờ vượt quá 95%. Vì vậy, Redis luôn hoạt động tốt hơn MongoDB khi chạy trên một luồng duy nhất, trong khi MongoDB đang bão hòa tất cả các lõi của máy.
- Đối với Redis, ở 128 luồng, các lần chạy thường không thành công với các ngoại lệ thời gian chờ đọc.
Khối lượng công việc A Hiệu suất
Dưới đây là các con số về thông lượng / độ trễ từ khối lượng công việc 25 triệu hoạt động. Tỷ lệ đọc / ghi là 50% / 50%:
Lưu ý:Thông lượng được vẽ theo trục chính (trái), trong khi độ trễ được vẽ theo trục phụ (phải).
Quan sát trong quá trình chạy Khối lượng công việc A:
- Đối với MongoDB, CPU đã bão hòa bởi 32 luồng trở đi. Sử dụng nhiều hơn 300% với tỷ lệ phần trăm nhàn rỗi là một chữ số.
- Đối với Redis, hiệu suất sử dụng CPU chưa bao giờ vượt quá 95%.
- Đối với Redis, từ 64 luồng trở lên, thường không chạy được với các ngoại lệ thời gian chờ đọc.
Chèn hiệu suất khối lượng công việc
Cuối cùng, đây là các con số về thông lượng / độ trễ từ khối lượng công việc chèn bản ghi 2,5 triệu. Số lượng bản ghi đã được chọn để đảm bảo tổng bộ nhớ được sử dụng trong trường hợp Redis không vượt quá 80% (vì Redis là bộ nhớ, xem Phụ lục B).
Lưu ý:Thông lượng được vẽ theo trục chính (trái), trong khi độ trễ được vẽ theo trục phụ (phải).
Quan sát trong quá trình chạy Chèn khối lượng công việc:
- Đối với MongoDB, CPU đã bão hòa bởi 32 luồng trở đi. Sử dụng nhiều hơn 300% với tỷ lệ phần trăm nhàn rỗi là một chữ số.
- Đối với Redis, hiệu suất sử dụng CPU chưa bao giờ vượt quá 95%.
Phụ lục
A:Hiệu suất một luồng
Tôi rất muốn tìm ra điều này - mặc dù nó không hữu ích lắm trong điều kiện thực tế:ai sẽ tốt hơn khi áp dụng cùng một tải cho mỗi người trong số họ từ một chuỗi duy nhất. Đó là, một ứng dụng đơn luồng sẽ hoạt động như thế nào?
B:Kích thước cơ sở dữ liệu
Định dạng mặc định của các bản ghi được chèn bởi YCSB là:mỗi bản ghi gồm 10 trường và mỗi trường là 100 byte. Giả sử mỗi bản ghi là khoảng 1KB, tổng dung lượng dự kiến trong bộ nhớ sẽ lên tới 2,4GB. Có một sự tương phản hoàn toàn về kích thước thực tế như được thấy trong cơ sở dữ liệu.
MongoDB
> db.usertable.count() 2500000 > db.usertable.findOne() { "_id" : "user6284781860667377211", "field1" : BinData(0,"OUlxLllnPC0sJEovLTpyL18jNjk6ME8vKzF4Kzt2OUEzMSEwMkBvPytyODZ4Plk7KzRmK0FzOiYoNFU1O185KFB/IVF7LykmPkE9NF1pLDFoNih0KiIwJU89K0ElMSAgKCF+Lg=="), "field0" : BinData(0,"ODlwIzg0Ll5vK1s7NUV1O0htOVRnMk53JEd3KiwuOFN7Mj5oJ1FpM11nJ1hjK0BvOExhK1Y/LjEiJDByM14zPDtgPlcpKVYzI1kvKEc5PyY6OFs9PUMpLEltNEI/OUgzIFcnNQ=="), "field7" : BinData(0,"N155M1ZxPSh4O1B7IFUzJFNzNEB1OiAsM0J/NiMoIj9sP1Y1Kz9mKkJ/OiQsMSk2OCouKU1jOltrMj4iKEUzNCVqIV4lJC0qIFY3MUo9MFQrLUJrITdqOjJ6NVs9LVcjNExxIg=="), "field6" : BinData(0,"Njw6JVQnMyVmOiZyPFxrPz08IU1vO1JpIyZ0I1txPC9uN155Ij5iPi5oJSIsKVFhP0JxM1svMkphL0VlNzdsOlQxKUQnJF4xPkk9PUczNiF8MzdkNy9sLjg6NCNwIy1sKTw6MA=="), "field9" : BinData(0,"KDRqP1o3KzwgNUlzPjwgJEgtJC44PUUlPkknKU5pLzkuLEAtIlg9JFwpKzBqIzo2MCIoKTxgNU9tIz84OFB/MzJ4PjwoPCYyNj9mOjY+KU09JUk1I0l9O0s/IEUhNU05NShiNg=="), "field8" : BinData(0,"NDFiOj9mJyY6KTskO0A/OVg/NkchKEFtJUprIlJrPjYsKT98JyI8KFwzOEE7ICR4LUF9JkU1KyRkKikoK0g3MEMxKChsL10pKkAvPFRxLkxhOlotJFZlM0N/LiR4PjlqJ0FtOw=="), "field3" : BinData(0,"OSYoJTR+JEp9K00pKj0iITVuIzVqPkBpJFN9Myk4PDhqOjVuP1YhPSM2MFp/Kz14PTF4Mlk3PkhzKlx3L0xtKjkqPCY4JF0vIic6LEx7PVBzI0U9KEM1KDV4NiEuKFx5MiZyPw=="), "field2" : BinData(0,"Njd8LywkPlg9IFl7KlE5LV83ISskPVQpNDYgMEprOkprMy06LlotMUF5LDZ0IldzLl0tJVkjMTdgJkNxITFsNismLDxuIyYoNDgsLTc+OVpzKkBlMDtoLyBgLlctLCxsKzl+Mw=="), "field5" : BinData(0,"OCJiNlI1O0djK1BtIyc4LEQzNj9wPyQiPT8iNE1pODI2LShqNDg4JF1jNiZiNjZuNE5lNzA8OCAgMDp2OVkjNVU3MzIuJTgkNDp0IyVkJyk6IEEvKzVyK1s9PEAhKUJvPDxyOw=="), "field4" : BinData(0,"OFN1I0B7N1knNSR2LFp7PjUyPlJjP15jIUdlN0AhNEkhMC9+Lkd5P10jO1B3K10/I0orIUI1NzYuME81I0Y1NSYkMCxyI0w/LTc8PCEgJUZvMiQiIkIhPCF4LyN6K14rIUJlJg==") } > db.runCommand({ dbStats: 1, scale: 1 }) { "db" : "ycsb", "collections" : 1, "objects" : 2500000, "avgObjSize" : 1167.8795252, "dataSize" : 2919698813, "storageSize" : 2919698813, "numExtents" : 0, "indexes" : 1, "indexSize" : 76717901, "ok" : 1 }
Vì vậy, dung lượng được sử dụng là ~ 2,7GB, khá gần với những gì chúng tôi mong đợi.
Redis
Bây giờ hãy xem Redis.
> info keyspace # Keyspace db0:keys=2500001,expires=0,avg_ttl=0 127.0.0.1:6379> RANDOMKEY "user3176318471616059981" 127.0.0.1:6379> hgetall user3176318471616059981 1) "field1" 2) "#K/<No\"&l*M{,;f;]\x7f)Ss'+2<D}7^a8I/01&9.:)Q71T7,3r&\\y6:< Gk;6n*]-)*f>:p:O=?<:(;v/)0)Yw.W!8]+4B=8.z+*4!" 3) "field2" 4) "(9<9P5**d7<v((2-6*3Zg/.p4G=4Us;N+!C! I50>h=>p\"X9:Qo#C9:;z.Xs=Wy*H3/Fe&0`8)t.Ku0Q3)E#;Sy*C).Sg++t4@7-" 5) "field5" 6) "#1 %8x='l?5d38~&U!+/b./b;(6-:v!5h.Ou2R}./(*)4!8>\"B'!I)5U?0\" >Ro.Ru=849Im+Qm/Ai(;:$Z',]q:($%&(=3~5(~?" 7) "field0" 8) "+\"(1Pw.>*=807Jc?Y-5Nq#Aw=%*57r7!*=Tm!<j6%t3-45L5%Cs#/h;Mg:Vo690-/>-X}/X#.U) )f9-~;?p4;p*$< D-1_s!0p>" 9) "field7" 10) ":]o/2p/3&(!b> |#:0>#0-9b>Pe6[}<Z{:S}9Uc*0<)?60]37'~'Jk-Li',x!;.5H'\"'|.!v4Y-!Hk=E\x7f2;8*9((-09*b#)x!Pg2" 11) "field3" 12) " C; ,f6Uq+^i Fi'8&0By\"^##Qg\":$+7$%Y;7Rs'\"d3Km'Es>.|33$ Vo*M%=\"<$&j%/<5]%\".h&Kc'5.46x5D35'0-3l:\"| !l;" 13) "field6" 14) "-5x6!22)j;O=?1&!:&.S=$;|//r'?d!W54(j!$:-H5.*n&Zc!0f;Vu2Cc?E{1)r?M'!Kg'-b<Dc*1d2M-9*d&(l?Uk5=8,>0.B#1" 15) "field9" 16) "(Xa&1t&Xq\"$((Ra/Q9&\": &>4Ua;Q=!T;(Vi2G+)Uu.+|:Ne;Ry3U\x7f!B\x7f>O7!Dc;V7?Eu7E9\"&<-Vi>7\"$Q%%A%1<2/V11: :^c+" 17) "field8" 18) "78(8L9.H#5N+.E5=2`<Wk+Pw?+j'Q=3\"$,Nk3O{+3p4K?0/ 5/r:W)5X}#;p1@\x7f\"+&#Ju+Z97#t:J9$'*(K).7&0/` 125O38O)0" 19) "field4" 20) "$F=)Ke5V15_)-'>=C-/Ka7<$;6r#_u F9)G/?;t& x?D%=Ba Zk+]) ($=I%3P3$<`>?*=*r9M1-Ye:S%%0,(Ns3,0'A\x7f&Y12A/5" 127.0.0.1:6379> info memory # Memory used_memory:6137961456 used_memory_human:5.72G used_memory_rss:6275940352 used_memory_rss_human:5.84G used_memory_peak:6145349904 used_memory_peak_human:5.72G total_system_memory:7844429824 total_system_memory_human:7.31G used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:7516192768 maxmemory_human:7.00G maxmemory_policy:noeviction mem_fragmentation_ratio:1.02 mem_allocator:jemalloc-3.6.0
Ở mức sử dụng cao nhất, Redis dường như chiếm khoảng 5,72G bộ nhớ, tức là gấp đôi bộ nhớ so với MongoDB. Bây giờ, sự so sánh này có thể không hoàn hảo vì sự khác biệt trong hai cơ sở dữ liệu, nhưng sự khác biệt này trong việc sử dụng bộ nhớ là quá lớn để bỏ qua. YCSB chèn bản ghi trong hàm băm trong Redis và một chỉ mục được duy trì trong một tập hợp được sắp xếp. Vì một mục nhập riêng lẻ lớn hơn 64, hàm băm được mã hóa bình thường và không tiết kiệm dung lượng. Hiệu suất của Redis đi kèm với cái giá của việc tăng dung lượng bộ nhớ.
Theo ý kiến của chúng tôi, đây có thể là một điểm dữ liệu quan trọng trong việc lựa chọn giữa MongoDB và Redis - MongoDB có thể phù hợp hơn cho những người dùng quan tâm đến việc giảm chi phí bộ nhớ của họ.
C:Thông lượng mạng
Máy chủ cơ sở dữ liệu trong bộ nhớ có thể bị ràng buộc máy tính hoặc mạng I / O, vì vậy điều quan trọng trong toàn bộ tập hợp các bài kiểm tra này là đảm bảo rằng chúng ta không bao giờ bị ràng buộc mạng. Việc đo thông lượng mạng trong khi chạy các bài kiểm tra thông lượng ứng dụng ảnh hưởng xấu đến phép đo thông lượng tổng thể. Vì vậy, chúng tôi đã chạy các phép đo thông lượng mạng tiếp theo bằng cách sử dụng iftop tại số lượng luồng nơi thông lượng ghi cao nhất được quan sát. Điều này được phát hiện là khoảng 440 Mbps cho cả Redis và MongoDB ở thông lượng cao nhất tương ứng của chúng. Với phép đo ban đầu của chúng tôi về băng thông mạng tối đa là khoảng 1,29 Gbps, chúng tôi chắc chắn rằng chúng tôi chưa bao giờ đạt đến giới hạn mạng. Trên thực tế, nó chỉ hỗ trợ suy luận rằng nếu Redis là đa lõi, chúng ta có thể nhận được những con số tốt hơn nhiều.