亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

從源碼解讀redis持久化

2020-10-28 21:32:47
字體:
來源:轉載
供稿:網友

為什么需要持久化?

由于Redis是一種內存型數據庫,即服務器在運行時,系統為其分配了一部分內存存儲數據,一旦服務器掛了,或者突然宕機了,那么數據庫里面的數據將會丟失,為了使服務器即使突然關機也能保存數據,必須通過持久化的方式將數據從內存保存到磁盤中。

對于進行持久化的程序來說,數據從程序寫到計算機的磁盤的流程如下:

1、客戶端發送一個寫指令給數據庫(此時數據在客戶端的內存)

2、數據庫接收到寫的指令以及數據(數據此時在服務端的內存)

3、數據庫發起一個系統調用,把數據寫到磁盤(此時數據在內核的內存)

4、操作系統把數據傳輸到磁盤控制器(數據此時在磁盤緩存中)

5、磁盤控制器執行真正寫入數據到物理媒介的操作(如磁盤)

如果只是考慮數據庫層面,數據在第三階段之后就安全了,在這個時候,系統調用已經發起了,即使數據庫進程奔潰了,系統調用會繼續進行,也能順利將數據寫入到磁盤中。 在這一步之后,在第4步內核會將數據從內核緩存保存到磁盤緩存中,但為了系統的效率問題,默認情況下不會太頻繁地執行這個動作,大概會在30s執行一次,這就意味著如果這一步失敗了或者就在進行這一步的時候服務器突然關機了,那么就可能會有30s的數據丟失了,這種比較普通的災難性問題也是需要考慮的。

POSIX API也提供了一個系統調用讓內核強制將緩存數據寫入到磁盤中,比較常見的就是fsync系統調用。

int fsync(int fd);

fsync函數只對由文件描述符fd指定的一個文件起作用,并且等待寫磁盤操作結束后才返回。每次調用fsync時,會初始化一個寫操作,然后把緩沖區的數據寫入到磁盤中。fsync()函數在完成寫操作的時候會阻塞進程,如果其他線程也在寫同一個文件,它也會阻塞其他線程,直到完成寫操作。

持久化

持久化是將程序數據在持久狀態和瞬時狀態間轉換的機制。對于程序來說,程序運行中數據是在內存的,如果沒有及時同步寫入到磁盤,那么一旦斷電或者程序突然奔潰,數據就會丟失了,只有把數據及時同步到磁盤,數據才能永久保存,不會因為宕機影像數據的有效性。而持久化就是將數據從程序同步到磁盤的一個動作過程。

Redis的持久化

redis有RDB和AOF兩種持久化方式。RDB是快照文件的方式,redis通過執行SAVE/BGSAVE命令,執行數據的備份,將redis當前的數據保存到*.rdb文件中,文件保存了所有的數據集合。AOF是服務器通過讀取配置,在指定的時間里,追加redis寫操作的命令到*.aof文件中,是一種增量的持久化方式。

RDB

RDB文件通過SAVE或BGSAVE命令實現。 SAVE命令會阻塞Redis服務進程,直到RDB文件創建完成為止。 BGSAVE命令通過fork子進程,有子進程來進行創建RDB文件,父進程和子進程共享數據段,父進程繼續提供讀寫服務,子進程實現備份功能。BGSAVE階段只有在需要修改共享數據段的時候才進行拷貝,也就是COW(Copy On Write)。SAVE創建RDB文件可以通過設置多個保存條件,只要其中一個條件滿足,就可以在后臺執行SAVE操作。

SAVE和BGSAVE命令的實現代碼如下:

