Dalam postingan ini, kami membandingkan dua database NoSQL paling populer:Redis (dalam memori) dan MongoDB (mesin penyimpanan memori Percona).
Redis adalah penyimpanan struktur database dalam memori yang populer dan sangat cepat yang terutama digunakan sebagai cache atau perantara pesan. Berada dalam memori, ini adalah penyimpanan data pilihan saat waktu respons mengalahkan segalanya.
MongoDB adalah penyimpanan dokumen di disk yang menyediakan antarmuka JSON ke data dan memiliki bahasa kueri yang sangat kaya. Dikenal karena kecepatan, efisiensi, dan skalabilitasnya, saat ini database NoSQL paling populer digunakan saat ini. Namun, sebagai basis data pada disk, ia tidak dapat dibandingkan dengan basis data dalam memori seperti Redis dalam hal kinerja absolut. Namun, dengan tersedianya mesin penyimpanan dalam memori untuk MongoDB, perbandingan yang lebih langsung menjadi mungkin.
Mesin Memori Percona untuk MongoDB
Mulai di versi 3.0, MongoDB menyediakan API untuk menyambungkan mesin penyimpanan pilihan Anda. Mesin penyimpanan, dari konteks MongoDB, adalah komponen database yang bertanggung jawab untuk mengelola bagaimana data disimpan, baik di dalam memori maupun di dalam disk. MongoDB mendukung mesin penyimpanan dalam memori, namun saat ini terbatas pada produk edisi Enterprise. Pada tahun 2016, Percona merilis mesin dalam memori open source untuk MongoDB Community Edition yang disebut Percona Memory Engine untuk MongoDB. Seperti mesin dalam memori MonogDB, ini juga merupakan variasi dari mesin penyimpanan WiredTiger, tetapi tanpa persistensi ke disk.
Dengan adanya mesin penyimpanan MongoDB di dalam memori, kami memiliki medan permainan yang setara antara Redis dan MongoDB. Jadi, mengapa kita perlu membandingkan keduanya? Mari kita lihat keunggulan masing-masing sebagai solusi caching.
Mari kita lihat Redis dulu.
Keuntungan Redis sebagai Cache
- Solusi caching terkenal yang unggul dalam hal itu.
- Redis bukanlah solusi cache biasa – ia memiliki struktur data lanjutan yang menyediakan banyak cara canggih untuk menyimpan dan membuat kueri data yang tidak dapat dicapai dengan cache nilai kunci vanilla.
- Redis cukup mudah untuk disiapkan, digunakan, dan dipelajari.
- Redis memberikan kegigihan yang dapat Anda pilih untuk disiapkan, jadi pemanasan cache jika terjadi error tidak akan merepotkan.
Kekurangan Redis:
- Tidak memiliki enkripsi bawaan pada kabel.
- Tidak ada kontrol akun berbasis peran (RBAC).
- Tidak ada solusi pengelompokan yang matang dan mulus.
- Akan sulit untuk diterapkan dalam penerapan cloud skala besar.
Keuntungan MongoDB sebagai Cache
- MongoDB adalah database yang lebih tradisional dengan fitur manipulasi data lanjutan (pikirkan agregasi dan pengurangan peta) dan bahasa kueri yang kaya.
- SSL, RBAC, dan scale-out bawaan.
- Jika Anda sudah menggunakan MongoDB sebagai database utama, maka biaya operasional dan pengembangan Anda akan turun karena Anda hanya memiliki satu database untuk dipelajari dan dikelola.
Lihat postingan dari Peter Zaitsev ini tentang di mana mesin dalam memori MongoDB mungkin cocok.
Kerugian MongoDB:
- Dengan mesin dalam memori, ia tidak menawarkan persistensi hingga diterapkan sebagai set replika dengan persistensi yang dikonfigurasi pada replika baca.
Dalam postingan ini, kami akan fokus untuk mengukur perbedaan kinerja antara Redis dan MongoDB . Perbandingan kualitatif dan perbedaan operasional akan dibahas dalam posting berikutnya.
Redis vs. MongoDB Dalam Memori
Kinerja
- Kinerja Redis jauh lebih baik untuk pembacaan untuk semua jenis beban kerja, dan lebih baik untuk menulis saat beban kerja meningkat.
- Meskipun MongoDB menggunakan semua inti sistem, itu membuat CPU terikat relatif lebih awal. Meskipun masih memiliki komputasi yang tersedia, itu lebih baik dalam menulis daripada Redis.
- Kedua database pada akhirnya terikat dengan komputasi. Meskipun Redis adalah single-threaded, ini (kebanyakan) menyelesaikan lebih banyak hal dengan menjalankan satu inti daripada yang dilakukan MongoDB saat menjenuhkan semua inti.
- Redis , untuk kumpulan data non-trivial, menggunakan lebih banyak RAM dibandingkan dengan MongoDB untuk menyimpan jumlah data yang sama.
Konfigurasi
Kami menggunakan YCSB untuk mengukur performa, dan telah menggunakannya untuk membandingkan dan membandingkan kinerja MongoDB di berbagai penyedia dan konfigurasi cloud di masa lalu. Kami mengasumsikan pemahaman dasar tentang beban kerja dan fitur YCSB dalam deskripsi rig pengujian.
- Jenis instance database: AWS EC2 c4.xlarge menampilkan 4 core, memori 7,5 GB, dan jaringan yang ditingkatkan untuk memastikan kami tidak mengalami kemacetan jaringan.
- Mesin Klien: AWS EC2 c4.xlarge di virtual private cloud (VPC) yang sama dengan server database.
- Redis: Versi 3.2.8 dengan AOF dan RDB dimatikan. Mandiri.
- MongoDB: Percona Memory Engine berdasarkan MongoDB versi 3.2.12. Mandiri.
- Troughput Jaringan : Diukur melalui iperf seperti yang direkomendasikan oleh 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
- Detail Beban Kerja
- Masukkan Beban Kerja: 100% Tulis – 2,5 juta catatan
- Beban Kerja A: Perbarui beban kerja berat – 50%/50% Baca/Tulis – 25 juta operasi
- Beban Kerja B: Sebagian besar beban kerja baca – 95%/5% Baca/Tulis – 25 juta operasi
- Pemuatan Klien: Throughput dan latensi diukur melalui peningkatan beban yang dihasilkan dari klien secara bertahap. Ini dilakukan dengan meningkatkan jumlah utas pemuatan klien YCSB, mulai dari 8 dan bertambah dalam kelipatan 2
Hasil
Kinerja Beban Kerja B
Karena kasus penggunaan utama untuk database dalam memori adalah cache, mari kita lihat Beban Kerja B terlebih dahulu.
Berikut adalah angka throughput/latency dari 25 juta beban kerja operasi dan rasio baca/tulis adalah 95%/5%. Ini akan menjadi beban kerja pembacaan cache yang representatif:
Catatan:Throughput diplot terhadap sumbu utama (kiri), sedangkan latensi diplot terhadap sumbu sekunder (kanan).
Pengamatan selama Beban Kerja B dijalankan:
- Untuk MongoDB, CPU dipenuhi oleh 32 utas dan seterusnya. Lebih dari 300% penggunaan dengan persentase menganggur satu digit.
- Untuk Redis, penggunaan CPU tidak pernah melampaui 95%. Jadi, Redis secara konsisten berperforma lebih baik daripada MongoDB saat berjalan di satu utas, sementara MongoDB memenuhi semua inti mesin.
- Untuk Redis, pada 128 utas, proses sering gagal dengan pengecualian batas waktu baca.
Beban Kerja Sebuah Performa
Berikut adalah angka throughput/latency dari 25 juta beban kerja operasi. Rasio baca/tulis adalah 50%/50%:
Catatan:Throughput diplot terhadap sumbu utama (kiri), sedangkan latensi diplot terhadap sumbu sekunder (kanan).
Pengamatan selama Beban Kerja A dijalankan:
- Untuk MongoDB, CPU dipenuhi oleh 32 utas dan seterusnya. Lebih dari 300% penggunaan dengan persentase menganggur satu digit.
- Untuk Redis, penggunaan CPU tidak pernah melampaui 95%.
- Untuk Redis, dengan 64 utas ke atas, proses sering gagal dengan pengecualian batas waktu baca.
Sisipkan Kinerja Beban Kerja
Terakhir, berikut adalah angka throughput/latency dari 2,5 juta beban kerja penyisipan record. Jumlah record dipilih untuk memastikan total memori yang digunakan saat Redis tidak melebihi 80% (karena Redis adalah memory hog, lihat Lampiran B).
Catatan:Throughput diplot terhadap sumbu utama (kiri), sedangkan latensi diplot terhadap sumbu sekunder (kanan).
Pengamatan selama menjalankan Insert Workload:
- Untuk MongoDB, CPU dipenuhi oleh 32 utas dan seterusnya. Lebih dari 300% penggunaan dengan persentase menganggur satu digit.
- Untuk Redis, penggunaan CPU tidak pernah melampaui 95%.
Lampiran
J:Performa Utas Tunggal
Saya memiliki keinginan yang kuat untuk mengetahui hal ini – meskipun tidak terlalu berguna dalam kondisi dunia nyata:siapa yang akan lebih baik jika menerapkan beban yang sama ke masing-masing dari mereka dari satu utas. Yaitu, bagaimana kinerja aplikasi utas tunggal?
B:Ukuran Basis Data
Format default catatan yang dimasukkan oleh YCSB adalah:setiap catatan terdiri dari 10 bidang dan setiap bidang berukuran 100 byte. Dengan asumsi setiap record sekitar 1KB, total ukuran memori yang diharapkan akan lebih dari 2,4GB. Ada perbedaan mencolok dalam ukuran sebenarnya seperti yang terlihat di database.
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 }
Jadi, ruang yang digunakan adalah ~2,7 GB yang cukup mendekati yang kami harapkan.
Merah
Mari kita lihat Redis sekarang.
> 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
Pada penggunaan puncak, Redis tampaknya menggunakan sekitar 5,72G memori yaitu memori dua kali lebih banyak dari yang dibutuhkan MongoDB. Sekarang, perbandingan ini mungkin tidak sempurna karena perbedaan dalam dua database, tetapi perbedaan dalam penggunaan memori ini terlalu besar untuk diabaikan. YCSB menyisipkan catatan dalam hash di Redis, dan indeks dipertahankan dalam kumpulan yang diurutkan. Karena entri individu lebih besar dari 64, hash dienkode secara normal dan tidak ada penghematan ruang. Kinerja Redis harus dibayar dengan peningkatan jejak memori.
Menurut kami, ini dapat menjadi titik data penting dalam memilih antara MongoDB dan Redis – MongoDB mungkin lebih disukai bagi pengguna yang ingin mengurangi biaya memori mereka.
C:Throughput Jaringan
Server database dalam memori bertanggung jawab untuk terikat pada komputasi atau jaringan I/O-terikat, jadi penting di seluruh rangkaian pengujian ini untuk memastikan bahwa kami tidak pernah terikat jaringan. Mengukur throughput jaringan saat menjalankan tes throughput aplikasi berdampak buruk pada pengukuran throughput secara keseluruhan. Jadi, kami menjalankan pengukuran throughput jaringan berikutnya menggunakan iftop pada jumlah thread di mana throughput tulis tertinggi diamati. Ini ditemukan sekitar 440 Mbps untuk Redis dan MongoDB pada throughput puncak masing-masing. Mengingat pengukuran awal bandwidth jaringan maksimum kami adalah sekitar 1,29 Gbps, kami yakin bahwa kami tidak pernah mencapai batas jaringan. Faktanya, ini hanya mendukung kesimpulan bahwa jika Redis adalah multi-core, kita mungkin mendapatkan angka yang jauh lebih baik.