sql >> Databáze >  >> NoSQL >> Redis

Redis vs. MongoDB:Porovnání databází v paměti s Percona Memory Engine

V tomto příspěvku porovnáváme dvě nejoblíbenější databáze NoSQL:Redis (in-memory) a MongoDB (Percona memory storage engine).

Redis je oblíbené a velmi rychlé úložiště databázových struktur v paměti primárně používané jako mezipaměť nebo zprostředkovatel zpráv. Protože je v paměti, je to úložiště dat, které si vyberete, když doba odezvy předčí všechno ostatní.

MongoDB je úložiště dokumentů na disku, které poskytuje datům rozhraní JSON a má velmi bohatý dotazovací jazyk. Známá svou rychlostí, efektivitou a škálovatelností je v současnosti nejoblíbenější NoSQL databází, která se dnes používá. Vzhledem k tomu, že jde o databázi na disku, nemůže se srovnávat příznivě s databází v paměti, jako je Redis, pokud jde o absolutní výkon. Ale s dostupností in-memory storage engine pro MongoDB je možné přímější srovnání.

Percona Memory Engine pro MongoDB

Počínaje verzí 3.0 poskytuje MongoDB rozhraní API pro připojení úložiště podle vašeho výběru. Úložný modul z kontextu MongoDB je součástí databáze, která je zodpovědná za správu způsobu ukládání dat, a to jak v paměti, tak na disku. MongoDB podporuje modul úložiště v paměti, v současnosti je však omezen na verzi Enterprise produktu. V roce 2016 Percona vydala open source in-memory engine pro MongoDB Community Edition s názvem Percona Memory Engine for MongoDB. Stejně jako in-memory engine MonogDB je to také varianta úložiště WiredTiger, ale bez perzistence na disku.

S in-memory úložištěm MongoDB máme mezi Redis a MongoDB rovné podmínky. Proč je tedy musíme porovnávat? Podívejme se na výhody každého z nich jako řešení ukládání do mezipaměti.

Nejprve se podívejme na Redis.

Výhody Redis jako mezipaměti

  • Známé řešení ukládání do mezipaměti, které v tom vyniká.
  • Redis není jednoduché řešení mezipaměti – má pokročilé datové struktury, které poskytují mnoho výkonných způsobů ukládání a dotazování na data, kterých nelze dosáhnout pomocí vanilla klíč–hodnota mezipaměti.
  • Redis se poměrně snadno nastavuje, používá a učí se.
  • Redis poskytuje stálost, kterou si můžete nastavit, takže zahřívání mezipaměti v případě selhání je bezproblémové.

Nevýhody Redis:

  • Nemá vestavěné šifrování na drátě.
  • Žádné řízení účtů založené na rolích (RBAC).
  • Neexistuje bezproblémové a vyspělé řešení shlukování.
  • Nasazení ve velkých cloudových nasazeních může být obtížné.

Výhody MongoDB jako mezipaměti

  •  MongoDB je tradičnější databáze s pokročilými funkcemi pro manipulaci s daty (agregace a redukce map) a bohatým dotazovacím jazykem.
  • Vestavěné SSL, RBAC a scale-out.
  • Pokud již používáte MongoDB jako svou primární databázi, vaše provozní náklady a náklady na vývoj klesnou, protože máte pouze jednu databázi, kterou se můžete učit a spravovat.

Podívejte se na tento příspěvek od Petera Zaitseva o tom, kde by se in-memory engine MongoDB mohl hodit.

Nevýhoda MongoDB:

  • S modulem in-memory nenabízí žádnou persistenci, dokud není nasazen jako sada replik s perzistencí nakonfigurovanou na čtených replikách.

V tomto příspěvku se zaměříme na kvantifikaci výkonnostních rozdílů mezi Redis a MongoDB . Kvalitativní srovnání a provozní rozdíly budou popsány v následujících příspěvcích.

Redis vs. In-Memory MongoDB

Výkon

  • Redis má při čtení podstatně lepší výkon pro všechny druhy zátěže a lepší pro zápisy s rostoucí zátěží.
  • Přestože MongoDB využívá všechna jádra systému, je poměrně brzy vázán na CPU. I když měl stále k dispozici výpočty, byl lepší v zápisech než Redis.
  • Obě databáze jsou nakonec vázány na výpočty. I když je Redis jednovláknový, zvládne (většinou) více práce s provozem na jednom jádře než MongoDB a zároveň saturuje všechna jádra.
  • Redis , pro netriviální datové sady používá mnohem více paměti RAM ve srovnání s MongoDB k uložení stejného množství dat.

Konfigurace

Použili jsme YCSB k měření výkonu a v minulosti jsme jej používali k porovnání a benchard výkonu MongoDB u různých poskytovatelů cloudu a konfigurací. Předpokládáme základní porozumění pracovní zátěži a funkcím YCSB v popisu testovacího zařízení.

  • Typ instance databáze:   AWS EC2 c4.xlarge se 4 jádry, 7,5 GB paměti a vylepšeným síťovým připojením, abychom zajistili, že nebudeme mít žádná úzká místa v síti.
  • Stroj klienta:   AWS EC2 c4.xlarge ve stejném virtuálním privátním cloudu (VPC) jako databázové servery.
  • Redis:  Verze 3.2.8 s vypnutým AOF a RDB. Samostatný.
  • MongoDB:  Percona Memory Engine založený na MongoDB verze 3.2.12. Samostatný.
  • Propustnost sítě :  Měřeno přes iperf podle doporučení 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
    
  • Podrobnosti o pracovní zátěži
    1. Vložit pracovní zátěž: 100 % zápis – 2,5 milionu záznamů
    2. Úloha A: Aktualizujte velké zatížení – 50 %/50 % čtení/zápis – 25 milionů operací
    3. Úloha B: Převážná zátěž čtení – 95 %/5 % čtení/zápis – 25 milionů operací
  • Zatížení klienta: Propustnost a latence měřené s postupně se zvyšujícím zatížením generovaným klientem. Toho bylo dosaženo zvýšením počtu zátěžových vláken klientů YCSB, počínaje 8 a rostoucími v násobcích 2

