<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么 Redis 要比 Memcached 更火?

          共 3485字,需瀏覽 7分鐘

           ·

          2020-09-12 04:31

          前言


          我們都知道,Redis和Memcached都是內存數據庫,它們的訪問速度非常之快。但我們在開發(fā)過程中,這兩個內存數據庫,我們到底要如何選擇呢?它們的優(yōu)劣都有哪些?


          為什么現在看Redis要比Memcached更火一些?


          這篇文章,我們就從各個方面來對比這兩個內存數據庫的差異,方便你在使用時,做出最符合業(yè)務需要的選擇。


          要分析它們的區(qū)別,主要從以下幾個方面對比:


          • 線程模型

          • 數據結構

          • 淘汰策略

          • 管道與事務

          • 持久化

          • 高可用

          • 集群化


          線程模型


          要說性能,必須要分析它們的服務模型。


          Memcached處理請求采用多線程模型,并且基于IO多路復用技術,主線程接收到請求后,分發(fā)給子線程處理。


          這樣做好的好處是,當某個請求處理比較耗時,不會影響到其他請求的處理。


          當然,缺點是CPU的多線程切換必然存在性能損耗,同時,多線程在訪問共享資源時必然要加鎖,也會在一定程度上降低性能。


          Redis同樣采用IO多路復用技術,但它處理請求采用是單線程模型,從接收請求到處理數據都在一個線程中完成。推薦看一下這篇《Redis 到底是單線程還是多線程?》。


          這意味著使用Redis,一旦某個請求處理耗時比較長,那么整個Redis就會阻塞住,直到這個請求處理完成后返回,才能處理下一個請求,使用Redis時一定要避免復雜的耗時操作。


          單線程的好處是,少了CPU的上下文切換損耗,沒有了多線程訪問資源的鎖競爭,但缺點是無法利用CPU多核的性能。


          由于Redis是內存數據庫,它的訪問速度非常地快,所以它的性能瓶頸不在于CPU,而在于內存和網絡帶寬,這也是作者采用單線程模型的主要原因。同時,單線程對于程序開發(fā)非常友好,調試起來也很方便。開發(fā)多線程程序必然會增加一定的調試難度。


          因此,當我們的業(yè)務使用key的數據比較大時,Memcached的訪問性能要比Redis好一些。如果key的數據比較小,兩者差別并不大。

          嚴格來說,Redis的單線程指的是處理請求的線程,它本身還有其他線程在工作,例如有其他線程用來異步處理耗時的任務。


          Redis6.0又進一步完善了多線程,在接收請求和發(fā)送請求時使用多線,進一步提高了處理性能。


          數據結構


          Memcached支持的數據結構很單一,僅支持string類型的操作。并且對于value的大小限制必須在1MB以下,過期時間不能超過30天。


          而Redis支持的數據結構非常豐富,除了常用的數據類型string、list、hash、set、zset之外,還可以使用geo、hyperLogLog數據類型。


          使用Memcached時,我們只能把數據序列化后寫入到Memcached中。然后再從Memcached中讀取數據,再反序列化為我們需要的格式,只能“整存整取”。


          而Redis對于不同的數據結構可以采用不同的操作方法,非常靈活。


          • list:可以方便的構建一個鏈表,或者當作隊列使用

          • hash:靈活地操作我們需要的字段,進行“整存零取”、“零存整取”以及“零存零取”

          • set:構建一個不重復的集合,并方便地進行差集、并集運算

          • zset:構建一個排行榜,或帶有權重的列表

          • geo:用于地圖相關的業(yè)務,標識兩個地點的坐標,以及計算它們的距離

          • hyperLogLog:使用非常少的內存計算UV


          總之,Redis正是因為提供了這么豐富的數據結構,近幾年在內存數據庫領域大放異彩,為我們的業(yè)務開發(fā)提供了極大的便利。


          淘汰策略


          Memcached必須設置整個實例的內存上限,數據達到上限后觸發(fā)LRU淘汰機制,優(yōu)先淘汰不常用使用的數據。


          但它的數據淘汰機制存在一些問題:剛寫入的數據可能會被優(yōu)先淘汰掉,這個問題主要是它本身內存管理設計機制導致的。


          Redis沒有限制必須設置內存上限,如果內存足夠使用,Redis可以使用足夠大的內存。推薦看下《Redis 內存滿了怎么辦》


          同時Redis提供了多種淘汰策略:


          • volatile-lru:從過期key中按LRU機制淘汰

          • allkeys-lru:在所有key中按LRU機制淘汰

          • volatile-random:在過期key中隨機淘汰key

          • allkeys-random:在所有key中隨機淘汰key

          • volatile-ttl:優(yōu)先淘汰最近要過期的key

          • volatile-lfu:在所有key中按LFU機制淘汰

          • allkeys-lfu:在過期key中按LFU機制淘汰


          我們可以針對業(yè)務場景,使用不同的數據淘汰策略。


          管道與事務


          Redis還支持管道功能,客戶端一次性打包發(fā)送多條命令到服務端,服務端依次處理客戶端發(fā)來的命令。這樣可以減少來回往來的網絡IO次數,提供高訪問性能。


          另外它還支持事務,這里所說的事務并不是MySQL那樣嚴格的事務模型,這種事務模型是Redis特有的。


          一般事務會配合管道一塊使用,客戶端一次性打包發(fā)送多條命令到服務端,并且標識這些命令必須嚴格按順序執(zhí)行,不能被其他客戶端打斷。同時執(zhí)行事務之前,客戶端可以告訴服務端某個key稍后會進行相關操作,如果這個客戶端在操作這個key之前,有其他客戶端對這個key進行更改,那么當前客戶端在執(zhí)行這些命令時會放棄整個事務操作,保證一致性。


          持久化


          Memcached不支持數據的持久化,如果Memcached服務宕機,那么這個節(jié)點的數據將全部丟失。


          Redis支持將數據持久化磁盤上,提供RDB和AOF兩種方式:


          • RDB:將整個實例中的數據快照到磁盤上,全量持久化

          • AOF:把每一個寫命令持久到磁盤,增量持久化


          Redis使用這兩種方式相互配合,完成數據完整性保障,最大程度降低服務宕機導致的數據丟失問題。


          高可用


          Memcached沒有主從復制架構,只能單節(jié)點部署,如果節(jié)點宕機,那么該節(jié)點數據全部丟失。業(yè)務需要對這種情況做兼容處理,當某個節(jié)點不可用時,把數據寫入到其他節(jié)點以降低對業(yè)務的影響。


          Redis擁有主從復制架構,兩個節(jié)點組成主從架構,從可以實時同步主的數據,提高整個Redis服務的可用性。


          同時Redis還提供了哨兵節(jié)點,在主節(jié)點宕機時,主動把從節(jié)點提升為主節(jié)點,繼續(xù)提供服務。


          主從兩個節(jié)點還可以提供讀寫分離功能,進一步提高程序訪問的性能。


          集群化


          Memcached和Redis都是由多個節(jié)點組成集群對外提供服務,但他們的機制也有所不同。


          Memcached的集群化是在客戶端采用一致性哈希算法向指定節(jié)點發(fā)送數據,當一個節(jié)點宕機時,其他節(jié)點會分擔這個節(jié)點的請求。


          而Redis集群化采用的是每個節(jié)點維護一部分虛擬槽位,通過key的哈希計算,將key映射到具體的虛擬槽位上,這個槽位再映射到具體的Redis節(jié)點。


          同時每個Redis節(jié)點都包含至少一個從節(jié)點,組成主從架構,進一步提高每個節(jié)點的高可用能力。


          當增加或下線節(jié)點時,需要手動觸發(fā)數據遷移,重新進行哈希槽位映射。


          Redis官方的集群化解決方案為Redis cluster,它采用無中心化的設計。另外也有第三方的采用中心化設計proxy方式的集群化解決方案,例如Codis、Twemproxy。


          總結


          從以上幾個方面進行對比分析,總結如下表。


          #MemcachedRedis
          線程模型多線程單線程
          數據結構僅支持string、value最大1M、過期時間不能超過30天string、list、hash、set、zset、geo、hyperLogLog
          淘汰策略LRULRU、LFU、隨機等多種策略
          管道與事務不支持支持
          持久化不支持支持
          高可用不支持主從復制+哨兵
          集群化客戶端一致性哈希算法主從復制+哨兵+固定哈希槽位


          整體來說,Redis提供了非常豐富的功能,而且性能基本上與Memcached相差無幾,這也是它最近這幾年占領內存數據庫鰲頭的原因。


          如果你的業(yè)務需要各種數據結構給予支撐,同時要求數據的高可用保障,那么選擇Redis是比較合適的。


          如果你的業(yè)務非常簡單,只是簡單的set/get,并且對于內存使用并不高,那么使用簡單的Memcached足夠。


          如果此文章能給您帶來小小的工作效率提升,不妨在看、轉發(fā)一下,以鼓勵我寫出更好的文章!


          推薦閱讀

          阿里精選:Java 代碼精簡之道

          Java8 中用法優(yōu)雅的 Stream,性能也""優(yōu)雅""嗎?

          ElasticSearch 索引 VS MySQL 索引

          還在手動部署SpringBoot應用?試試這個自動化插件!

          MySQL執(zhí)行計劃Explain詳解

          瀏覽 34
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久国产高清视频免费看 | 色婷婷黄色无码视频 | 婷婷爱97 | 国产乱伦毛片张雪馨 | 在线日韩亚洲中文字幕av |