天天看點

【原創】你的Redis怎麼持久化的

(本文改編自生活真實案例,如有類同,絕不是巧合!)

端午節,煙哥正在一邊愉快的學習....

突然,微信一陣抖動。原來是老劉呼喚煙哥!善良的煙哥本以為人家是要約我出去玩!然而,打開微信一看,出現下圖聊天記錄

【原創】你的Redis怎麼持久化的

于是本文的主題就這麼展開了。由于我需要迅速讓老劉明白,這種問題的回答套路,是以我回答的時候,教她的是一種通用做法。

<code>ps</code>:附《那些年用過的redis叢集架構(含面試解析)》的連接配接位址。

當然,必須的,我一定要先問一下老劉答了哪種redis叢集架構!老劉的回答是用了redis cluster叢集架構。

于是,我一聽心裡就有底,開始balabala....

OK,一般我們在生産上采用的持久化政策為

(1)master關閉持久化

(2)slave開RDB即可,必要的時候AOF和RDB都開啟

該政策能夠适應絕大部分場景,絕大部分叢集架構。

為什麼是絕大部分場景?

因為這套政策存在部分的資料丢失可能性。redis的主從複制是異步的,master執行完用戶端請求的指令後會立即傳回結果給用戶端,然後異步的方式把指令同步給slave。是以master可能還未來得及将指令傳輸給slave,就當機了,此時slave變為master,資料就丢了。

幸運的是,絕大部分業務場景,都能容忍資料的部分丢失。假設,真的遇到緩存雪崩的情況,代碼中也有熔斷器來進行資源保護,不至于所有的請求都轉發到資料庫上,導緻我們的服務崩潰!

<code>ps</code>:這裡的緩存雪崩是指同一時間來了一堆請求,請求的key在redis中不存在,導緻請求全部轉發到資料庫上。

為什麼是絕大部分叢集架構?

因為在叢集中存在redis讀寫分離的情況,就不适合這套方案了。

幸運的是,由于采用redis讀寫分離架構,就必須要考慮主從同步的延遲性問題,徒增系統複雜度。目前業内采用redis讀寫分離架構的項目,真的太少了。

原因很簡單,因為無論哪種持久化方式都會影響redis的性能,哪一種持久化都會造成CPU卡頓,影響對用戶端請求的處理。為了保證讀寫最佳性能,将master的持久化關閉!

RDB持久化

RDB持久化是将目前程序中的資料生成快照儲存到硬碟(是以也稱作快照持久化),儲存的檔案字尾是rdb;當Redis重新啟動時,可以讀取快照檔案恢複資料。

那麼RDB持久化的過程,相當于在執行bgsave指令。該指令執行過程如下圖所示

【原創】你的Redis怎麼持久化的

如圖所示,主線程需要調用系統函數fork(),建構出一個子程序進行持久化!很不幸的是,在建構子程序的過程中,父程序就會阻塞,無法響應用戶端的請求!

而且,在測試中發現,fork函數在虛拟機上較慢,真機上較快。考慮到現在都是部署在docker容器中,很少部署在真機上,為了性能,master不建議打開RDB持久化!

AOF持久化

RDB持久化是将程序資料寫入檔案,而AOF持久化(即Append Only File持久化),則是将Redis執行的每次寫指令記錄到單獨的日志檔案中。

随着時間的流逝,你會發現這個AOF檔案越來越大,于是redis有一套rewrite機制,來縮小AOF檔案的體積。然而,在rewrite的過程中也是需要父程序來fork出一個子程序進行rewrite操作。至于fork函數的影響,上面提到過了。

還有一個就是刷盤政策fsync,這個值推薦是配everysec,也就是Redis會預設每隔一秒進行一次fsync調用,将緩沖區中的資料寫到磁盤。

然而,如果磁盤性能不穩定,fsync的調用時間超過1秒鐘。此時主線程進行AOF的時候會對比上次fsync成功的時間;如果距上次不到2s,主線程直接傳回;如果超過2s,則主線程阻塞直到fsync同步完成。

是以AOF也是會影響redis的性能的。

<code>ps</code>:linux函數中,wrtie函數将資料寫入檔案的時候,是将資料寫入作業系統的緩沖區,還并未刷入磁盤。而fsync函數,可以強制讓作業系統将緩沖區資料刷入磁盤。

綜上所述,我們為了保證讀寫性能最大化,将master的持久化關閉。

首先,我先說明一下,我不推薦單開AOF的原因是,基于AOF的資料恢複太慢。

你要想,我們已經做了主從複制,資料已經實作備份,為什麼slave還需要開持久化?

因為某一天可能因為某某工程,把機房的電線挖斷了,就會導緻master和slave機器同時關機。

那麼這個時候,我們需要迅速恢複叢集,而RDB檔案檔案小、恢複快,是以災難恢複常用RDB檔案。

其次,官網也不推薦單開AOF,位址如下:

<code>https://redis.io/topics/persistence</code>

截圖如下

【原創】你的Redis怎麼持久化的

是以,如果實在對資料安全有一定要求,将AOF和RDB持久化都開啟。

另外,做好災難備份。利用linux的scp指令,定期将rdb檔案拷貝到雲伺服器上。

<code>ps</code>:scp是secure copy的簡寫,用于在Linux下進行遠端拷貝檔案的指令,和它類似的指令有cp,不過cp隻是在本機進行拷貝不能跨伺服器,而且scp傳輸是加密的。

本文提出的是一種通用的持久化政策,主要目的是在面試的時候被問到,給出一個合理的回答,而不至于一臉懵逼。

作者:孤獨煙

出處: http://rjzheng.cnblogs.com/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。如果覺得還有幫助的話,可以點一下右下角的【推薦】。