1. 程式人生 > >【修真院java小課堂】MemCache和Redis的區別

【修真院java小課堂】MemCache和Redis的區別

大家好,我是IT修真院西安分院第三期學員,一枚正直純潔善良的JAVA程式設計師。 今天給大家分享一下,修真院官網JAVA任務六,深度思考中的知識點——MemCache和Redis的區別

一、背景介紹

Memcache和Redis

Memcache :是 danga.com 的一個專案,最早是為 LiveJournal 服務的,目前全世界不少人使用這個快取專案來構建自己大負載的網站,來分擔資料庫的壓力。

Redis:2008年,義大利的一家創業公司Merzia推出了一款基於MySQL的網站實時統計系統 LLOOGG,然而沒過多久該公司的創始人 Salvatore Sanfilippo 便對MySQL 的效能感到失望,於是他決定親自為 LLOOGG 量身定做一個 資料庫,並並於 2009 年開發完成,這個資料庫就是Redis。

Redis 和 Memcache 都是基於記憶體的資料儲存系統。Memcached是高效能分散式記憶體快取服務;Redis是一個開源的key-value儲存系統。 與Memcached類似,Redis將大部分資料儲存在記憶體中,支援的資料型別包括:字串、雜湊 表、連結串列、等資料型別的相關操作。

MemCache:

MemCache是一個自由、原始碼開放、高效能、分散式的分散式記憶體物件快取系統,用於動態Web應用以減輕資料庫的負載。它通過在記憶體中快取資料和物件來減少讀取資料庫的次數,從而提高了網站訪問的速度。

二、知識剖析

MemCache和Redis的區別

(1)資料型別支援不同

(2)記憶體管理機制不同

(3)資料持久化支援

(4)叢集管理的不同

2.1.資料型別支援不同

(1) Redis和Memcache都是將資料存放在記憶體中,都是記憶體資料庫。不過memcache還可用快取其他東西,例如圖片、視訊等等

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

2.2記憶體管理機制不同

MemCache: memcache使用slab allocator機制來記憶體管理。

slab allocator原理:先將記憶體劃分為多個slab class倉庫,每個倉庫切分成不同尺寸的小塊chunk。需要儲存內容時候,判斷內容大小,為其選擇合理的倉庫;

Redis:底層實現通過對malloc/free進行封裝來實現,通過儲存資料的size,來申請一段連續的記憶體空間;

Redis通過定義一個數組來記錄所有的記憶體分配情況,這個陣列的長度為ZMALLOC_MAX_ALLOC_STAT。陣列的每一個元素代表當前程式所分配的記憶體塊的個數,且記憶體塊的大小為該元素的下標。在原始碼中,這個陣列為zmalloc_allocations。zmalloc_allocations[16]代表已經分配的長度為16bytes的記憶體塊的個數。

2.3資料儲存及持久化

memcached不支援記憶體資料的持久化操作,所有的資料都以in-memory的形式儲存。

redis支援持久化操作。redis提供了兩種不同的持久化方法來講資料儲存到硬盤裡面,一種是快照(snapshotting),它可以將存在於某一時刻的所有資料都寫入硬盤裡面。另一種方法叫只追加檔案(append-only file, AOF),它會在執行寫命令時,將被執行的寫命令複製到硬盤裡面。

2.4叢集管理不同

Memcached本身並不支援分散式,因此只能在客戶端通過像一致性雜湊這樣的分散式演算法來實現Memcached的分散式儲存。

相較於Memcached只能採用客戶端實現分散式儲存,Redis更偏向於在伺服器端構建分散式儲存。Redis本身提供叢集服務的。

三、常見問題

Memcache和Redis叢集對比簡介

四、解決方案

Memcache和Redis叢集對比簡介

Memcache:

Memcached本身並不支援分散式,因此只能在客戶端通過像一致性雜湊這樣的分散式演算法來實現Memcached的分散式儲存。

當客戶端向Memcached叢集傳送資料之前,首先會通過內建的分散式演算法計算出該條資料的目標節點,然後資料會直接傳送到該節點上儲存。但客戶端查詢資料時,同樣要計算出查詢資料所在的節點,然後直接向該節點發送查詢請求以獲取資料。

Redis官方叢集方案 Redis Cluster

Redis Cluster是一種伺服器Sharding技術,3.0版本開始正式提供。對客戶端來說,整個cluster被看做是一個整體,客戶端可以連線任意一個node進行操作,就像操作單一Redis例項一樣,當客戶端操作的key沒有分配到該node上時,就像操作單一Redis例項一樣,當客戶端操作的key沒有分配到該node上時,Redis會返回轉向指令,指向正確的node。

總體來說,

MemCache在客戶端通過hash演算法,根據key把資料發往不同的memcached伺服器端;

Redis將所有的資料發往Redis伺服器端的叢集,由Redis叢集自動儲存到相應的節點;

五、編碼實戰

六、擴充套件思考

redis的持久化方法

redis提供了兩種不同的持久化方法來講資料儲存到硬盤裡面,一種是快照(snapshotting),它可以將存在於某一時刻的所有資料都寫入硬盤裡面。另一種方法叫只追加檔案(append-only file, AOF),它會在執行寫命令時,將被執行的寫命令複製到硬盤裡面。

快照(snapshotting):通過save命令,以下為預設

save 900 1   //對redis資料只進行1次修改,間隔900s寫入硬碟
save 300 10  //對redis資料進行10次修改,間隔300s寫入硬碟
save 60 10000

最後生成rdb檔案,寫在硬碟上;

只追加檔案(append-only file, AOF):預設不開啟。

appendonly no

以下為預設設定:

# appendfsync always
appendfsync everysec
# appendfsync no

七、參考文獻

https://blog.csdn.net/u011489043/article/details/78922390

https://www.cnblogs.com/_popc/p/5968683.html

8.更多討論

1、MemCache和Redis效能對比

由於 Redis 只使用單核,而 Memcached 可以使用多核,所以平均每一個核上 Redis 在儲存小資料時比 Memcached 效能更高。而在 100k 以上的資料中,Memcached 效能要高於 Redis,雖然 Redis 最近也在儲存大資料的效能上進行優化,但是比起 Memcached,還是稍有遜色

Memcache多執行緒,Redis單執行緒,處理資料較小沒有太大區別;單執行緒模型會嚴重影響整體吞吐量,CPU計算過程中,整個IO排程都是被阻塞的。

2、MemCache記憶體分配

  Memcached在啟動時通過-m引數指定最大使用記憶體,但是這個不會一啟動就佔用完,而是逐步分配給各slab的。如果一個新的資料要被存放,首先選擇一個合適的slab,然後檢視該slab是否還有空閒的chunk,如果有則直接存放進去;如果沒有則要進行申請,slab申請記憶體時以page為單位,無論大小為多少,都會有1M大小的page被分配給該slab(該page不會被回收或者重新分配,永遠都屬於該slab)。申請到page後,slab會將這個page的記憶體按chunk的大小進行切分,這樣就變成了一個chunk的陣列,再從這個chunk陣列中選擇一個用於儲存資料。若沒有空閒的page的時候,則會對改slab進行LRU,而不是對整個memcache進行LRU。

3、什麼叫MemCached不支援分散式,Redis支援叢集服務?    

都是針對伺服器端的,Redis3.0正式支援叢集服務,通過配置檔案中的:

#是否使用叢集----yes
cluster-enabled yes

感謝觀看,如有出錯,懇請指正