Redis緩存技術介紹

概念

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。

Redis與Memcached的主要區別

Replication(樹形)
data types(String、Lists、Sorted Sets、Hashes)
persistence (snapshot、aof)

很多開發者都認爲Redis不可能比Memcached快,Memcached完全基於內存,而Redis具有持久化保存特性,即使是異步的,Redis也不可能比Memcached快。但是測試結果基本是Redis佔絕對優勢。一直在思考這個原因,目前想到的原因有這幾方面。

Libevent。和Memcached不同,Redis並沒有選擇libevent。Libevent爲了迎合通用性造成代碼龐大(目前Redis代碼還不到libevent的1/3)及犧牲了在特定平臺的不少性能。Redis用libevent中兩個文件修改實現了自己的epoll event loop(4)。業界不少開發者也建議Redis使用另外一個libevent高性能替代libev,但是作者還是堅持Redis應該小巧並去依賴的思路。一個印象深刻的細節是編譯Redis之前並不需要執行./configure。

CAS問題。CAS是Memcached中比較方便的一種防止競爭修改資源的方法。CAS實現需要爲每個cache key設置一個隱藏的cas token,cas相當value版本號,每次set會token需要遞增,因此帶來CPU和內存的雙重開銷,雖然這些開銷很小,但是到單機10G+ cache以及QPS上萬之後這些開銷就會給雙方相對帶來一些細微性能差別(5)。

數據冷熱分離

Redis的數據全部放在內存帶來了高速的性能,但是也帶來一些不合理之處。比如一箇中型網站有100萬註冊用戶,如果這些資料要用Redis來存儲,內存的容量必須能夠容納這100萬用戶。但是業務實際情況是100萬用戶只有5萬活躍用戶,1周來訪問過1次的也只有15萬用戶,因此全部100萬用戶的數據都放在內存有不合理之處,RAM需要爲冷數據買單。

這跟操作系統非常相似,操作系統所有應用訪問的數據都在內存,但是如果物理內存容納不下新的數據,操作系統會智能將部分長期沒有訪問的數據交換到磁盤,爲新的應用留出空間。現代操作系統給應用提供的並不是物理內存,而是虛擬內存(Virtual Memory)的概念。

基於相同的考慮,Redis 2.0也增加了VM特性。讓Redis數據容量突破了物理內存的限制。並實現了數據冷熱分離。

節省內存的操作

作爲一個key value存在,很多開發者自然的使用set/get方式來使用Redis,實際上這並不是最優化的使用方法。尤其在未啓用VM情況下,Redis全部數據需要放入內存,節約內存尤其重要。

假如一個key-value單元需要最小佔用512字節,即使只存一個字節也佔了512字節。這時候就有一個設計模式,可以把key複用,幾個key-value放入一個key中,value再作爲一個set存入,這樣同樣512字節就會存放10-100倍的容量。

這就是爲了節約內存,建議使用hashset而不是set/get的方式來使用Redis

持久化機制

Redis有兩種存儲方式,默認是snapshot方式,實現方法是定時將內存的快照(snapshot)持久化到硬盤,這種方法缺點是持久化之後如果出現crash則會丟失一段數據。因此在完美主義者的推動下作者增加了aof方式。aof即append only mode,在寫入內存數據的同時將操作命令保存到日誌文件,在一個併發更改上萬的系統中,命令日誌是一個非常龐大的數據,管理維護成本非常高,恢復重建時間會非常長,這樣導致失去aof高可用性本意。另外更重要的是Redis是一個內存數據結構模型,所有的優勢都是建立在對內存複雜數據結構高效的原子操作上,這樣就看出aof是一個非常不協調的部分。

其實aof目的主要是數據可靠性及高可用性,在Redis中有另外一種方法來達到目的:Replication。由於Redis的高性能,複製基本沒有延遲。這樣達到了防止單點故障及實現了高可用。

集羣

redis主從複製配置和使用都非常簡單。通過主從複製可以允許多個slave server擁有和master server相同的數據庫副本。下面是關於redis主從複製的一些特點
1.master可以有多個slave
2.除了多個slave連到相同的master外,slave也可以連接其他slave形成圖狀結構
3.主從複製不會阻塞master。也就是說當一個或多個slave與master進行初次同步數據時,master可以繼續處理client發來的請求。相反slave在初次同步數據時則會阻塞不能處理client的請求。
4.主從複製可以用來提高系統的可伸縮性,我們可以用多個slave 專門用於client的讀請求,比如sort操作可以使用slave來處理。也可以用來做簡單的數據冗餘
5.可以在master禁用數據持久化,只需要註釋掉master 配置文件中的所有save配置,然後只在slave上配置數據持久化。
下面介紹下主從複製的過程
當設置好slave服務器後,slave會建立和master的連接,然後發送sync命令。無論是第一次同步建立的連接還是連接斷開後的重新連 接,master都會啓動一個後臺進程,將數據庫快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存起來。後臺進程完成寫文件 後,master就發送文件給slave,slave將文件保存到磁盤上,然後加載到內存恢復數據庫快照到slave上。接着master就會把緩存的命 令轉發給slave。而且後續master收到的寫命令都會通過開始建立的連接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多個 slave發來的同步連接命令,只會使用啓動一個進程來寫數據庫鏡像,然後發送給所有slave。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章