इस पोस्ट में, हम दो सबसे लोकप्रिय NoSQL डेटाबेस की तुलना कर रहे हैं:Redis (इन-मेमोरी) और MongoDB (Percona मेमोरी स्टोरेज इंजन)।
Redis एक लोकप्रिय और बहुत तेज़ इन-मेमोरी डेटाबेस संरचना स्टोर है जो मुख्य रूप से कैश या संदेश ब्रोकर के रूप में उपयोग किया जाता है। स्मृति में होने के कारण, यह पसंद का डेटा स्टोर होता है जब प्रतिक्रिया समय बाकी सब चीजों से आगे निकल जाता है।
MongoDB एक ऑन-डिस्क दस्तावेज़ स्टोर है जो डेटा को JSON इंटरफ़ेस प्रदान करता है और इसमें एक बहुत समृद्ध क्वेरी भाषा है। इसकी गति, दक्षता और मापनीयता के लिए जाना जाता है, यह वर्तमान में आज उपयोग किया जाने वाला सबसे लोकप्रिय NoSQL डेटाबेस है। हालाँकि, एक ऑन-डिस्क डेटाबेस होने के नाते, यह पूर्ण प्रदर्शन के मामले में रेडिस जैसे इन-मेमोरी डेटाबेस से अनुकूल रूप से तुलना नहीं कर सकता है। लेकिन, MongoDB के लिए इन-मेमोरी स्टोरेज इंजन की उपलब्धता के साथ, अधिक प्रत्यक्ष तुलना संभव हो जाती है।
MongoDB के लिए Percona मेमोरी इंजन
संस्करण 3.0 से शुरू होकर, MongoDB आपकी पसंद के स्टोरेज इंजन को प्लग इन करने के लिए एक API प्रदान करता है। MongoDB संदर्भ से एक स्टोरेज इंजन, डेटाबेस का वह घटक है जो इन-मेमोरी और ऑन-डिस्क दोनों में डेटा को कैसे संग्रहीत किया जाता है, इसे प्रबंधित करने के लिए जिम्मेदार है। MongoDB एक इन-मेमोरी स्टोरेज इंजन का समर्थन करता है, हालांकि, यह वर्तमान में उत्पाद के एंटरप्राइज़ संस्करण तक सीमित है। 2016 में, Percona ने MongoDB कम्युनिटी संस्करण के लिए एक ओपन सोर्स इन-मेमोरी इंजन जारी किया, जिसे MongoDB के लिए Percona मेमोरी इंजन कहा जाता है। MonogDB के इन-मेमोरी इंजन की तरह, यह भी WiredTiger स्टोरेज इंजन का एक रूपांतर है, लेकिन डिस्क के लिए कोई दृढ़ता नहीं है।
एक इन-मेमोरी MongoDB स्टोरेज इंजन के साथ, हमारे पास Redis और MongoDB के बीच एक लेवल प्लेइंग फील्ड है। तो, हमें दोनों की तुलना करने की आवश्यकता क्यों है? आइए कैशिंग समाधान के रूप में उनमें से प्रत्येक के लाभों को देखें।
आइए पहले रेडिस को देखें।
कैश के रूप में Redis के लाभ
- एक प्रसिद्ध कैशिंग समाधान जो इसमें उत्कृष्ट है।
- Redis एक सादा कैश समाधान नहीं है - इसमें एक उन्नत डेटा संरचनाएं हैं जो डेटा को सहेजने और क्वेरी करने के कई शक्तिशाली तरीके प्रदान करती हैं जिन्हें वैनिला की-वैल्यू कैश के साथ हासिल नहीं किया जा सकता है।
- Redis सेटअप, उपयोग और सीखने के लिए काफी सरल है।
- Redis दृढ़ता प्रदान करता है कि आप सेट अप करने का विकल्प चुन सकते हैं, इसलिए क्रैश की स्थिति में कैश वार्मिंग परेशानी मुक्त है।
रेडिस के नुकसान:
- इसमें वायर पर इनबिल्ट एन्क्रिप्शन नहीं है।
- कोई भूमिका-आधारित खाता नियंत्रण (RBAC) नहीं।
- कोई सहज, परिपक्व क्लस्टरिंग समाधान नहीं है।
- बड़े पैमाने पर क्लाउड परिनियोजन में परिनियोजित करने के लिए दर्द हो सकता है।
एक कैश के रूप में MongoDB के लाभ
- MongoDB उन्नत डेटा हेरफेर सुविधाओं (थिंक एग्रीगेशन और मैप-रिड्यूस) और एक समृद्ध क्वेरी भाषा के साथ एक अधिक पारंपरिक डेटाबेस है।
- एसएसएल, आरबीएसी, और स्केल-आउट बिल्ट इन।
- यदि आप पहले से ही अपने प्राथमिक डेटाबेस के रूप में MongoDB का उपयोग कर रहे हैं, तो आपकी परिचालन और विकास लागत कम हो जाती है क्योंकि आपके पास सीखने और प्रबंधित करने के लिए केवल एक डेटाबेस है।
पीटर जैतसेव की इस पोस्ट को देखें जहां मोंगोडीबी इन-मेमोरी इंजन एक अच्छा फिट हो सकता है।
MongoDB के नुकसान:
- इन-मेमोरी इंजन के साथ, यह तब तक कोई दृढ़ता प्रदान नहीं करता है जब तक कि इसे एक प्रतिकृति सेट के रूप में तैनात नहीं किया जाता है, जिसमें पठन प्रतिकृति (ओं) पर दृढ़ता से कॉन्फ़िगर किया गया है।
इस पोस्ट में, हम Redis और MongoDB के बीच प्रदर्शन अंतर को मापने पर ध्यान केंद्रित करेंगे . बाद की पोस्ट में गुणात्मक तुलना और संचालन संबंधी अंतरों को शामिल किया जाएगा।
Redis बनाम इन-मेमोरी MongoDB
प्रदर्शन
- Redis पढ़ने के लिए काफी बेहतर प्रदर्शन करता है सभी प्रकार के कार्यभार के लिए, और कार्यभार बढ़ने पर लिखने के लिए बेहतर है।
- भले ही MongoDB सिस्टम के सभी कोर का उपयोग करता है, लेकिन यह CPU को अपेक्षाकृत जल्दी बाध्य कर देता है। जबकि इसके पास अभी भी कंप्यूट उपलब्ध था, यह रेडिस की तुलना में लिखने में बेहतर था।
- दोनों डेटाबेस अंततः कंप्यूट-बाउंड हैं। भले ही रेडिस सिंगल-थ्रेडेड है, लेकिन यह (ज्यादातर) सभी कोर को संतृप्त करते हुए मोंगोडीबी की तुलना में एक कोर पर चलने के साथ और अधिक हो जाता है।
- Redis , गैर-तुच्छ डेटा सेट के लिए, समान मात्रा में डेटा संग्रहीत करने के लिए MongoDB की तुलना में बहुत अधिक RAM का उपयोग करता है।
कॉन्फ़िगरेशन
हमने प्रदर्शन को मापने के लिए YCSB का उपयोग किया है, और अतीत में विभिन्न क्लाउड प्रदाताओं और कॉन्फ़िगरेशन पर MongoDB के प्रदर्शन की तुलना और बेंचमार्क करने के लिए इसका उपयोग करते रहे हैं। हम परीक्षण रिग विवरण में YCSB कार्यभार और सुविधाओं की एक बुनियादी समझ मानते हैं।
- डेटाबेस इंस्टेंस प्रकार: AWS EC2 c4.xlarge 4 कोर, 7.5 जीबी मेमोरी और बेहतर नेटवर्किंग की विशेषता है ताकि यह सुनिश्चित किया जा सके कि हमें कोई नेटवर्क अड़चन न हो।
- क्लाइंट मशीन: डेटाबेस सर्वर के समान वर्चुअल प्राइवेट क्लाउड (VPC) में AWS EC2 c4.xlarge.
- रेडिस: संस्करण 3.2.8 AOF और RDB के साथ बंद हो गया। स्टैंडअलोन.
- मोंगोडीबी: मोंगोडीबी संस्करण 3.2.12 पर आधारित पेरकोना मेमोरी इंजन। स्टैंडअलोन.
- नेटवर्क थ्रूपुट : एडब्ल्यूएस द्वारा अनुशंसित iperf के माध्यम से मापा गया:
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
- कार्यभार विवरण
- कार्यभार सम्मिलित करें: 100% लिखें – 2.5 मिलियन रिकॉर्ड
- कार्यभार ए: भारी कार्यभार अपडेट करें - 50%/50% पढ़ता/लिखता है - 25 मिलियन ऑपरेशन
- कार्यभार बी: ज़्यादातर काम का बोझ पढ़ें - 95%/5% पढ़ता/लिखता है - 25 मिलियन ऑपरेशन
- क्लाइंट लोड: थ्रूपुट और लेटेंसी को क्लाइंट से उत्पन्न बढ़ते भार पर मापा जाता है। यह YCSB क्लाइंट लोड थ्रेड्स की संख्या बढ़ाकर, 8 से शुरू करके और 2 के गुणकों में बढ़ाकर किया गया था
परिणाम
कार्यभार B प्रदर्शन
चूंकि इन-मेमोरी डेटाबेस के लिए प्राथमिक उपयोग केस कैश है, आइए पहले वर्कलोड बी को देखें।
यहां 25 मिलियन संचालन कार्यभार से थ्रूपुट/विलंबता संख्याएं हैं और पढ़ने/लिखने का अनुपात 95%/5% था। यह एक प्रतिनिधि कैश रीडिंग वर्कलोड होगा:
ध्यान दें:थ्रूपुट को प्राथमिक अक्ष (बाएं) के विरुद्ध प्लॉट किया जाता है, जबकि विलंबता को द्वितीयक अक्ष (दाएं) के विरुद्ध प्लॉट किया जाता है।
कार्यभार B रन के दौरान अवलोकन:
- MongoDB के लिए, CPU को 32 थ्रेड्स से आगे बढ़ाया गया था। एकल अंकों के निष्क्रिय प्रतिशत के साथ 300% से अधिक उपयोग।
- Redis के लिए, CPU उपयोग कभी भी 95% से अधिक नहीं हुआ। इसलिए, एक ही थ्रेड पर चलते समय Redis लगातार MongoDB से बेहतर प्रदर्शन कर रहा था, जबकि MongoDB मशीन के सभी कोर को संतृप्त कर रहा था।
- Redis के लिए, 128 थ्रेड्स पर, रीड-टाइमआउट अपवादों के साथ रन अक्सर विफल हो जाते हैं।
कार्यभार एक प्रदर्शन
यहां 25 मिलियन संचालन कार्यभार से थ्रूपुट/विलंबता संख्याएं हैं। पढ़ने/लिखने का अनुपात 50%/50% था:
नोट:थ्रूपुट को प्राथमिक अक्ष (बाएं) के विरुद्ध प्लॉट किया जाता है, जबकि विलंबता को द्वितीयक अक्ष (दाएं) के विरुद्ध प्लॉट किया जाता है।
वर्कलोड ए रन के दौरान अवलोकन:
- MongoDB के लिए, CPU को 32 थ्रेड्स से आगे बढ़ाया गया था। एकल अंकों के निष्क्रिय प्रतिशत के साथ 300% से अधिक उपयोग।
- Redis के लिए, CPU उपयोग कभी भी 95% से अधिक नहीं हुआ।
- रेडिस के लिए, 64 थ्रेड्स और उससे ऊपर के रन, रीड-टाइमआउट अपवादों के साथ अक्सर विफल हो जाते हैं।
कार्यभार प्रदर्शन सम्मिलित करें
अंत में, 2.5 मिलियन रिकॉर्ड प्रविष्टि कार्यभार से थ्रूपुट/विलंबता संख्याएं यहां दी गई हैं। रिकॉर्ड की संख्या का चयन यह सुनिश्चित करने के लिए किया गया था कि कुल मेमोरी का उपयोग उस घटना में किया गया था जो कि रेडिस 80% से अधिक नहीं थी (चूंकि रेडिस मेमोरी हॉग है, परिशिष्ट बी देखें)।
नोट:थ्रूपुट को प्राथमिक अक्ष (बाएं) के विरुद्ध प्लॉट किया जाता है, जबकि विलंबता को द्वितीयक अक्ष (दाएं) के विरुद्ध प्लॉट किया जाता है।
इंसर्ट वर्कलोड रन के दौरान अवलोकन:
- MongoDB के लिए, CPU को 32 थ्रेड्स से आगे बढ़ाया गया था। एकल अंकों के निष्क्रिय प्रतिशत के साथ 300% से अधिक उपयोग।
- Redis के लिए, CPU उपयोग कभी भी 95% से अधिक नहीं हुआ।
परिशिष्ट
A:सिंगल-थ्रेड प्रदर्शन
मुझे यह पता लगाने की तीव्र इच्छा थी - भले ही यह वास्तविक दुनिया की स्थितियों में बहुत उपयोगी नहीं है:एक ही धागे से उनमें से प्रत्येक पर समान भार लागू करते समय कौन बेहतर होगा। यानी, सिंगल-थ्रेडेड एप्लिकेशन कैसा प्रदर्शन करेगा?
B:डेटाबेस का आकार
YCSB द्वारा डाले गए रिकॉर्ड का डिफ़ॉल्ट प्रारूप हैं:प्रत्येक रिकॉर्ड 10 फ़ील्ड का होता है और प्रत्येक फ़ील्ड 100 बाइट्स का होता है। प्रत्येक रिकॉर्ड को 1KB के आसपास मानते हुए, मेमोरी में कुल अपेक्षित आकार 2.4GB से ऊपर होगा। जैसा कि डेटाबेस में देखा गया है, वास्तविक आकारों में काफी अंतर था।
मोंगोडीबी
> 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 }
तो, ली गई जगह ~2.7GB है जो हमारी अपेक्षा के काफी करीब है।
रेडिस
आइए अब रेडिस को देखें।
> 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
चरम उपयोग पर, Redis लगभग 5.72G मेमोरी लेता है, यानी MongoDB जितनी मेमोरी लेता है उससे दोगुना। अब, दो डेटाबेस में अंतर के कारण यह तुलना सही नहीं हो सकती है, लेकिन स्मृति उपयोग में यह अंतर अनदेखा करने के लिए बहुत बड़ा है। YCSB रेडिस में एक हैश में रिकॉर्ड सम्मिलित करता है, और एक इंडेक्स को एक क्रमबद्ध सेट में बनाए रखा जाता है। चूंकि एक व्यक्तिगत प्रविष्टि 64 से बड़ी है, हैश सामान्य रूप से एन्कोड किया गया है और स्थान में कोई बचत नहीं है। Redis का प्रदर्शन बढ़ी हुई मेमोरी फ़ुटप्रिंट की कीमतों पर आता है।
यह, हमारी राय में, MongoDB और Redis के बीच चयन करने में एक महत्वपूर्ण डेटा बिंदु हो सकता है - MongoDB उन उपयोगकर्ताओं के लिए बेहतर हो सकता है जो अपनी मेमोरी लागत को कम करने की परवाह करते हैं।
C:नेटवर्क थ्रूपुट
इन-मेमोरी डेटाबेस सर्वर या तो कंप्यूट-बाउंड या नेटवर्क I/O-बाउंड होने के लिए उत्तरदायी है, इसलिए इन परीक्षणों के पूरे सेट में यह सुनिश्चित करना महत्वपूर्ण था कि हम कभी भी नेटवर्क-बाउंड नहीं हो रहे थे। एप्लिकेशन थ्रूपुट परीक्षण चलाते समय नेटवर्क थ्रूपुट को मापना समग्र थ्रूपुट माप पर प्रतिकूल प्रभाव डालता है। इसलिए, हमने थ्रेड काउंट पर iftop का उपयोग करके बाद के नेटवर्क थ्रूपुट मापन चलाए जहां उच्चतम लेखन थ्रूपुट देखे गए थे। यह रेडिस और मोंगोडीबी दोनों के लिए उनके संबंधित पीक थ्रूपुट पर लगभग 440 एमबीपीएस पाया गया। अधिकतम नेटवर्क बैंडविड्थ के हमारे प्रारंभिक माप लगभग 1.29 Gbps को देखते हुए, हम निश्चित हैं कि हम कभी भी नेटवर्क सीमा से नहीं टकराएंगे। वास्तव में, यह केवल इस अनुमान का समर्थन करता है कि यदि रेडिस मल्टी-कोर होते, तो हमें बहुत बेहतर संख्याएँ मिल सकती थीं।