redis啟動載入過程、資料持久化
https://www.cnblogs.com/cuijl/p/7992433.html
付出才有回報,敢於嘗試才能成功。
隨筆- 89 文章- 0 評論- 0
redis啟動載入過程、資料持久化
背景
公司一年的部分業務資料放在redis伺服器上,但資料量比較大,單純的string型別資料一年就將近32G,而且是經過壓縮後的。
所以我在想能否通過獲取string資料的時間改為儲存list資料型別,或者將資料持久化到硬碟上,或者放在不同庫上,解決未來資料過大導致down機的問題。
相關知識點
- 資料持久化
- 資料載入
資料持久化
- filesnapshotting(快照)
- Append-only(aof)
filesnapshotting
預設redis是會以快照的形式將資料持久化到磁碟的(一個二進 制檔案,xx.rdb)
在配置檔案中的格式是:save N M表示在N秒之內,redis至少發生M次修改則redis抓快照到磁碟。
當然我們也可以手動執行save或者bgsave(非同步)做快照。
工作原理簡單介紹:當redis需要做持久化時,redis會fork一個子程序;子程序將資料寫到磁碟上一個臨時RDB檔案中;當子程序完成寫臨時檔案後,將原來的RDB替換掉,這樣的好處就是可以copy-on-write
缺點:filesnapshotting方法在redis異常死掉時, 最近的資料會丟失(丟失資料的多少視你save策略的配置),所以這是它最大的缺點,當業務量很大時,丟失的資料是很多的
Appened-only
可以做到全部資料不丟失,但redis的效能就要差些。AOF就可以做到全程持久化,只需要在配置檔案中開啟(預設是no),appendonly yes開啟AOF之後,可以選擇三種不同的策略,都會把它新增到aof檔案中,當redis重啟時,將會讀取AOF檔案進行“重放”以恢復到 redis關閉前的最後時刻。
AOF的三種策略
appendfsync :appendfsync always
appendfsync everysec每秒鐘都呼叫fsync重新整理到AOF檔案,很快,但可能會丟失一秒以內的資料;
appendfsync no依靠OS進行重新整理,redis不主動重新整理AOF,這樣最快,但安全性就差。預設並推薦每秒重新整理,這樣在速度和安全上都做到了兼顧。
LOG Rewriting隨著修改資料的執行AOF檔案會越來越大,其中很多內容記錄某一個key的變化情況。
因此redis有了一種比較有意思的特性:在後臺重建AOF檔案,而不會影響client端操作。在任何時候執行BGREWRITEAOF命令,都會把當前記憶體中最短序列的命令寫到磁碟,這些命令可以完全構建當前的資料情況,而不會存在多餘的變化情況(比如狀態變化,計數器變化等),縮小的AOF檔案的大小。
所以當使用AOF時,redis推薦同時使用BGREWRITEAOF。
LOG Rewrite的工作原理:同樣用到了copy-on-write:首先redis會fork一個子程序;子程序將最新的AOF寫入一個臨時檔案;父程序 增量的把記憶體中的最新執行的修改寫入(這時仍寫入舊的AOF,rewrite如果失敗也是安全的);當子程序完成rewrite臨時檔案後,父程序會收到 一個訊號,並把之前記憶體中增量的修改寫入臨時檔案末尾;這時redis將舊AOF檔案重新命名,臨時檔案重新命名,開始向新的AOF中寫入。
Redis啟動載入過程
1. 初始化全域性伺服器配置
2. 載入配置檔案(如果指定了配置檔案,否則使用預設配置)
3. 初始化伺服器
4. 載入資料庫
5. 網路監聽
下面對上面這些步驟進行介紹
初始化全域性伺服器配置
初始化全域性伺服器配置通過initServerConfig()函式完成,主要是初始化server變數
初始化的內容包括下面幾個方面:
1. 網路監聽相關,如繫結地址,TCP埠等
2. 虛擬記憶體相關,如swap檔案、page大小等
3. 儲存機制,多長時間內有多少次更新才進行儲存
4. 複製相關,如是否是slave,master地址、埠
5. Hash相關設定
6. 初始化命令表
如其中的儲存機制中,伺服器初始化策略為:
// 1小時內1次更新 appendServerSaveParams(60*60,1); // 5分鐘內100次更新 appendServerSaveParams(300,100); // 1分鐘內10000次更新 appendServerSaveParams(60,10000);
如果在啟動伺服器時,指定了配置檔案,則會在下面的“載入配置檔案”步驟中,根據配置檔案內容,更改其中的某些伺服器配置。
載入配置檔案
如果指定了配置檔案,Redis使用loadServerConfig()函式載入配置檔案,使用標準I/O庫開啟配置檔案,迴圈讀取每一行然後覆蓋上一步進行的預設配置。
需要注意的是,下載Redis後代碼包中有一個預設配置檔案,如果啟動Redis伺服器時,不指定配置檔案,Redis不會使用這個預設檔案的配置,而是使用上一步“初始化全域性伺服器配置”中的配置。在預設配置檔案中提供的配置項與上一步預設初始化的配置有些事不一樣的,所以如果沒有指定配置檔案,千萬不能認為Redis的行為會按照預設配置檔案進行,最典型的一個例子,在預設配置檔案中的資料儲存策略是:
# 15分鐘內1次更新 save 900 1 # 5分鐘內100次更新 save 300 10 # 1分鐘內10000次更新 save 60 10000
而預設初始化的全域性配置中資料儲存策略:appendServerSaveParams的配置項
初始化伺服器
初始化伺服器的工作在initServer()函式中,主要是完成前面未完成的工作,繼續對server變數初始化,如設定訊號處理、建立clients、slaves列表,建立Pub/Sub通道列表,同時還會建立共享物件:
shared.crlf = createObject(REDIS_STRING,sdsnew("\r\n")); shared.ok = createObject(REDIS_STRING,sdsnew("+OK\r\n")); shared.err = createObject(REDIS_STRING,sdsnew("-ERR\r\n")); shared.emptybulk = createObject(REDIS_STRING,sdsnew("$0\r\n\r\n"));
最後,如果啟用了虛擬記憶體機制,還需要初始化虛擬記憶體相關,如Thread I/O等。
載入資料庫
在完成了上面的所有的初始化工作之後,Redis開始載入資料到記憶體中,如果啟用了appendonly了,則Redis從appendfile載入資料,否則就從dbfile載入資料。
1. 從appendfile中載入資料:loadAppendOnlyFile()函式
在此之前,我們先來看一下appendfile裡面儲存了什麼,如我執行了下面兩條命令(記得在配置檔案中開啟appendonly):
redis> SET mykey001 myvalue001 OK redis> GET mykey001 "myvalue001"
使用cat命令檢視appendonly.aof的內容:
$ cat appendonly.aof *2 $6 SELECT $1 0 *3 $3 SET $8 mykey001 $10 myvalue001
在appendonly.aof檔案中儲存的正是從客戶端發過來的請求命令,還可以看到對於GET命令,並沒有儲存。
既然appendonly.aof中儲存了所有寫入資料的請求命令,那麼在載入資料的時候只要重新執行一遍這些命令即可。
事實上Redis也正是這麼做的,在開始載入之前暫時關閉appendonly,然後Redis建立一個假的Redis客戶端。
然後讀取appendonly.aof檔案中的命令,在假的Redis客戶端上下文中執行,同時伺服器也不對該客戶端做任何應答。
如果載入過程中實體記憶體不夠用,並且Redis開啟了VM,則還需要處理swap操作,最後載入完成後重新設定appendonly標誌。
2. 從dbfile中載入資料:rdbLoad()函式
如果Redis沒有開啟appendonly,就需要從資料庫檔案中載入資料到記憶體,基本步驟如下:
a. 處理SELECT命令,即選擇資料庫
b. 讀取key
c. 讀取value
d. 檢測key是否過期
e. 新增新的物件到雜湊表
f. 設定過期時間(如果需要)
g. 如果開啟了VM,處理swap操作
網路監聽
在完成了初始化配置和資料載入後,Redis啟動監聽。Redis的網路庫沒有使用libevent或者libev,而是作者自己實現的一個非常輕量級的庫(主要實現在ae.c檔案中)
然而回到我的問題上,如果資料庫中資料已經放入了32G的資料,在啟動redis時載入資料庫這部分必定會相當相當慢,而且涉及到宕機的問題(實體記憶體到達峰值)
這時可能單臺redis很難解決這個問題,而應該考慮叢集。
作者:大胖兒在努力 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
分類: NoSQL
0
0
« 上一篇:MongoDB學習筆記
» 下一篇:高位位元組、低位位元組
posted @ 2017-12-06 14:14 大胖兒在努力 閱讀(1588) 評論(0) 編輯 收藏
註冊使用者登入後才能發表評論,請 登入 或 註冊,訪問網站首頁。
【推薦】超50萬VC++原始碼: 大型組態工控、電力模擬CAD與GIS原始碼庫!
相關博文:
· Redis資料儲存解決方案
· C# Redis
· redis 資料型別詳解 以及 redis適用場景場合
· REDIS 資料型別詳解 以及 REDIS適用場景場合
· Redis應用場景
最新新聞:
· 清華畢業計算機教授遭持槍劫車!靠“貪心演算法”追回秒殺美國警察
· 位元組跳動涉訴訟365起 或難支撐750億美元超高估值
· 2018<1790,這才是中華民族最大危機?
· 美國網癮戒除中心:沒有電擊、隔絕WiFi,治一次18萬元
· 蘋果iTune和三星電視達成流媒體合作
» 更多新聞...
暱稱:大胖兒在努力
園齡:6年11個月
粉絲:8
關注:18
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
30 | 31 | 1 | 2 | 3 | 4 | 5 | |||
6 | 7 | 8 | 9 | 10 | 11 | 12 | |||
13 | 14 | 15 | 16 | 17 | 18 | 19 | |||
20 | 21 | 22 | 23 | 24 | 25 | 26 | |||
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
隨筆分類
- AndRoid(13)
- Asp.Net MVC(13)
- C語言基礎(3)
- dotnet基礎(14)
- EF(5)
- JQuery(6)
- NoSQL(4)
- RabbitMQ(3)
- redis開發與運維讀後感(1)
- SQL(13)
- 併發程式設計(6)
- 單車生活(5)
- 設計模式(4)
隨筆檔案
- 2018年4月 (1)
- 2018年3月 (10)
- 2017年12月 (10)
- 2017年11月 (3)
- 2017年10月 (5)
- 2017年8月 (11)
- 2017年7月 (9)
- 2017年4月 (6)
- 2017年3月 (11)
- 2015年8月 (1)
- 2015年7月 (2)
- 2015年6月 (11)
- 2015年5月 (9)
閱讀排行榜
- 1. EntityFramework使用及優化(10091)
- 2. 單例模式和多執行緒有沒有關係?(1980)
- 3. redis啟動載入過程、資料持久化(1588)
- 4. FluentAPI配置(605)
- 5. 高位位元組、低位位元組(522)
推薦排行榜
Copyright ©2019 大胖兒在努力