Výsledky

Výkon pracovní zátěže B

Protože primárním případem použití pro databáze v paměti je mezipaměť, podívejme se nejprve na pracovní zátěž B.

Zde jsou čísla propustnosti/latence z 25 milionů operací a poměr čtení/zápis byl 95 %/5 %. Toto by byla reprezentativní zátěž čtení mezipaměti:

Poznámka:Propustnost se vykresluje proti primární ose (vlevo), zatímco latence se vykresluje proti sekundární ose (vpravo).

Pozorování během běhu pracovní zátěže B:

  • U MongoDB byl CPU zasycen o 32 vláken a dále. Využití více než 300 % s jednocifernými procenty nečinnosti.
  • U Redis využití CPU nikdy nepřesáhlo 95 %. Redis tedy trvale vykazoval lepší výkon než MongoDB při běhu na jediném vláknu, zatímco MongoDB zahlcoval všechna jádra počítače.
  • U Redis se 128 vlákny běhy často selhávaly s výjimkami z časového limitu čtení.

Pracovní zátěž A Výkon

Zde jsou čísla propustnosti/latence z 25 milionů operací. Poměr čtení/zápisu byl 50 %/50 %:

Poznámka:Propustnost se vykresluje proti primární ose (vlevo), zatímco latence se vykresluje proti sekundární ose (vpravo).

Pozorování během pracovního zatížení A:

  • U MongoDB byl CPU zasycen o 32 vláken a dále. Využití více než 300 % s jednocifernými procenty nečinnosti.
  • U Redis využití CPU nikdy nepřesáhlo 95 %.
  • U Redis, u 64 vláken a více, běhy často selhávaly s výjimkami z časového limitu čtení.

Vložit výkon zátěže

Konečně, zde jsou čísla propustnosti/latence z 2,5 milionu zátěže pro vkládání záznamů. Počet záznamů byl zvolen tak, aby bylo zajištěno, že v případě Redis byla využita celková paměť, která nepřesáhla 80 % (protože Redis je pamětní prase, viz Příloha B).

Poznámka:Propustnost se vykresluje proti primární ose (vlevo), zatímco latence se vykresluje proti sekundární ose (vpravo).

Pozorování během běhu úlohy vložení:

  • U MongoDB byl CPU zasycen o 32 vláken a dále. Využití více než 300 % s jednocifernými procenty nečinnosti.
  • U Redis využití CPU nikdy nepřesáhlo 95 %.

Přílohy

Odpověď:Výkon jednoho vlákna

Měl jsem silné nutkání to zjistit – i když to v reálných podmínkách není příliš užitečné:kdo by byl lepší, když na každý z nich aplikuje stejnou zátěž z jednoho vlákna. To znamená, jak by fungovala aplikace s jedním vláknem?

B:Velikost databáze

Výchozí formát záznamů vložených pomocí YCSB je:každý záznam má 10 polí a každé pole má 100 bajtů. Za předpokladu, že každý záznam bude mít přibližně 1 kB, bude celková očekávaná velikost paměti více než 2,4 GB. Ve skutečných velikostech, jak je vidět v databázích, byl výrazný kontrast.

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
}

Zabraný prostor je tedy ~2,7 GB, což je docela blízko tomu, co jsme očekávali.

Redis

Podívejme se nyní na 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

Při maximálním využití se zdá, že Redis zabírá přibližně 5,72 G paměti, tj. dvojnásobek paměti, než zabírá MongoDB. Toto srovnání nemusí být dokonalé kvůli rozdílům ve dvou databázích, ale tento rozdíl ve využití paměti je příliš velký na to, aby se dal ignorovat. YCSB vloží záznam do hash v Redis a index je udržován v setříděné sadě. Protože jednotlivý záznam je větší než 64, hash je zakódován normálně a nedochází k žádné úspoře místa. Výkon Redis přichází za ceny zvýšeného zatížení paměti.

Podle našeho názoru to může být důležitý datový bod při výběru mezi MongoDB a Redis – MongoDB může být výhodnější pro uživatele, kterým záleží na snížení nákladů na paměť.

C:Propustnost sítě

Databázový server v paměti může být buď výpočetně vázán, nebo síťový I/O vázán, takže bylo důležité během celé sady těchto testů zajistit, že se nikdy nedostaneme k síti. Měření propustnosti sítě za běhu testů propustnosti aplikací nepříznivě ovlivňuje měření celkové propustnosti. Spustili jsme tedy následná měření propustnosti sítě pomocí iftop v počtech vláken, kde byly pozorovány nejvyšší propustnosti zápisu. Bylo zjištěno, že to je přibližně 440 Mbps pro Redis i MongoDB při jejich příslušné špičkové propustnosti. Vzhledem k našemu počátečnímu měření maximální šířky pásma sítě kolem 1,29 Gbps jsme si jisti, že jsme nikdy nenarazili na hranice sítě. Ve skutečnosti to pouze podporuje závěr, že kdyby byl Redis vícejádrový, mohli bychom získat mnohem lepší čísla.


  1. Odstraňování problémů

  2. Ve výchozím nastavení se připojte ke konkrétní databázi v mongodb

  3. Lombok - java.lang.StackOverflowError:null na metodě toString

  4. Proč bylo v tomto programu gevent provedeno pouze jedno připojení k redis?