Redis
 sql >> база данни >  >> NoSQL >> Redis

Redis срещу MongoDB:Сравняване на бази данни в паметта с Percona Memory Engine

В тази публикация сравняваме две от най-популярните NoSQL бази данни:Redis (в паметта) и MongoDB (механизъм за съхранение на памет Percona).

Redis е популярно и много бързо хранилище за структура на база данни в паметта, използвано предимно като кеш или посредник на съобщения. Тъй като е в паметта, това е предпочитано хранилище за данни, когато времето за отговор превъзхожда всичко останало.

MongoDB е хранилище за документи на диск, което предоставя JSON интерфейс за данни и има много богат език за заявки. Известна със своята скорост, ефективност и мащабируемост, в момента това е най-популярната база данни NoSQL, използвана днес. Въпреки това, тъй като е дискова база данни, тя не може да се сравни благоприятно с база данни в паметта като Redis по отношение на абсолютната производителност. Но с наличието на механизмите за съхранение в паметта за MongoDB става възможно по-пряко сравнение.

Percona Memory Engine за MongoDB

Започвайки от версия 3.0, MongoDB предоставя API за включване на движката за съхранение по ваш избор. Машината за съхранение, от контекста на MongoDB, е компонентът на базата данни, който е отговорен за управлението на това как се съхраняват данните, както в паметта, така и на диска. MongoDB поддържа двигател за съхранение в паметта, но в момента е ограничен до Enterprise изданието на продукта. През 2016 г. Percona пусна двигател с отворен код в паметта за MongoDB Community Edition, наречен Percona Memory Engine за MongoDB. Подобно на механизма в паметта на MonogDB, той също е вариант на механизма за съхранение на WiredTiger, но без постоянство на диска.

С инсталиран двигател за съхранение на MongoDB в паметта, ние имаме равни условия между Redis и MongoDB. И така, защо трябва да сравняваме двете? Нека разгледаме предимствата на всеки от тях като решение за кеширане.

Нека първо да разгледаме Redis.

Предимства на Redis като кеш

  • Добре познато решение за кеширане, което се отличава с него.
  • Redis не е обикновено решение за кеширане – той има разширени структури от данни, които предоставят много мощни начини за запазване и запитване на данни които не могат да бъдат постигнати с ванилен кеш ключ-стойност.
  • Redis е сравнително лесен за настройка, използване и научаване.
  • Redis осигурява постоянство, което можете да изберете да настроите, така че затоплянето на кеша в случай на срив е безпроблемно.

Недостатъци на Redis:

  • Няма вградено криптиране на проводника.
  • Без контрол на акаунта, базиран на роли (RBAC).
  • Няма безпроблемно, зряло решение за клъстериране.
  • Може да бъде проблем за внедряване при широкомащабни облачни внедрявания.

Предимства на MongoDB като кеш

  •  MongoDB е по-традиционна база данни с разширени функции за манипулиране на данни (мислете за агрегиране и намаляване на картата) и богат език за заявки.
  • Вградени SSL, RBAC и мащабиране.
  • Ако вече използвате MongoDB като основна база данни, тогава вашите оперативни и развойни разходи намаляват, тъй като имате само една база данни за изучаване и управление.

Вижте тази публикация от Петър Зайцев за това къде може да е подходящ механизмът на MongoDB в паметта.

Недостатък на MongoDB:

  • С механизъм в паметта той не предлага постоянство, докато не бъде разгърнат като набор от реплики с конфигурирана постоянство на репликата за четене.

В тази публикация ще се съсредоточим върху количественото определяне на разликите в производителността между Redis и MongoDB . Качественото сравнение и оперативните разлики ще бъдат разгледани в следващите публикации.

Redis срещу MongoDB в паметта

Ефективност

  • Redis работи значително по-добре при четене за всякакви видове натоварвания и по-добре за записвания, тъй като натоварванията се увеличават.
  • Въпреки че MongoDB използва всички ядра на системата, тя се свързва с процесора сравнително рано. Въпреки че все още имаше достъпни изчисления, беше по-добър в записването от Redis.
  • В крайна сметка и двете бази данни са обвързани с изчисления. Въпреки че Redis е еднонишков, той (предимно) се справя повече с изпълнение на едно ядро, отколкото MongoDB, докато насища всички ядра.
  • Redis , за нетривиални набори от данни, използва много повече RAM в сравнение с MongoDB, за да съхранява същото количество данни.

Конфигурация

Използвахме YCSB за измерване на ефективността и го използвахме за сравняване и сравнение на ефективността на MongoDB при различни доставчици на облак и конфигурации в миналото. Предполагаме основно разбиране на работните натоварвания и функции на YCSB в описанието на тестовата платформа.

  • Тип екземпляр на базата данни:   AWS EC2 c4.xlarge с 4 ядра, 7,5 GB памет и подобрена работа в мрежа, за да гарантираме, че нямаме проблеми с мрежата.
  • Клиентска машина:   AWS EC2 c4.xlarge в същия виртуален частен облак (VPC) като сървърите на база данни.
  • Redis:  Версия 3.2.8 с изключени AOF и RDB. Самостоятелен.
  • MongoDB:  Percona Memory Engine, базиран на MongoDB версия 3.2.12. Самостоятелен.
  • Пропускателна способност на мрежата :  Измерено чрез iperf, както е препоръчано от 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
    
  • Подробности за работното натоварване
    1. Вмъкване на натоварване: 100 % запис – 2,5 милиона записа
    2. Работно натоварване A: Актуализиране на голямо натоварване – 50%/50% четене/записване – 25 милиона операции
    3. Работно натоварване Б: Четене предимно натовареност – 95%/5% четене/записване – 25 милиона операции
  • Зареждане на клиента: Пропускателна способност и латентност, измерени при постепенно нарастващи натоварвания, генерирани от клиента. Това беше направено чрез увеличаване на броя на нишките за зареждане на клиента YCSB, като се започне от 8 и нараства кратно на 2

