天天看點

memcache和redis差別

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/qq_34173549/article/details/80612867

我這段時間在用

Redis

,感覺挺友善的,但比較疑惑在選擇記憶體

資料庫

的時候到底什麼時候選擇redis,什麼時候選擇memcache,然後就查到下面對應的資料,是來自redis作者的說法(stackoverflow上面)。

    You should not care too much about performances. Redis is faster per core with small values, but memcached is able to use multiple cores with a single executable and TCP port without help from the client. Also memcached is faster with big values in the order of 100k. Redis recently improved a lot about big values (unstable branch) but still memcached is faster in this use case. The point here is: nor one or the other will likely going to be your bottleneck for the query-per-second they can deliver.

    You should care about memory usage. For simple key-value pairs memcached is more memory efficient. If you use Redis hashes, Redis is more memory efficient. Depends on the use case.

    You should care about persistence and replication, two features only available in Redis. Even if your goal is to build a cache it helps that after an upgrade or a reboot your data are still there.

    You should care about the kind of operations you need. In Redis there are a lot of complex operations, even just considering the caching use case, you often can do a lot more in a single operation, without requiring data to be processed client side (a lot of I/O is sometimes needed). This operations are often as fast as plain GET and SET. So if you don’t need just GEt/SET but more complex things Redis can help a lot (think at timeline caching).

    有網友翻譯如下[1]:

    沒有必要過多的關注性能。由于Redis隻使用單核,而Memcached可以使用多核,是以在比較上,平均每一個核上Redis在存儲小資料時比Memcached性能更高。而在100k以上的資料中,Memcached性能要高于Redis,雖然Redis最近也在存儲

大資料

的性能上進行優化,但是比起Memcached,還是稍有遜色。說了這麼多,結論是,無論你使用哪一個,每秒處理請求的次數都不會成為瓶頸。

    你需要關注記憶體使用率。對于key-value這樣簡單的資料儲存,memcache的記憶體使用率更高。如果采用hash結構,redis的記憶體使用率會更高。當然,這些都依賴于具體的應用場景。

    你需要關注關注資料持久化和主從複制時,隻有redis擁有這兩個特性。如果你的目标是建構一個緩存在更新或者重新開機後之前的資料不會丢失的話,那也隻能選擇redis。

    你應該關心你需要的操作。redis支援很多複雜的操作,甚至隻考慮記憶體的使用情況,在一個單一操作裡你常常可以做很多,而不需要将資料讀取到用戶端中(這樣會需要很多的IO操作)。這些複雜的操作基本上和純GET和POST操作一樣快,是以你不隻是需要GET/SET而是更多的操作時,redis會起很大的作用。

    對于兩者的選擇還是要看具體的應用場景,如果需要緩存的資料隻是key-value這樣簡單的結構時,我在項目裡還是采用memcache,它也足夠的穩定可靠。如果涉及到存儲,排序等一系列複雜的操作時,毫無疑問選擇redis。

    關于redis和memcache的不同,下面羅列了一些相關說法,供記錄:

    redis和memecache的不同在于[2]:

    1、存儲方式:

    memecache 把資料全部存在記憶體之中,斷電後會挂掉,資料不能超過記憶體大小

    redis有部份存在硬碟上,這樣能保證資料的持久性,支援資料的持久化(筆者注:有快照和AOF日志兩種持久化方式,在實際應用的時候,要特别注意配置檔案快照參數,要不就很有可能伺服器頻繁滿載做dump)。

    2、資料支援類型:

    redis在資料支援上要比memecache多的多。

    3、使用底層模型不同:

    新版本的redis直接自己建構了VM 機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。

    4、運作環境不同:

    redis目前官方隻支援

Linux

 上去行,進而省去了對于其它系統的支援,這樣的話可以更好的把精力用于本系統 環境上的優化,雖然後來微軟有一個小組為其寫了更新檔。但是沒有放到主幹上

memcach簡介

Memcache時一個記憶體對象緩存系統,用于加速動态web應用程式,減輕資料庫負載。它可以應對任意多個連接配接,使用非阻塞的網絡I/O,

工作機制:

在記憶體中開辟一塊空間,然後建立一個hash表,memcached自管理這些hash表

工作原理

Memcached基于健值對存儲,key會通過hash算法轉化成hash-key,便于查找。

Memcached有兩個核心元件組成:服務端(server)和用戶端,在一個memcached的查詢中,用戶端會先計算key的hash值來确定所出的server位置。當server确定以後,用戶端對就會發送一個查詢請求給對應的server,讓它查找确切的資料。

