Redis單機資料庫持久化與過期建刪除

廣州蘆葦科技Java開發團隊發表於2019-01-09

簡言

作為一名程式猿,redis已經是我們接觸最多的快取工具之一,它的應用面很廣,那麼大家是否對他真的有些瞭解呢,對於antirez大神的想法我也是算不上略懂一二,再此知識簡單談談關於redis的一些小事

redis的儲存結構

首先讓我們來了解一下redis的儲存結構(廢話不多說,直接上圖)

enter description here
這張圖很好地說明了Redis是如何儲存的,我們知道redis是以鍵值對的方式來進行資料儲存,首先redis會維持一個鍵表,在這個表上儲存著redis所有的 “key” (也就是direct表)再來就是以指標的方式指向對於的"value",而它的value就資料結構比較豐富,有動態字串,連結串列,跳躍表等等、redis採用物件式儲存,每一個鍵都是一個String物件,而value則是一個對應資料結構的物件。

1、redis單機資料庫與過期鍵刪除策略

下面讓我們來自轉入正題,redis的過期鍵刪除策略,我們知道當我們安裝redis後,它預設有16個子資料庫,我們可以通過一些命令插入刪除鍵值對,也可以切換資料庫,但我們今天討論的重點不在這兒,在redis中有一類比較特殊的鍵值對,那就是被expire命令設定了過期時間的鍵值對,他們只在規定時間內有效,最最常見的應用例項便是驗證碼,在生活中我們經常需要驗證碼,一般一分鐘就失效了,那麼這些失效了的驗證碼要如何處理呢,如果放任不管,我們知道redis是本地資料庫,如果不處理,這些驗證碼長期存留於記憶體便造成記憶體洩漏,久而久之,伺服器必然癱瘓。

1.1、redis儲存過期鍵的方式

enter description here
如上圖,redis中專門會設定一個表來儲存所有設定了過期鍵的鍵值對,儲存方式為新增一個long資料記錄過期時間

1.2、那麼redis是如何處理過期鍵的?

廢話不多說,直接出答案 redis的三種過期鍵刪除策略

  • 定時刪除 在設定具有過期時間的鍵值對的時候,給這個鍵值對加上定時器,當過期時間來臨則刪除這個鍵值對 優點 時效性很好 缺點 對cpu很不友好,大量消耗cpu效能,影響整體效能
  • 惰性刪除 放任過期鍵不管,但是每次在redis取出鍵值對的時候,進行過期檢驗,刪除其中過期鍵 優點 對cpu很友好 缺點 對記憶體很不友好,導致大量記憶體洩漏
  • 定期刪除 每隔一段時間檢查一次資料庫,刪除裡面的過期鍵,至於檢查多少個資料庫,由演算法決定 優點 對cpu和記憶體均比較友好 缺點 如果頻繁清除對cpu不友好,如果清除不及時對記憶體不友好

從上面來看,不論選擇哪種方式都不是最優,畢竟人無完人,十全十美的策略也是不存在的,團隊的力量才是最強大的,所以redis最終採用的策略是惰性刪除與定期刪除相結合,定期刪除過期鍵,並且在做get操作時進行過期鍵檢查,刪除過期鍵

2、redis持久化

2.1、RDB

RDB的持久化方式是將資料化當前的狀態儲存起來,也就是將它的鍵值對儲存為一個壓縮的二進位制檔案,RDB的持久化有兩種命令

  • SAVE 系統阻塞然後生成RDB檔案,在檔案生成期間不能對外提供服務,
  • BGSAVE 建立子程式進行RDB檔案的生成,父程式繼續處理任務

那麼何時進行RDB儲存當前狀態? 在redis中以下的情況會進行RDB儲存當前狀態(預設的配置)

  • 1、900秒之內有一次修改這進行RDB儲存
  • 2、300秒之內有十次修改,進行RDB儲存
  • 3、60秒內有一萬次修改,進行RDB儲存

最後RDB檔案什麼時候被使用? RDB檔案只在系統啟動的時候被使用,系統啟動的時候檢測到RDB檔案的存在則會載入RDB檔案

2.2、AOF

RDB通過儲存資料庫資料來儲存狀態,而AOF則是通過儲存Redis說執行的每一條命令來儲存資料庫狀態

當Redis開啟Aof功能的時候,系統將會將說執行的命令通過Aof的方式進行同步 他的同步分為大致可分為兩部,

  • 1、將命令寫入aof緩衝區aof_buf 我們知道寫入儲存器是極為費時的操作,所以為了加快寫回速度,減少I/O造成的效能浪費,Redis加上了緩衝區

  • 2、 將緩衝區命令寫入到AOF檔案進行同步 將緩衝區的資料寫回AOF檔案採用FlushAppendOnlyFile函式,而這個函式的執行實際由redis的一個配置選項appendSync決定,它有三種策略

    • awalys 總是將緩衝區aof_buf的資料時時同步到AOF檔案(此方法I/O和cpu消耗較大)

    • everysec 每隔一秒將資料寫回一次(Redis預設的方式)

    • no 將緩衝區aof_buf的資料同步到AOF檔案由系統決定。

    從上面的介紹可知三種方法各有利弊,系統採用了everysec的方式。

  • 3、AOF檔案的重寫 當AOF檔案過大的時候,會對Redis造成影響,那麼Redis就會對AOF進行重寫 如

    //假設系統有如下三條命令
    127.0.0.1:6379[1]> RPUSH list 1 2 3 4    //[1,2,3,4]
    127.0.0.1:6379[1]> RPOP list                    //[1,2,3]
    127.0.0.1:6379[1]> LPOP list            //[2,3]
    
    //其實可用一條命令代替
    RPUSH 23
    
    複製程式碼

    經過重寫可大大縮小Redis AOF檔案的大小

  • 4、AOF檔案何時啟用 AOF檔案也是在系統啟動的時候系統自動載入AOF檔案進行同步

2.3、AOF與RDB共存時啟動過程

見下圖

enter description here

2.4、一些值得探討的事

我們知道redis是記憶體資料庫,並非持久化資料庫,根據CAP理論,redis是滿足高可用和分割槽容錯性的資料庫,那麼其實Redis的持久化並不安全?答案確實如此,很多人說,Redis也是可以做到持久化的,將AOF的持久化策略設定為awalys不就可以了嗎,那樣最多就丟失一條命令。。。

但是這恰恰違背了Redis高可用的特性,會大大降低Redis的qbs,讓Redis大打折扣,在通常情況下我們採用的是everysec,在每隔一秒將緩衝區的資料寫回AOF檔案,這樣的話,如果系統當機,就會有丟失一秒資料的危險。

魚與熊掌不可兼得,所以Redis並不是很好的持久化資料庫工具,當儲存重要資料的時候還是得使用mysql sqlsever 等持久化資料庫工具。

結語

文字簡單介紹了redis的一些簡單的內容,如有差錯歡迎討論和提出意見與建議,請各位大神手下留情,下一篇文章本小小編將簡單介紹多機版Redis的叢集,叢集同步等內容,期待下回再見。

  • 參考書籍《Redis設計與實現》
  • 網上文章,不一一列舉。

增鑫

廣州蘆葦科技Java開發團隊

蘆葦科技-廣州專業網際網路軟體服務公司

抓住每一處細節 ,創造每一個美好

關注我們的公眾號,瞭解更多

想和我們一起奮鬥嗎?lagou搜尋“ 蘆葦科技 ”或者投放簡歷到 server@talkmoney.cn 加入我們吧

Redis單機資料庫持久化與過期建刪除

關注我們,你的評論和點贊對我們最大的支援

相關文章