一、複雜資料結構,選擇redis更適合
value是哈希,列表,集合,有序集合這類複雜的資料結構時,會選擇redis,因為mc無法滿足這些需求。
最典型的場景,用戶訂單列表,用戶訊息,貼文評論列表等。
二、持久化,選擇redis更合適
mc無法滿足持久化的需求,只得選擇redis。然而,要注意的是,你真的確保了正確使用了Redis的持久化功能嗎?
千萬不要把redis當作資料庫用:
redis的定期快照不能保證資料不遺失;
redis的AOF會降低效率,並且不能支援太大的資料量;
不要期望redis做固化儲存會比mysql做得好,不同的工具做各自擅長的事情,把redis當作資料庫用,這樣的設計八成是錯誤的。
快取場景,開啟固化功能,有什麼利弊?
如果只是快取場景,資料存放在資料庫,快取在redis,此時如果開啟固化功能:
優點是,redis掛了再重啟,記憶體裡能夠快速恢復熱數據,不會瞬間將壓力壓到資料庫上,沒有一個cache預熱的過程。
缺點是,在redis掛了的過程中,如果資料庫中有資料的修改,可能導致redis重啟後,資料庫與redis的資料不一致。
因此,只讀場景,或允許一些不一致的業務場景,可以嘗試開啟redis的固化功能。
三、高可用,選擇redis更適合
redis天然支援群集功能,可以實現主動複製,讀寫分離。
redis官方也提供了sentinel叢集管理工具,能夠實現主從服務監控,故障自動轉移,這一切,對於客戶端都是透明的,無需程序改動,也無需人工介入。
畫外音:memcache,要想要實現高可用,需要進行二次開發,例如客戶端的雙讀雙寫,或服務端的叢集同步。
但是,這裡要提醒的是,大部分業務場景,快取真的需要高可用麼?
快取場景,很多時候,是允許cache miss;
快取掛了,很多時候可以透過DB讀取資料;
所以,需要認真剖析業務場景,高可用,是否真的是快取的主要需求?
畫外音:即時通訊業務中,使用者的線上狀態,就有高可用需求。
四、儲存的內容比較大,選擇redis比較適合
memcache的value存儲,最大為1M,如果儲存的value很大,只能使用redis 。
當然,redis與memcache相比,由於底層實作機制的差異,也有一些「劣勢」的情況。
情況一:由於記憶體分配機制的差異,redis可能導致記憶體碎片
memcache使用預先分配記憶體池的方式管理內存,能夠省去記憶體分配時間。
redis則是臨時申請空間,可能導致碎片。
從這一點上,mc會更快一些。
情況二:由於虛擬記憶體使用的差異,redis可能會刷盤影響效能
memcache把所有的資料儲存在實體記憶體裡。
redis有自己的VM機制,理論上能夠儲存比實體記憶體更多的數據,當數據超量時,會引發swap,把冷數據刷到磁碟上。從這一點上,當資料量大時,mc會更快一些。
畫外音:新版redis已經最佳化。
情況三:由於網路模型的差異,redis可能會因為CPU運算影響IO調度
memcache使用非阻塞IO復用模型,redis也是使用非阻塞IO復用模型。
但由於redis也提供一些非KV儲存以外的排序,聚合功能,在執行這些功能時,複雜的CPU計算,會阻塞整個IO調度。
從這一點上,由於redis提供的功能較多,mc會更快一些。
情況四:由於執行緒模型的差異,redis難以利用多核心特效提升效能
memcache使用多執行緒,主執行緒監聽,worker子執行緒接受請求,執行讀寫,這個過程中,可能有鎖定衝突。
redis使用單線程,雖無鎖定衝突,但難以利用多核心的特性提升整體吞吐量。
從這一點上,mc會快一些。
情況五:由於缺乏auto-sharding,redis只能手動水平擴展
不管是redis還是memcache,服務端集群沒有天然支援水平擴展,需要在客戶端進行分片,其實對呼叫方並不友善。如果能服務端叢集能夠支援水平擴展,會更完美一些。
最後說一點,可能是很多人喜歡redis的原因之一:原始碼可讀性高,程式碼品質很高。
看過redis和memcache的源碼,從可讀性上說,redis是我見過程式碼最清爽的軟體,甚至沒有之一,或許簡單是redis設計的初衷,編譯redis甚至不需要configure,不需要依賴第三方函式庫,一個make就搞定了。
而memcache源碼,可能是考慮了太多的擴展性,多系統的兼容性,代碼不清爽,看起來費勁。
例如網路IO的部分,redis原始碼1-2個檔案就搞定了,mc使用了libevent,一個fd傳過來傳過去,又pipe又線程傳遞的,特別容易把人繞暈。
以上是什麼時候選Redis的詳細內容。更多資訊請關注PHP中文網其他相關文章!