摘自 https://blog.csdn.net/tr1912/article/details/70197085?foxhandler=RssReadRenderProcessHandler
一、redis的適用環境
首先作為一個nosql的key—value組成的數據庫,它們能存儲的數據結構必須是簡單的,因為有關系的數據即使存儲進去之后查詢也是很困難的,並且對於海量的數據存儲還是關系型數據庫比較合適。
舉一個把一般數據庫數據存儲到key-value中的例子:
student
學號
姓名
年齡
班級
001
小明
18
2
key
value
student:001:姓名
小明
student:001:年齡
18
student:001:班級
2
遵從規則為 key 表名:主鍵值:列名
value 列值
如果加上表關系的話還要復雜好幾倍的。
那么什么樣的數據適合存儲在非關系型數據庫中的呢?
1、關系不是很密切的的數據,比如用戶信息,班級信息,評論數量等等。
2、量比較大的數據,如訪問記錄等
3、訪問比較頻繁的數據,如用戶信息,訪問數量,最新微博等
二、持久化
那么這么多,這么重要的數據都存儲在內存中,如果突然斷電,豈不是很糟糕,於是就有了數據的持久化機制,這個其實就是把內存中的數據存儲到硬盤中,方便數據的持續存在,也可以減少斷電造成的損失。
那么我們怎么持久化數據呢?多長時間進行一次持久化呢?
redis 支持兩種持久化方式,一種是 Snapshotting(快照)也是默認方式,另一種是 Append-only file(縮寫 aof)的方式。下面分別介紹:
一)、Snapshotting
快照是默認的持久化方式。這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb。可以通過配置設置自動做快照持久化的方式。我們可以配置 redis在 n 秒內如果超過 m 個 key 被修改就自動做快照,下面是默認的快照保存配置:
save 900 1 #900 秒內如果超過 1 個 key 被修改,則發起快照保存
save 300 10 #300 秒內容如超過 10 個 key 被修改,則發起快照保存
save 60 10000
下面介紹詳細的快照保存過程:
1.redis 調用 fork,現在有了子進程和父進程。
2. 父進程繼續處理 client 請求,子進程負責將內存內容寫入到臨時文件。由於 os 的實時復制機制( copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時 os 會為父進程要修改的頁面創建副本,而不是寫共享的頁面。所以子進程地址空間內的數據是 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 寫入到磁盤的時機。有三種方式如下(默認是:每秒 fsync 一次)
appendonly yes //啟用 aof 持久化方式
# appendfsync always //收到寫命令就立即寫入磁盤,最慢,但是保證完全的持久化
appendfsync everysec //每秒鍾寫入磁盤一次,在性能和持久化方面做了很好的折中
# appendfsync no //完全依賴 os,性能最好,持久化沒保證
aof 的方式也同時帶來了另一個問題。持久化文件會變的越來越大。例如我們調用 incr test命令 100 次,文件中必須保存全部的 100 條命令,其實有 99 條都是多余的。因為要恢復數據庫的狀態其實文件中保存一條 set test 100 就夠了。為了壓縮 aof 的持久化文件。 redis 提供了 bgrewriteaof 命令。收到此命令 redis 將使用與快照類似的方式將內存中的數據以命令的方式保存到臨時文件中,最后替換原來的文件。
---------------------
作者:王嘯tr1912
來源:CSDN
原文:https://blog.csdn.net/tr1912/article/details/70197085
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!