redis和memcached

LingLee_荊棘鳥發表於2017-07-24

1. 使用redis有哪些好處?

(1) 速度快,因為資料存在記憶體中,類似於HashMap,HashMap的優勢就是查詢和操作的時間複雜度都是O(1) 
(2) 支援豐富資料型別,支援string,list,set,sorted set,hash,即任何型別的kv結構
(3) 支援事務,操作都是原子性,所謂的原子性就是對資料的更改要麼全部執行,要麼全部不執行 
(4) 豐富的特性:可用於快取,訊息,按key設定過期時間,過期後將會自動刪除

2. redis相比memcached有哪些優勢?

(1) memcached所有的值均是簡單的字串,Redis作為其替代者,支援更為豐富的資料型別 
(2) redis的速度比memcached快很多 
(3) redis可以持久化其資料

在Redis中,並不是所有的資料都一直儲存在記憶體中的這是和Memcached最大的區別。Redis只會快取所有的 key的資訊,如果Redis發現記憶體的使用量超過了一個閥值,將觸發swap的操作,Redis根據“swappability = age*log(size_in_memory)”計算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在記憶體中清除。這種特性使得Redis可以保持超過其機器本身記憶體大小的資料。當然,機器本身的記憶體必須要能夠保持所有的key,畢竟這些資料是不會進行swap操作的。同時由於Redis將記憶體中的資料swap到磁碟中的時候,提供服務的主執行緒和進行swap操作的子執行緒會共享這部分記憶體,所以如果更新需要swap的資料,Redis將阻塞這個操作,直到子執行緒完成swap操作後才可以進行修改。


當從Redis中讀取資料的時候,如果讀取的key對應的value不在記憶體中,那麼Redis就需要從swap檔案中載入相應資料,然後再返回給請求方。 這裡就存在一個I/O執行緒池的問題在預設的情況下,Redis會出現阻塞,即完成所有的swap檔案載入後才會相應。這種策略在客戶端的數量較小,進行批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程式中,這顯然是無法滿足大併發的情況的。所以Redis執行我們設定I/O執行緒池的大小,對需要從swap檔案中載入相應資料的讀取請求進行併發操作,減少阻塞的時間。

三、Memcache與Redis比較

1網路IO模型

Memcached是多執行緒,非阻塞IO複用的網路模型分為監聽主執行緒和worker子執行緒,監聽執行緒監聽網路連線,接受請求後,將連線描述字pipe 傳遞給worker執行緒,進行讀寫IO, 網路層使用libevent封裝的事件庫,多執行緒模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全域性變數加鎖,進行計數等工作,帶來了效能損耗。


Redis使用單執行緒的IO複用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單執行緒可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單執行緒模型實際會嚴重影響整體吞吐量CPU計算過程中,整個IO排程都是被阻塞住的。

2記憶體管理方面

Memcached使用預分配的記憶體池的方式,使用slab和大小不同的chunk來管理記憶體,Item根據大小選擇合適的chunk儲存,記憶體池的方式可以省去申請/釋放記憶體的開銷,並且能減小記憶體碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在記憶體仍然有很大空間時,新的資料也可能會被剔除,原因可以參考Timyang的文章:http://timyang.NET/data/Memcached-lru-evictions/

Redis使用現場申請記憶體的方式來儲存資料,並且很少使用free-list等方式來優化記憶體分配,會在一定程度上存在記憶體碎片,Redis跟據儲存命令引數,會把帶過期時間的資料單獨存放在一起,並把它們稱為臨時資料,非臨時資料是永遠不會被剔除的即便實體記憶體不夠,導致swap也不會剔除任何非臨時資料(但會嘗試剔除部分臨時資料),這點上Redis更適合作為儲存而不是cache。

3.資料一致性問題

Memcached提供了cas命令,可以保證多個併發訪問操作同一份資料的一致性問題。 Redis沒有提供cas 命令,並不能保證這點,不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。

4.儲存方式及其它方面

Memcached基本只支援簡單的key-value儲存,不支援列舉,不支援持久化和複製等功能

Redis除key/value之外,還支援list,set,sorted set,hash等眾多資料結構,提供了KEYS

進行列舉操作,但不能線上上使用,如果需要列舉線上資料,Redis提供了工具可以直接掃描其dump檔案,列舉出所有資料,Redis還同時提供了持久化和複製等功能。

  5.關於不同語言的客戶端支援

  在不同語言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇,不過因為Memcached發展的時間更久一些,目前看在客戶端支援方面,Memcached的很多客戶端更加成熟穩定,而Redis由於其協議本身就比Memcached複雜,加上作者不斷增加新的功能等,對應第三方客戶端跟進速度可能會趕不上,有時可能需要自己在第三方客戶端基礎上做些修改才能更好的使用。

  根據以上比較不難看出,當我們不希望資料被踢出,或者需要除key/value之外的更多資料型別時,或者需要落地功能時,使用Redis比使用Memcached更合適。

 

3. Memcache與Redis的區別都有哪些?

1)、儲存方式 
Memecache把資料全部存在記憶體之中,斷電後會掛掉,資料不能超過記憶體大小。 
Redis有部份存在硬碟上,swap操作,這樣能保證資料的永續性。 
2)、資料支援型別 
Memcache對資料型別支援相對簡單 key-value。 
Redis有複雜的資料型別 key-value,list,sorted set,hash set。 
3)、使用底層模型不同 
它們之間底層實現方式 以及與客戶端之間通訊的應用協議不一樣。 Redis直接自己構建了VM 機制 ,因為一般的系統呼叫系統函式的話,會浪費一定的時間去移動和請求。

4. redis常見效能問題和解決方案:

(1) Master最好不要做任何持久化工作,如RDB記憶體快照和AOF日誌檔案 
(2) 如果資料比較重要,某個Slave開啟AOF備份資料,策略設定為每秒同步一次 
(3) 為了主從複製的速度和連線的穩定性,Master和Slave最好在同一個區域網內 
(4) 儘量避免在壓力很大的主庫上增加從庫 
(5) 主從複製不要用圖狀結構,用單向連結串列結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3… 
這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

5. mySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料

相關知識:redis 記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰策略。redis 提供 6種資料淘汰策略: 
volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰 
volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選將要過期的資料淘汰 
volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰 
allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰 
allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰 
no-enviction(驅逐):禁止驅逐資料

6. 請用Redis和任意語言實現一段惡意登入保護的程式碼,限制1小時內每使用者Id最多隻能登入5次。

7.總結:

  1.Redis使用最佳方式是全部資料in-memory。

  2.Redis更多場景是作為Memcached的替代者來使用。

  3.當需要除key/value之外的更多資料型別支援時,使用Redis更合適。

  4.當儲存的資料不能被剔除時,使用Redis更合適。

 

 

相關文章