Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key-value存儲的不足,在部 分場合可以對關係數據庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。
一、Redis使用場景:
1. 按照我們一般的使用Redis的場景應該是這樣的:
也就是說:我們會先去redis中判斷數據是否存在,如果存在,則直接返回緩存好的數據。而如果不存在的話,就會去數據庫中,讀取數據,並把數據緩存到Redis中。
適用場合:如果數據量比較大,但不是經常更新的情況(比如用戶排行)
2. 而第二種Redis的使用,跟第一種的情況完成不同,具體的情況請看:
這裏我們會先去redis中判斷數據是否存在,如果存在,則直接更新對應的數據(這一步會把對應更新過的key記錄下來,比如也保存到redis中比如:key爲:save_update_keys【用lpush列表記錄】),並把更新後的數據返回給頁面。而如果不存在的話,就會去先更新數據庫中內容,然後把數據保存一份到Redis中。後面的工作:後臺會有相關機制把Redis中的save_update_keys存儲的key,分別讀取出來,找到對應的數據,更新到DB中。
- 優點:這個流程的主要目的是把Redis當作數據庫使用,更新獲取數據比DB快。非常適合大數據量的頻繁變動(比如微博)。
- 缺點:對Redis的依賴很大,要做好宕機時的數據保存。(不過可以使用redis的快照AOF,快速恢復的話,應該不會有多大影響,因爲就算Redis不工作了,也不會影響後續數據的處理。)
- 難點:在前期規劃key的格式,存儲類型很重要,因爲這會影響能否把數據同步到DB。
二、redis啓動流程
- 1.初始化server變量,設置redis相關的默認值
- 2.讀入配置文件,同時接收命令行中傳入的參數,替換服務器設置的默認值
- 3.初始化服務器功能模塊。在這一步初始化了包括進程信號處理、客戶端鏈表、共享對象、初始化數據、初始化網絡連接等
- 4.從RDB或AOF重載數據
- 5.網絡監聽服務啓動前的準備工作
- 6.開啓事件監聽,開始接受客戶端的請求
- a)保存(rdbSave):rdbSave負責將內存中的數據庫數據以RDB格式保存到磁盤中,如果RDB文件已經存在將會替換已有的RDB文件。保存RDB文件期間會阻塞主進程,這段時間期間將不能處理新的客戶端請求,直到保存完成爲止。爲避免主進程阻塞,Redis提供了rdbSaveBackground函數。在新建的子進程中調用rdbSave,保存完成後會向主進程發送信號,同時主進程可以繼續處理新的客戶端請求。
- b)讀取(rdbLoad):當Redis啓動時,會根據配置的持久化模式,決定是否讀取RDB文件,並將其中的對象保存到內存中。載入RDB過程中,每載入1000個鍵就處理一次已經等待處理的客戶端請求,但是目前僅處理訂閱功能的命令(PUBLISH 、 SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE),其他一律返回錯誤信息。因爲發佈訂閱功能是不寫入數據庫的,也就是不保存在Redis數據庫的。
#save <seconds> <changes>
save 900 1 #如果15分鐘內,有1個鍵被修改
save 300 10 #如果6分鐘內,有10個鍵被修改
save 60 10000 #如果60秒內有10000個鍵被修改
意思是當滿足上面任意一個條件時,將會進行快照保存。爲了保證IO讀寫性能不會成爲Redis的瓶頸,一般都會創建一個比較大的值來作爲保存點。此時如果保存點設置過大,就會導致宕機丟失的數據過多。保存點設置過小,又會造成IO瓶頸,當對數據進行保存時,可能會由於數據集過大導致操作耗時,這會導致Redis可能在短時間內無法處理客戶端請求
- 1.將客戶端請求的命令轉換爲網絡協議格式
- 2.將協議內容字符串追加到變量server.aof_buf中
- 3.當AOF系統達到設定的條件時,會調用aof_fsync(文件描述符號)將數據寫入磁盤
1.AOF_FSYNC_NO:不保存
此模式下,每執行一條客戶端的命令,都會將協議字符串追加到server.aof_buf中,但不會執行寫入磁盤。
寫入只發生在:
1.Redis被正常關閉
2.Aof功能關閉
3.系統寫緩存已滿,或後臺定時保存操作被執行
上面三種情況都會阻塞主進程,導致客戶端請求失敗。
2.AOF_FSYNC_EVERYSECS:每一秒保存一次
由後臺子進程調用寫入保存,不會阻塞主進程。如果發生宕機,那麼最大丟失數據會在2s以內的數據。這也是默認的設置選項
3.AOF_FSYNC_ALWAYS:每執行一個命令都保存一次
這種模式下,可以保證每一條客戶端指令都被保存,保證數據不會丟失。但缺點就是性能大大下降,因爲每一次操作都是獨佔性的,需要阻塞主進程。
LPUSH list 1 2 3 4 5
LPOP list
LPOP list
LPUSH list 1
最初保存到AOF文件的將會是四條指令。但經過AOF重寫後,會變成一條指令:
LPUSH list 1 3 4 5
同時,考慮到爲了在AOF重寫時,不影響AOF的寫入增加了AOF重寫緩存的概念。也就是說Redis在開啓AOF時,除了將命令格式數據寫入到AOF文件,同時也會寫入到AOF重寫緩存。這樣AOF的寫入、重寫就做到了隔離,保證了重寫時不會阻塞寫入。
四、Redis數據庫的實現
TODO