在web伺服器中,高可用是指伺服器可以正常存取的時間,衡量的標準是在多長時間內可以提供正常服務(99.9%、99.99%、99.999%等等)。【相關推薦:Redis視訊教學】
但是在Redis語境中,高可用的含義似乎要寬泛一些,除了保證提供正常服務(如主從分離、快速容災技術),還需要考慮資料容量的擴充套件、資料安全不會丟失等。
在Redis中,實現高可用的技術主要包括持久化、主從分離、哨兵和叢集。
高可用策略 | 說明 |
---|---|
持久化 | 持久化是最簡單的高可用方法(有時甚至不被歸為高可用的手段),主要作用是資料備份,即將資料儲存在硬碟,保證資料不會因程序退出而丟失。 |
主從複製 | 主從複製是高可用Redis的基礎,哨兵和叢集都是在主從複製基礎上實現高可用的。主從複製主要實現了資料的多機備份,以及對於讀操作的負載均衡和簡單的故障恢復。缺陷:故障恢復無法自動化,寫操作無法負載均衡,儲存能力受到單機的限制。 |
哨兵 | 在主從複製的基礎上,哨兵實現了自動化的故障恢復。缺陷:寫操作無法負載均衡,儲存能力受到單機的限制。 |
叢集 | 通過叢集,Redis解決了寫操作無法負載均衡,以及儲存能力受到單機限制的問題,實現了較為完善的高可用方案。 |
Redis是記憶體資料庫,資料都是儲存在記憶體中,為了避免伺服器斷電等原因導致Redis程序異常退出後資料的永久丟失,需要定期將Redis中的資料以某種形式(資料或命令)從記憶體儲存到硬碟;當下次Redis重新啟動時,利用持久化檔案實現資料恢復。除此之外,為了進行災難備份,可以將持久化檔案拷貝到一個遠端位置。
RDB持久化是指在指定的時間間隔內將記憶體中當前程序中的資料生成快照儲存到硬碟(因此也稱為快照持久化),用二進位制壓縮儲存,儲存的檔案字尾是rdb;當Redis重新啟動時,可以讀取快照檔案恢復資料。
RDB持久化的觸發分為手動觸發和自動觸發兩種。
[root@localhost ~]# vim /etc/redis/6379.conf ##219行,以下三個save條件滿足任意一個時,都會引起bgsave的呼叫save 900 1 ##當時間到900秒時,如果redis資料發生了至少1次變化,則執行bgsavesave 300 10 ##當時間到300秒時,如果redis資料發生了至少10次變化,則執行bgsavesave 60 10000 ##當時間到60秒時,如果redis資料發生了至少10000次變化,則執行bgsave##254行,指定RDB檔名dbfilename dump.rdb##264行,指定RDB檔案和AOF檔案所在目錄dir /var/lib/redis/6379##242行,是否開啟RDB檔案壓縮rdbcompression yes
除了save m n以外,還有一些其他情況會觸發bgsave:
RDB檔案的載入工作是在伺服器啟動時自動執行的,並沒有專門的命令。但是由於AOF的優先順序更高,因此當AOF開啟時,Redis會優先載入AOF檔案來恢復資料;只有當AOF關閉時,才會在Redis伺服器啟動時檢測RDB檔案,並自動載入。伺服器載入RDB檔案期間處於阻塞狀態,直到載入完成為止。
Redis載入RDB檔案時,會對RDB檔案進行校驗,如果檔案損壞,則紀錄檔中會列印錯誤,Redis啟動失敗。
RDB持久化是將程序資料寫入檔案,而AOF持久化則是將Redis執行的每次寫、刪除命令記錄到單獨的紀錄檔檔案中,查詢操作不會記錄;當Redis重新啟動時再次執行AOF檔案中的命令來恢復資料。
與RDB相比,AOF的實時性更好,因此已成為主流的持久化方案。
Redis伺服器預設開啟RDB,關閉AOF;要開啟AOF,需要在組態檔中設定
[root@localhost ~]# vim /etc/redis/6379.conf ##700行,修改,開啟AOFappendonly yes##704行,指定AOF檔名稱appendfilename "appendonly.aof"##796行,是否忽略最後一條可能存在問題的指令aof-load-truncated yes[root@localhost ~]# /etc/init.d/redis_6379 restartStopping ... Redis stopped Starting Redis server...
由於需要記錄Redis的每條寫命令,因此AOF不需要觸發,下面介紹AOF的執行流程。
AOF的執行流程包括:
Redis先將命令追加到緩衝區,而不是直接寫入檔案,主要是為了避免每次有寫命令都直接寫入硬碟,導致硬碟IO稱為Redis負載的瓶頸。
命令追加的格式是Redis命令請求的協定格式,它是一種純文字格式,具有相容性好、可讀性強、容易處理、操作簡單、避免二次開銷等優點。在AOF檔案中,除了用於指定資料庫的select命令(如select 0為選中0號資料庫)是由Redis新增的,其他都是使用者端傳送來的寫命令。
Redis提供了多種AOF快取區的同步檔案策略,策略涉及到作業系統的write和fsync函數,說明如下:
為了提高檔案寫入效率,在現代作業系統中,當使用者呼叫write函數將資料寫入檔案時,作業系統通常會將資料暫存到一個記憶體緩衝區裡,當緩衝區被填滿或超過了指定時限後,才真正將緩衝區的資料寫入到硬碟裡。這樣的操作雖然提高了效率,但也帶來了安全問題:如果計算機停機,記憶體緩衝區中的資料會丟失;因此係統同時提供了fsync、fdatasync等同步函數,可以強制作業系統立刻將緩衝區中的資料寫入到硬碟裡,從而確保資料的安全性。
AOF快取區的同步檔案策略存在三種同步方式,通過對/etc/redis/6379.conf的729行的修改進行設定。
命令寫入aof_buf後立即呼叫系統fsync操作同步到AOF檔案,fsync完成後執行緒返回。這種情況下,每次有寫命令都要同步到AOF檔案,硬碟IO成為效能瓶頸,Redis只能支援大約幾百TPS寫入,嚴重降低了Redis的效能;即便是使用固態硬碟(SSD),每秒大約也就只能處理幾萬個命令,而且會大大降低SSD的壽命。
命令寫入aof_buf後呼叫系統write操作,不對AOF檔案做fsync同步;同步由作業系統負載,通常同步週期為30秒。這種情況下,檔案同步的時間不可控,且緩衝區中堆積的資料會很多,資料安全性無法保證。
命令寫入aof_buf後呼叫系統write操作,write完成後執行緒返回:fsync同步檔案操作由專門的執行緒每秒呼叫一次。everysec是前述兩種策略的折中,是效能和資料安全性的平衡,一次是Redis的預設設定,也是我們推薦的設定。
隨著時間流逝,Redis伺服器執行的寫命令越來越多,AOF檔案也會越來越大;過大的AOF檔案不僅會影響伺服器的正常執行,也會導致資料恢復需要的時間過長。
檔案重寫是指定期重寫AOF檔案,減小AOF檔案的體積。需要注意的是,AOF重寫是把Redis程序內的資料轉化為寫命令,同步到新的AOF檔案;不會對舊的AOF檔案進行任何讀取、寫入操作。
關於檔案重寫需要注意的另一點是:對於AOF持久化來說,檔案重寫雖然是強烈推薦的,但並不是必須的;即使沒有檔案重寫,資料也可以被持久化並在Redis啟動的時候匯入;因此在一些現實中,會關閉自動的檔案重寫,然後定時任務在每天的某一時刻定時執行。
檔案重寫之所以能夠壓縮AOF檔案,原因在於:
通過上述原因可以看出,由於重寫後AOF執行的命令減少了,檔案重寫既可以減少檔案佔用的空間,也可以加快恢復速度。
檔案重寫分為手動觸發和自動觸發:
自動觸發的設定位於/etc/redis/6379.conf的771行和772行
檔案重寫的流程如下:
關於檔案重寫的流程,有兩點需要特別注意:
RDB持久化
優點:RDB檔案緊湊,體積小,網路傳輸快,適合全量複製;恢復速度比AOF快很多。當然,與AOF相比,RDB最重要的優點之一是對效能的影響相對較小。
缺點:RDB檔案的知名缺點在於其資料快照的持久化方式決定了必然做不到實時持久化,而在資料越來越重要的今天,資料的大量丟失很多時候是無法接受的,因此AOF持久化成為主流。此外,RDB檔案需要滿足特定格式,相容性差(如老版本的Redis不相容新版本的RDB檔案)。
對於RDB持久化,一方面是bgsave在進行fork操作時Redis主程序會阻塞,另一方面,子程序向硬碟寫資料也會帶來IO壓力。
AOF持久化
與RDB持久化相對應,AOF的優先在於支援秒級持久化、相容性好,缺點是檔案大、恢復速度慢,對效能影響大。
對於AOF持久化,向硬碟寫資料的頻率大大提高(everysec策略下為秒級),IO壓力更大,甚至可能在成AOF追加阻塞問題。
AOF檔案的重寫與RDB的bgsave類似,會有fork時的阻塞和子程序的IO壓力問題。相對來說,由於AOF向硬碟中寫資料的頻率更高,因此對Redis主程序效能的影響會更大。
一般來說,建議關閉AOF的自動重寫功能,並在重寫操作設定計劃任務,放在凌晨業務量低的時候進行,以降低AOF對主程序效能的影響以及IO的讀寫壓力。
更多程式設計相關知識,請存取:!!
以上就是一文詳解redis中的高可用與持久化的詳細內容,更多請關注TW511.COM其它相關文章!