2015/2/2

memcached or redis ?

在選擇 cache 系統時,傳統會使用 memcached,但現在有另一個選擇就是 redis,這兩個 cache server 主要的功能就是在記憶體中暫存資料,用以加速網站資料處理的效能,兩個都是儲存 key-value 的資料結構,且都是存放在記憶體中。

Memcached or Redis ?

Why Redis beats Memcached for caching 這篇文章提出了討論,什麼時候該用 memcached,而什麼時候該用 redis。

memcached 相對於 redis 是比較年長的 server,因此 redis 的功能比較多,在大多數的時候都是比較好的選擇。但還是有兩種用途,建議使用 memcached (1) caching small and static data,例如 html code fragment,因為memcached 內部比較簡單,處理單純的字串效率更好一些 (2) horizontal scaling,但未來這個部份將會隨著 redis 3.0 內建了 cluster 以及 auto sharding 的功能而有不同的結果。

memcached 使用 LRU(Least Recently Used) algorithm 作為刪除舊資料的基準,redis 允許使用者選擇 6 種 data eviction policies。memcached 限制 key 上限為 250 bytes,value上限為 1MB,只能處理 string,redis 允許 key 與 value 上限各達到 512MB,可以儲存 binary data,共支援 6 種data types。

redis 支援資料的 replication,搭配 sentinel 服務,可自動偵測所有 master-slave server 的狀態,並自動切換 master node。

因為 redis 是單執行緒執行的 daemon,disk/memory/netowrk IO 序列化的條件下,如果資料量太大,就需要等待 IO 處理的時間,在一個 CPU 且資料不大的情況下,效能比 memcached 好,memcached 本身就是多執行緒的,單一個 daemon 就可直接使用多個 CPU 與多個 TCP Ports。

High Availability

考量到 HA 的議題,要思考兩點 (1) data availability (2) service availability,以目前 2.8 版的狀況,redis 支援 data replication,針對 service availabilty 也提供了sentinel做 redis daemon 的監控。

站在備援的角度來看,因為 redis 內建了 replication 機制,可存放的資料型別比較多,而老牌的 memcached 並沒有在 replication 上多做著墨,要不然就得選擇使用支援非同步 data replication 的 repcached

cache 需不需要備援

cache 本身並不是最終儲存資料的地方,它的存在單純是為了效能考量,簡單地說,通常網頁都直接去資料庫取得資料並顯示在畫面上,假設是顯示公告的頁面,如果目前網頁只有 1~5 個人去瀏覽,同一時間內 5 個人瀏覽就等於要透過網路向資料庫取得公告 5 次。

但如果同一時間內增加到 100人 甚至是 1000 人去瀏覽公告,資料庫在瞬間就必須承受 100 ~ 1000 個連線的流量,而且這 1000個取得的資料都是一樣的,這明顯是個資源與效能的浪費。

cache 的作用在於暫存常用的資料,如果在記憶體中沒有這個資料,就會去向資料庫取得,並存放到 cache 中。以這個角度來看,cache 究竟需不需要 replication 備援,似乎不是那麼重要的事情。應該這樣說,如果 cache daemon 的資料備援,並不因此影響到過多本身提供服務的效率,分配些許資源去進行 replication。

但這樣的假設,奠基於 Web Application Server 前面的 Load Balancer 採用了 sticky session 的流量分享策略,如果是不需要登入,沒有 server side session 的情況,cache 的 replication 重要性就會拉高,因為 Load Balancer 平均分攤網路 request 到多個 web application server 之後,取得了相同的資料,不同的 application server 使用到相同資料的機會大增。

因此 cache server 有沒有支援 data replication 的重要性,取決於應用程式系統中,到底是不是跨使用者之間使用到了大量相同的資料,如果是這樣的話,那麼 cache replication 就會比較重要。

cache 需不需要 sharding

單一 cache daemon 不管是記憶體或是網路頻寬的限制,都有對外提供服務能力的上限,資料 sharding 對一個服務超級大量資料的系統來說是重要的,但以一般的網站服務來說,因為需要進入 cache 的資料量沒那麼多,似乎重要性還就沒那麼高了。

memcached 的 sharding 必須由 application 自行處理,這種情況就像是使用 MySQL 一樣,Application 必須依照自己的資料的特性,自行決定要以什麼方式進行 data sharding。

redis 3.0 版支援 cluster,但目前還在 alpha 階段,redis cluster 會做資料的 auto sharding,這意味著資料並不會儲存在所有 redis 節點上,而是以多數決的方式進行。

如果願意以一些系統效能,換來簡易的 data sharding 機制,用這樣的想法,就可以使用 redis。

結論

Memcached vs. Redis不同key大小性能測試報告 的結果似乎也證實了這個想法,當 redis 啟用了 disk persistence 之後,會造成效能下降,另外當 redis 達到 memory 上限之後,效能會急速下降,而且這份測試報告測試的資料是比較小的,所以大部分的結果都是 memcached 效能比較好。

memcached 比較像是個短小精幹的螺絲釘,它將自己的目標定位在高效率的 cache,redis 在追求高效率的同時,為了增加自己面對 memcached 的優勢,所以支援了 binary data,支援了多種資料型別,做了 replicaiton 還有 cluster 的功能,換句話說,也等於是以一些系統效能換來了增強的功能。

如果有多種資料型別要儲存,那就選擇 redis,至於一般字串的情況,還是選擇 memcached 就好了。不過未來當 redis 的 sharding 穩定後,如果能靠這個功能,簡化使用 memcached 的 client 實做 sharding 功能的負擔,或許會有不同的情況。