1. 程式人生 > >redis 非關係型資料庫的持久化和快取原理

redis 非關係型資料庫的持久化和快取原理

Redis,通常我們認為它是一個類似快取的一個記憶體資料庫,經常使用它來快取我們的資料,為什麼需要使用它呢?我們的資料通常儲存在資料庫中,當資料訪問的併發量大的時候,或者是經常使用的通用資料,經常的訪問會對資料庫造成很大的壓力,此時使用Redis來快取,可以減輕訪問資料庫的壓力。

一:redis使用的環境

首先作為一個nosql的key—value組成的資料庫,它們能儲存的資料結構必須是簡單的,因為有關係的資料即使儲存進去之後查詢也是很困難的,並且對於海量的資料儲存還是關係型資料庫比較合適。

- 二,redis中資料結構

  • redis中儲存的資料是以key-value的形式存在的.其中value支援5種資料型別


    字串(String) (重點)
    雜湊(hash) (重點)——>map型別的資料
    字串列表(list)
    字串集合(set)
    有序的字串集合(sortedset或者叫zset)

    • key不要太長(不能>1024個位元組), 也不要太短 。
      • key在專案裡面最好統一寫法, key的常用的寫法:
        專案名子模組key名稱; store_user_pwd

    Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)

    Redis的列表的順序是從左到右的順序!

一個列表最多可以包含 2的32 次方- 1 個元素 (4294967295, 每個列表超過40億個元素)。 特點:有序

三、持久化

   為什麼需要持久化呢?對於每一個公司來講,資料庫中的資料是最重要的, 資料庫中的資料多而且重要,這麼重要的資料都儲存在記憶體中,如果異常斷電,將會對公司造成很大的影響,於是就有了資料的持久化機制,這個其實就是把記憶體中的資料儲存到硬碟中,方便資料的持續存在,也可以減少斷電等突發異常造成的損失。

 那麼我們怎麼持久化資料呢?多長時間進行一次持久化呢?

redis 支援兩種持久化方式,一種是 Snapshotting(快照)也是預設方式,另一種是 Append-only file(僅讀寫檔案:縮寫 aof)的方式。下面分別介紹:

 一)、Snapshotting(快照)

     快照是預設的持久化方式。這種方式是就是將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb。可以通過配置設定自動做快照持久化的方式。我們可以配置 redis在 n 秒內如果超過 m 個 key 被修改就自動做快照,下面是預設的快照儲存配置:

save 200 10 #200 秒內如果超過 10 個 key 被修改,則發起快照儲存
save 400 20 #400 秒內容如超過 20 個 key 被修改,則發起快照儲存
save 60 10000

下面介紹詳細的快照儲存過程:
我們知道通過fork()系統呼叫我們可以建立一個和當前程序印象一樣的新程序.我們通常將新程序稱為子程序,而當前程序稱為父程序.而子程序繼承了父程序的整個地址空間,其中包括了程序上下文,堆疊地址,記憶體資訊程序控制塊(PCB)等.

1.redis 呼叫 fork,現在有了子程序和父程序。(不是vfork,vfork是共享父程序的片段資源,而fork是複製父程序的資源)

2.當客戶有新的請求的時候,(parent)父程序繼續處理 客戶client 請求,子程序負責將記憶體內容寫入到臨時檔案。由於 os 的實時複製機制( copy on write)父子程序會共享相同的物理頁面,當父程序處理寫請求時 os 會為父程序要修改的頁面建立副本,而不是寫共享的頁面(與vfork機制不同)。所以子程序地址空間內的資料是 fork時刻整個資料庫的一個快照。

3.當子程序將快照寫入臨時檔案完畢後,臨時檔案將會替換原快照檔案,然後子程序就退出。client 也可以使用 save 或者 bgsave 命令通知 redis 做一次快照持久化。 save 操作是在主執行緒中儲存快照的,由於 redis 是用一個主執行緒來處理所有client 的請求,這種方式會阻塞所有client 請求。所以不推薦使用。另一點需要注意的是,每次快照持久化都是將記憶體資料完整寫入到磁碟一次,並不是增量的只同步變更資料,即內容可以覆蓋。如果需要操作的資料量很大,且讀寫操作比較多,必然會引起大量的磁碟 io 操作,可能會嚴重影響效能。

   二)、AOF方式

    由於快照方式存值有時間間隔,所以如果 redis 意外 down 掉的話,就會丟失最後一次快照後的所有修改。如果應用要求不能丟失任何修改的話,可以採用 aof 持久化方式。下面介紹 Append-only file:aof 比快照方式有更好的持久化性,是由於在使用 aof 持久化方式時,redis 會將每一個收到的寫命令都通過 write 函式追加到檔案中(預設是 appendonly.aof)。當 redis 重啟時會通過重新執行檔案中儲存的寫命令來在記憶體中重建整個資料庫的內容。當然由於 os 會在核心中快取 write 做的修改,所以可能不是立即寫到磁碟上。這樣 aof 方式的持久化也還是有可能會丟失部分修改。不過我們可以通過配置檔案告訴 redis 我們想要通過 fsync 函式強制 os 寫入到磁碟的時機。