Резултати

Ефективност на работното натоварване B

Тъй като основният случай на използване на бази данни в паметта е кешът, нека първо да разгледаме работното натоварване B.

Ето числата за пропускателна способност/закъснение от работното натоварване от 25 милиона операции и съотношението на четене/записване е 95%/5%. Това би било представително работно натоварване за четене на кеш:

Забележка:Пропускателната способност е нанесена спрямо основната ос (вляво), докато латентността е нанесена спрямо вторичната ос (вдясно).

Наблюдения по време на изпълнение на работното натоварване B:

  • За MongoDB процесорът беше наситен с 32 нишки нагоре. По-голямо от 300% използване с едноцифрени проценти на празен ход.
  • За Redis използването на процесора никога не е надхвърлило 95%. И така, Redis постоянно постигаше по-добри резултати от MongoDB, докато работеше в една нишка, докато MongoDB насищаше всички ядра на машината.
  • За Redis, при 128 нишки, изпълняването често е неуспешно с изключения за изчакване на изчакване.

Ефективност на работното натоварване

Ето числата за пропускателна способност/закъснение от работното натоварване от 25 милиона операции. Съотношението на четене/записване беше 50%/50%:

Забележка:Пропускателната способност е нанесена спрямо основната ос (вляво), докато латентността е нанесена спрямо вторичната ос (вдясно).

Наблюдения по време на изпълнение на работното натоварване A:

  • За MongoDB процесорът беше наситен с 32 нишки нагоре. По-голямо от 300% използване с едноцифрени проценти на празен ход.
  • За Redis използването на процесора никога не надхвърля 95%.
  • За Redis, с 64 нишки и повече, изпълняването често е неуспешно с изключения за изчакване на изчакване.

Вмъкване на производителност на натоварването

И накрая, тук са числата за пропускателна способност/закъснение от 2,5 милиона работно натоварване за вмъкване на записи. Броят на записите е избран, за да се гарантира, че общата памет е била използвана в събитие Redis, което не надвишава 80% (тъй като Redis е основната памет, вижте Приложение Б).

Забележка:Пропускателната способност е нанесена спрямо основната ос (вляво), докато латентността е нанесена спрямо вторичната ос (вдясно).

Наблюдения по време на изпълнение на вмъкване на работно натоварване:

  • За MongoDB процесорът беше наситен с 32 нишки нагоре. По-голямо от 300% използване с едноцифрени проценти на празен ход.
  • За Redis използването на процесора никога не надхвърля 95%.

Приложения

A:Еднонишкова производителност

Имах силно желание да разбера това – въпреки че не е много полезно в реални условия:кой би бил по-добър, когато прилага едно и също натоварване към всеки от тях от една нишка. Тоест как би се представило еднонишково приложение?

B:Размер на базата данни

Форматът по подразбиране на записите, вмъкнати от YCSB, е:всеки запис е от 10 полета и всяко поле е 100 байта. Ако приемем, че всеки запис е около 1KB, общият очакван размер в паметта ще бъде над 2,4GB. Имаше ярък контраст в действителните размери, както се вижда в базите данни.

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
}

И така, заетото пространство е ~2,7 GB което е доста близо до това, което очаквахме.

Redis

Нека сега да разгледаме 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

При пикова употреба изглежда, че Redis отнема около 5,72G памет, т.е. два пъти повече памет, отколкото заема MongoDB. Сега това сравнение може да не е перфектно поради разликите в двете бази данни, но тази разлика в използването на паметта е твърде голяма, за да се игнорира. YCSB вмъква запис в хеш в Redis и индексът се поддържа в сортиран набор. Тъй като отделният запис е по-голям от 64, хешът се кодира нормално и няма спестяване на пространство. Ефективността на Redis идва на цената на увеличената памет.

Според нас това може да бъде важен момент при избора между MongoDB и Redis – MongoDB може да е за предпочитане за потребители, които се грижат за намаляване на разходите за памет.

C:Пропускателна способност на мрежата

Сървърът на базата данни в паметта може да бъде или свързан към изчисления, или към мрежов I/O, така че беше важно през целия набор от тези тестове да се гарантира, че никога няма да бъдем обвързани с мрежа. Измерването на пропускателната способност на мрежата по време на провеждане на тестове за пропускателна способност на приложенията се отразява неблагоприятно върху цялостното измерване на пропускателната способност. И така, проведохме последващи измервания на пропускателната способност на мрежата, използвайки iftop при броя на нишките, където се наблюдава най-високата пропускателна способност на запис. Установено е, че това е около 440 Mbps както за Redis, така и за MongoDB при съответната им пикова пропускателна способност. Като се има предвид, че първоначалното ни измерване на максималната мрежова честотна лента е около 1,29 Gbps, ние сме сигурни, че никога не достигаме границите на мрежата. Всъщност това само подкрепя извода, че ако Redis беше многоядрен, може да получим много по-добри числа.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Изпълнете R скрипт при стартиране

  2. Парадигма за асинхронно програмиране с nodejs и redis-node

  3. Преобразуване на проста MySQL база данни в NoSQL решение

  4. Каква единица се използва за показване на използването на процесора Redis

  5. Redis свързва ECONNREFUSED в NodeJS в клъстер Kubernetes