void saveCommand(client *c) {// BGSAVE執行時不能執行SAVEif (server.rdb_child_pid != -1) {addReplyError(c,"Background save already in progress");return;}rdbSaveInfo rsi, *rsiptr;rsiptr = rdbPopulateSaveInfo(&rsi);// 調用rdbSave函數執行備份(阻塞當前客戶端)if (rdbSave(server.rdb_filename,rsiptr) == C_OK) {addReply(c,shared.ok);} else {addReply(c,shared.err);}}/** BGSAVE 命令實現 [可選參數"schedule"]*/void bgsaveCommand(client *c) {int schedule = 0;/* 當AOF正在執行時,SCHEDULE參數修改BGSAVE的效果* BGSAVE會在之后執行,而不是報錯* 可以理解為:BGSAVE被提上日程*/if (c->argc > 1) {// 參數只能是"schedule"if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"schedule")) {schedule = 1;} else {addReply(c,shared.syntaxerr);return;}}// BGSAVE正在執行,不操作if (server.rdb_child_pid != -1) {addReplyError(c,"Background save already in progress");} else if (server.aof_child_pid != -1) {// aof正在執行,如果schedule==1,BGSAVE被提上日程if (schedule) {server.rdb_bgsave_scheduled = 1;addReplyStatus(c,"Background saving scheduled");} else {addReplyError(c,"An AOF log rewriting in progress: can't BGSAVE right now. ""Use BGSAVE SCHEDULE in order to schedule a BGSAVE whenever ""possible.");}} else if (rdbSaveBackground(server.rdb_filename,NULL) == C_OK) {// 否則調用rdbSaveBackground執行備份操作addReplyStatus(c,"Background saving started");} else {addReply(c,shared.err);}}

有了RDB文件之后,如果服務器關機了,或者需要新增一個服務器,重新啟動數據庫服務器之后,就可以通過載入RDB文件恢復之前備份的數據。 但是bgsave會耗費較長時間,不夠實時,會導致在停機的時候丟失大量數據。

AOF(Append Only File)

RDB文件保存的是數據庫的鍵值對數據,AOF保存的是數據庫執行的寫命令。

AOF的實現流程有三步:

append->write->fsync

append追加命令到AOF緩沖區,write將緩沖區的內容寫入到程序緩沖區,fsync將程序緩沖區的內容寫入到文件。 當AOF持久化功能處于開啟狀態時,服務器每執行完一個命令,就會將命令以協議格式追加寫入到redisServer結構體的aof_buf緩沖區,具體的協議這里不展開闡述。

AOF的持久化發生時期有個配置選項:appendfsync。該選項有三個值: always:所有內容寫入并同步到aof文件 everysec:將aof_buf緩沖區的內容寫入到AOF文件,如果距離上次同步AOF文件的 no:將aof_buf緩沖區中的所有內容寫入到AOF文件,但并不對AOF文件進行同步,由操作系統決定何時進行同步,一般是默認情況下的30s。

AOF持久化模式每個寫命令都會追加到AOF文件,隨著服務器不斷運行,AOF文件會越來越大,為了避免AOF產生的文件太大,服務器會對AOF文件進行重寫,將操作相同key的相同命令合并,從而減少文件的大小。

舉個例子,要保存一個員工的名字、性別等信息:

> hset employee_12345 name "hoohack"

> hset employee_12345 good_at "php"

> hset employee_12345 gender "male"

只是錄入這個哈希鍵的狀態,AOF文件就需要保存三條命令,如果還有其他,比如刪除,或者更新值的操作,那命令將會更多,文件會更大,有了重寫后,就可以適當地減少文件的大小。

AOF重寫的實現原理是先服務器中的數據庫,然后遍歷數據庫,找出每個數據庫中的所有鍵對象,獲取鍵值對的鍵和值,根據鍵的類型對鍵值對進行重寫。比如上面的例子,可以合并為下面的一條命令:

> hset employee_12345 name "hoohack" good_at "php" gender "male"。

AOF的重寫會執行大量的寫入操作,Redis是單線程的,所以如果有服務器直接調用重寫,服務器就不能處理其他命令了,因此Redis服務器新起了單獨一個進程來執行AOF重寫。

Redis執行重寫的流程:

在子進程執行AOF重寫時,服務端接收到客戶端的命令之后,先執行客戶端發來的命令,然后將執行后的寫命令追加到AOF緩沖區中,同時將執行后的寫命令追加到AOF重寫緩沖區中。 等到子進程完成了重寫工作后,會發一個完成的信號給服務器,服務器就將AOF重寫緩沖區中的所有內容追加到AOF文件中,然后原子性地覆蓋現有的AOF文件。

RDB和AOF的優缺點

RDB持久化方式可以只通過服務器讀取數據就能加載備份中的文件到程序中,而AOF方式必須創建一個偽客戶端才能執行。

RDB的文件較小,保存了某個時間點之前的數據,適合做災備和主從同步。

RDB備份耗時較長,如果數據量大,在遇到宕機的情況下,可能會丟失部分數據。另外,RDB是通過配置使達到某種條件的時候才執行,如果在這段時間內宕機,那么這部分數據也會丟失。

AOF方式,在相同數據集的情況下,文件大小會比RDB方式的大。

AOF的持久化方式也是通過配置的不同,默認配置的是每秒同步,最快的模式是同步每一個命令,最壞的方式是等待系統執行fsync將緩沖同步到磁盤文件中,大部分操作系統是30s。通常情況下會配置為每秒同步一次,所以最多會有1s的數據丟失。

怎樣的同步方式更好?

RDB和AOF方式結合。起一個定時任務,每小時備份一份服務器當前狀態的數據,以日期和小時命名,另外起一個定時任務,定時刪除無效的備份文件(比如48小時之前)。AOF配置為1s一次。這樣一來,最多會丟失1s的數據,同時如果redis發生雪崩,也能迅速恢復為前一天的狀態,不至于停止服務。

總結

Redis的持久化方案也不是一成不變的,紙上的理論還需要結合實踐成果來證明其可行性。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产91露脸中文字幕在线| 国产婷婷成人久久av免费高清| 精品国产一区二区三区久久久狼| 日韩中文字幕视频| 91国产视频在线播放| www国产精品视频| 成人国产亚洲精品a区天堂华泰| 欧美成人精品一区| xxxx欧美18另类的高清| 国产精品91久久久| 日韩中文字幕在线| 色爱精品视频一区| 国产午夜精品美女视频明星a级| 国产精品白嫩美女在线观看| 大胆欧美人体视频| 亚洲男人的天堂在线播放| 日韩欧美成人免费视频| 欧美日韩国产在线播放| 国产欧美在线观看| 久久成人这里只有精品| 国产精品99蜜臀久久不卡二区| 国产日本欧美一区二区三区在线| 国产精品av电影| 日本一区二区在线免费播放| 久久综合国产精品台湾中文娱乐网| 亚洲成人精品久久| 在线观看免费高清视频97| 91社区国产高清| 久久精品99久久久久久久久| 欧美一区二区影院| 亚洲成色777777在线观看影院| 久久黄色av网站| 日韩国产精品一区| 欧美麻豆久久久久久中文| 国产丝袜精品第一页| 欧美性高跟鞋xxxxhd| 久久久久免费精品国产| 欧美丰满少妇xxxxx做受| **欧美日韩vr在线| 欧美亚洲一级片| 久久亚洲私人国产精品va| 国内揄拍国内精品少妇国语| 国产欧美日韩高清| 欧美视频在线免费看| 亚洲精品一区二区三区不| 久久影院模特热| 91亚洲午夜在线| 欧美亚洲成人xxx| 国产一级揄自揄精品视频| 欧美裸体视频网站| 97在线观看视频| 亚洲欧美三级在线| 色综合久久久888| 米奇精品一区二区三区在线观看| 国产精品视频精品| 成人h猎奇视频网站| 亚洲aaa激情| 日韩在线观看电影| 深夜福利91大全| 国产日韩欧美影视| 国产成人精品视频| 91久久精品国产91久久| 亚洲少妇激情视频| 成人精品在线观看| 久久亚洲春色中文字幕| 一区二区成人精品| 午夜精品久久久久久99热软件| 亚洲久久久久久久久久久| 久久精品免费播放| 亚洲欧美色图片| 国产精品va在线播放我和闺蜜| 久久久国产精品视频| 精品亚洲国产成av人片传媒| 国产一区二区美女视频| 亚洲国产精品视频在线观看| 国产精品丝袜一区二区三区| 亚洲精品电影网在线观看| 亚洲国产欧美日韩精品| 国产精品91久久久| 亚洲一区二区三区乱码aⅴ| 国产一区二区三区毛片| 久久噜噜噜精品国产亚洲综合| 日韩欧美国产网站| 亚洲国产欧美精品| 亚洲一级片在线看| 亚洲精品视频网上网址在线观看| 国产精品美女www爽爽爽视频| 色777狠狠综合秋免鲁丝| 成人激情视频在线观看| 亚洲人成77777在线观看网| 亚洲第一国产精品| 91高清视频免费观看| 97精品国产97久久久久久春色| 亚洲理论片在线观看| 成人激情视频在线播放| 国产第一区电影| 欧美日韩国产丝袜另类| 国产亚洲精品久久久久久777| 日韩精品日韩在线观看| 亚洲欧美福利视频| 色婷婷综合成人| 国产精品亚洲综合天堂夜夜| 日韩精品一区二区视频| 成人高清视频观看www| 色999日韩欧美国产| 狠狠色狠狠色综合日日五| 亚洲天堂第一页| 亚洲无亚洲人成网站77777| 国产91露脸中文字幕在线| 日韩av免费在线看| 在线播放精品一区二区三区| 成人有码在线播放| 91影视免费在线观看| 国产啪精品视频| 亚洲第一色中文字幕| 狠狠做深爱婷婷久久综合一区| 国产精品18久久久久久首页狼| 国产精品丝袜一区二区三区| 精品一区二区三区四区| www.美女亚洲精品| 久久久久亚洲精品成人网小说| 91精品视频网站| 国产精品久久久91| 日韩女在线观看| 成人免费大片黄在线播放| 久久99精品久久久久久琪琪| 久久男人av资源网站| 久久精品在线播放| 国产91色在线播放| 精品小视频在线| 日本成人在线视频网址| 日韩在线激情视频| 亚洲国产成人精品一区二区| 国外色69视频在线观看| 欧美电影免费在线观看| 国产va免费精品高清在线观看| 91精品久久久久久久久中文字幕| 国产成人小视频在线观看| 色偷偷偷综合中文字幕;dd| 九九久久久久久久久激情| 欧美国产在线视频| 欧美激情久久久久| 亚洲精品一区中文字幕乱码| 久久久久国产精品一区| 日韩欧美第一页| 91久久精品一区| 日韩在线播放一区| 尤物精品国产第一福利三区| 久久久av亚洲男天堂| 亚洲欧美福利视频| 91禁外国网站| 国产在线拍揄自揄视频不卡99| 亚洲最大福利网| 国产精品亚洲激情| 国产精品男女猛烈高潮激情| 亚洲一区第一页| 久久91亚洲精品中文字幕| 国产精品免费一区| 日韩av综合网| 欧美国产日韩二区| 91麻豆国产语对白在线观看| 欧洲日本亚洲国产区| 亚洲精品aⅴ中文字幕乱码| 狠狠躁夜夜躁久久躁别揉|