記憶體管理機制

emcached會預先配置設定記憶體,

Memcached使用預配置設定的記憶體池的方式,使用slab和大小不同的chunk來管理記憶體,ltem根據大小選擇合适的chunk存儲,記憶體池的方式可以省去申請/釋放記憶體的開銷,并且減少記憶體碎片的産生,但這種方式也會帶來一定程度上的空間浪費

memcache與redis差別

1)redis不僅僅支援簡單的k/v類型的資料,同時還提供list,set,hash等資料結構的存儲

2)記憶體使用使用效率對比

使用簡單的key-value存儲的話,memcached的記憶體使用率會更高一點,如果redis采用hash結構來做key-value存儲,由于其組合式的壓縮,記憶體的使用率更高。

3)性能對比:由于redis隻使用單核,而memcached使用多核,是以平均在每一個核上redis在存儲小資料時比memcached性能更高,而在100Ks=以上的時候memcached性能要高于redis

4)記憶體管理機制的不同

在redis中,并不是所有的資料都一一直存儲在記憶體中的,這是和memcached相比最大的一個差別

Redis隻會緩存所有的key端的資訊,如果redis發現記憶體的使用量超過某一個值,将觸發swap的操作,redis根據相應的表達式計算出那些key對應value需要swap到磁盤,然後再将這些這些key對應的value持久化到磁盤中,同時再記憶體清除。同時由于redis将記憶體中的資料swap到磁盤的時候,提供服務的主線程和進行swap操作的子程序會共享這部分記憶體,是以如果更新需要swap的資料,redis将阻塞這個操作,直到子線程完成swap操作後才可以進行修改

5)資料持久化的支援

雖然redis是基于記憶體的存儲系統,但是他本身是支援記憶體資料的持久化,而且主要提供兩種主要的持久化政策,RDB快照和AOF日志,而memcached是不支援資料持久化的操作的。

RDB持久化通過儲存了資料庫的健值對來記錄資料庫狀态的不同,AOF持久化是通過儲存reds伺服器所執行的指令來儲存記錄資料庫的狀态的,

RDB持久化儲存資料庫狀态的方法是将msg,fruits,numbers三個健的健值對儲存到RDB檔案中,而AOF持久化儲存資料庫的狀态則是将伺服器執行的SET,SADD,RPUSH三個指令儲存到AOF檔案中的,

RDB快照

redis支援将目前的資料快照存放成一個資料檔案的持久化機制,即RDB快照,但是一個持續寫入的資料庫是如何生成快照的,

在生成快照的時候,将目前的程序fork出一個子程序,然後在子程序中循環所有的資料,将資料寫成RDB檔案。我們可以通過redis的slave指令來配置RDB快照生成的時機。RDB檔案不會壞掉,因為其寫操作是在一個新程序中進行的,當生成一個新的RDB檔案時redis生成的子程序會先将資料寫到一個臨時檔案中,然後通過原子性rename系統調用将臨時檔案重命名為RDB檔案。

AOF持久化的實作

OF持久化的實作可以分為指令追擊(append),檔案寫入,檔案同步(sync)

1)指令追加

當AOF持久化功能打開的時候,伺服器在執行完一個寫指令的時候,會以協定的格式将被執行的寫指令追加到伺服器狀态的aof_buf緩沖區的末尾

2)AOF檔案的寫入與同步

伺服器在處理檔案事件時可能會執行寫指令,使得一些内容被追加到aof_buf緩沖區裡面,是以伺服器在每次結束一個事件循環之前,它都會調用flushAppendonlyFIle函數考慮是否需要将将緩沖區的内容寫入和儲存到AOF檔案裡面。如果函數被調用,并且距離上次同步AOF檔案已經超過了一秒鐘,那麼伺服器會先将aof_buf中的内容寫入到AOF檔案中,然後再對AOF檔案進行同步

3)檔案的載入與資料還原

4)AOF重寫

AOF持久化儲存的指令越來越多,檔案裡的内容也月來越多,會對計算機造成影響。為了解決AOF檔案體積膨脹問題,REDIS提供了AOF重寫功能。Redis伺服器可以建立一個新的AOF檔案,新舊兩個AOF檔案儲存的資料狀态相同,但新AOF檔案不會包含任何浪費空間的備援指令,是以新的AOF會比舊的體積要小