1. 程式人生 > 實用技巧 >elk之外掛部署 (實操三)

elk之外掛部署 (實操三)

https://www.cnblogs.com/wt645631686/p/6868615.html

Redis為了內部資料的安全考慮,會把本身的資料以檔案形式儲存到硬碟中一份,在伺服器重啟之後會自動把硬碟的資料恢復到記憶體(redis)的裡邊,資料儲存到硬碟的過程就稱為“持久化”效果。

redis有兩種持久化功能,一種是“快照持久化(RDB)”,一種是“AOF持久化”。

----------以下內容摘自《Redis深度歷險:核心原理和應用實踐》---------------

Redis的資料全部在記憶體裡,如果突然宕機,資料就會全部丟失,因此必須有一種機制 來保證Redis的資料不會因為故障而丟失,這種機制就是Redis的持久化機制。

Redis的持久化機制有兩種,第一種是快照,第二種是AOF日誌。快照是一次全量備 份,AOF日誌是連續的增量備份。快照是記憶體資料的二進位制序列化形式,在儲存上非常緊湊,而AOF日誌記錄的是記憶體資料修改的指令記錄文字。AOF日誌在長期的執行過程中會 變的無比龐大,資料庫重啟時需要載入AOF日誌進行指令重放,這個時間就會無比漫長。 所以需要定期進行AOF重寫,給AOF日誌進行瘦身。

快照原理

我們知道Redis是單執行緒程式,這個執行緒要同時負責多個客戶端套接字的併發讀寫操作 和記憶體資料結構的邏輯讀寫。

在服務線上請求的同時,Redis還需要進行記憶體快照,記憶體快照要求Redis必須進行文 件IO操作,可檔案IO操作是不能使用多路複用API。

這意味著單執行緒同時在服務線上的請求還要進行檔案IO操作,檔案IO操作會嚴重拖 垮伺服器請求的效能。還有個重要的問題是為了不阻塞線上的業務,就需要邊持久化邊響應 客戶端請求。持久化的同時,記憶體資料結構還在改變,比如一個大型的hash字典正在持久 化,結果一個請求過來把它給刪掉了,還沒持久化完呢,這尼瑪要怎麼搞?

那該怎麼辦呢?

Redis使用作業系統的多程序COW(Copy On Write)機制來實現快照持久化,這個機制 很有意思,也很少人知道。多程序COW也是鑑定程式設計師知識廣度的一個重要指標。

fork(多程序)

Redis在持久化時會呼叫glibc的函式fork產生一個子程序,快照持久化完全交給子進 程來處理,父程序繼續處理客戶端請求。子程序剛剛產生時,它和父程序共享記憶體裡面的代 碼段和資料段。這時你可以將父子程序想像成一個連體嬰兒,共享身體。這是Linux作業系統的機制,為了節約記憶體資源,所以儘可能讓它們共享起來。在程序分離的一瞬間,記憶體的增長几乎沒有明顯變化。子程序做資料持久化,它不會修改現有的記憶體資料結構,它只是對資料結構進行遍歷讀取,然後序列化寫到磁碟中。但是父程序不一樣,它必須持續服務客戶端請求,然後對記憶體資料結構進行不間斷的修改。這個時候就會使用作業系統的COW機制來進行資料段頁面的分離。資料段是由很多操 作系統的頁面組合而成,當父程序對其中一個頁面的資料進行修改時,會將被共享的頁面復 制一份分離出來,然後對這個複製的頁面進行修改。這時子程序相應的頁面是沒有變化的, 還是程序產生時那一瞬間的資料。

隨著父程序修改操作的持續進行,越來越多的共享頁面被分離出來,記憶體就會持續增 長。但是也不會超過原有資料記憶體的2倍大小。另外一個Redis例項裡冷資料佔的比例往 往是比較高的,所以很少會出現所有的頁面都會被分離,被分離的往往只有其中一部分頁 面。每個頁面的大小隻有4K,一個Redis例項裡面一般都會有成千上萬的頁面。

子程序因為資料沒有變化,它能看到的記憶體裡的資料在程序產生的一瞬間就凝固了,再 也不會改變,這也是為什麼Redis的持久化叫「快照」的原因。接下來子程序就可以非常安 心的遍歷資料了進行序列化寫磁碟了。

AOF原理

AOF日誌儲存的是Redis伺服器的順序指令序列,AOF日誌只記錄對記憶體進行修改的 指令記錄。

假設AOF日誌記錄了自Redis例項建立以來所有的修改性指令序列,那麼就可以通過 對一個空的Redis例項順序執行所有的指令,也就是「重放」,來恢復Redis當前例項的內 存資料結構的狀態。

Redis會在收到客戶端修改指令後,先進行引數校驗,如果沒問題,就立即將該指令文 本儲存到AOF日誌中,也就是先存到磁碟,然後再執行指令。這樣即使遇到突發宕機,已 經儲存到AOF日誌的指令進行重放一下就可以恢復到宕機前的狀態。

Redis在長期執行的過程中,AOF的日誌會越變越長。如果例項宕機重啟,重放整個AOF日誌會非常耗時,導致長時間Redis無法對外提供服務。所以需要對AOF日誌瘦 身。

AOF重寫

Redis提供了bgrewriteaof指令用於對AOF日誌進行瘦身。其原理就是開闢一個子進 程對記憶體進行遍歷轉換成一系列Redis的操作指令,序列化到一個新的AOF日誌檔案中。 序列化完畢後再將操作期間發生的增量AOF日誌追加到這個新的AOF日誌檔案中,追加 完畢後就立即替代舊的AOF日誌檔案了,瘦身工作就完成了。

fsync

AOF日誌是以檔案的形式存在的,當程式對AOF日誌檔案進行寫操作時,實際上是將 內容寫到了核心為檔案描述符分配的一個記憶體快取中,然後核心會非同步將髒資料刷回到磁碟 的。

這就意味著如果機器突然宕機,AOF日誌內容可能還沒有來得及完全刷到磁碟中,這個 時候就會出現日誌丟失。那該怎麼辦?

Linux的glibc提供了fsync(int fd)函式可以將指定檔案的內容強制從核心快取刷到磁 盤。只要Redis程序實時呼叫fsync函式就可以保證aof日誌不丟失。但是fsync是一個 磁碟IO操作,它很慢!如果Redis執行一條指令就要fsync一次,那麼Redis高效能的 地位就不保了。

所以在生產環境的伺服器中,Redis通常是每隔1s左右執行一次fsync操作,週期1s是可以配置的。這是在資料安全性和效能之間做了一個折中,在保持高效能的同時,儘可能 使得資料少丟失。

Redis同樣也提供了另外兩種策略,一個是永不fsync——讓作業系統來決定合適同步磁 盤,很不安全,另一個是來一個指令就fsync一次——非常慢。但是在生產環境基本不會使 用,瞭解一下即可。

運維

快照是通過開啟子程序的方式進行的,它是一個比較耗資源的操作。

1、遍歷整個記憶體,大塊寫磁碟會加重系統負載
2、AOF的fsync是一個耗時的IO操作,它會降低Redis效能,同時也會增加系統IO負擔

所以通常Redis的主節點是不會進行持久化操作,持久化操作主要在從節點進行。從節 點是備份節點,沒有來自客戶端請求的壓力,它的作業系統資源往往比較充沛。但是如果出現網路分割槽,從節點長期連不上主節點,就會出現資料不一致的問題,特別是在網路分割槽出現的情況下又不小心主節點宕機了,那麼資料就會丟失,所以在生產環境要做好實時監控工作,保證網路暢通或者能快速修復。另外還應該再增加一個從節點以降低網路分割槽的概率,只要有一個從節點資料同步正常,資料也就不會輕易丟失。

----------以上內容摘自《Redis深度歷險:核心原理和應用實踐》---------------

1.snap shotting快照持久化

該持久化預設開啟,一次性把redis中全部的資料儲存一份儲存在硬碟中,如果資料非常多(10-20G)就不合適頻繁操作該持久化操作。

如果對redis有資料操作,就會根據redis的配置檔案指定的檔名和路徑生成rdb檔案,先來看一下redis配置方面的截圖說明

再看一下在redis目錄下生成的rdb檔案

可以使用vim命令對dump.rdb檔案編輯看一下內容

注意:如果您細心的發現,在對redis客戶端進行資料操作之後,再次進行對dump.rdb檔案進行編輯檢視,檔案中可能會缺少最近的操作記錄,這與配置檔案中備份的頻率有關,下面看一下截圖

save 900 1             #900 秒內如果超過 1 個 key 被修改,則發起快照儲存
save 300 10            #300秒超過10個key被修改,發起快照
save 60 10000            #60秒超過10000個key被修改,發起快照

以上三個save的意思都有了相應的說明,資料修改的頻率非常高,備份的頻率也高,資料修改的頻率低,備份的頻率也低。

如果發現dump.rdb檔案缺少了最近的記錄,那麼在這補充一種手動持久化方式,可以立即看到效果,執行此命令

./redis-cli bgsave          #非同步儲存

其次還包括一些其他的手動命令

./redis-cli shutdown    #同步儲存到伺服器並關閉redis伺服器
./redis-cli lastsave    #返回上次成功儲存到磁碟的unix時間戳
./redis-cli bgrewriteaof  #當日志文件過長時優化AOF日誌檔案儲存

由於快照方式是在一定間隔時間做一次的,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改。如果應用要求不能丟失任何修改的話,可以採用aof持久化方式

2.append only file(AOF持久化)

AOF持久化本質:把使用者執行的每個“寫”指令(新增/修改/刪除)都備份到檔案中,還原資料的時候就是執行具體寫指令而已。

開啟AOF持久化(會清空redis內部的資料,最好在redis使用之前就開啟它)

我們在redis.conf配置檔案中可以找到它:

修改完成配置之後重啟redis

再次啟動測試一下是否有資料

看一下目錄下自定義的aof檔案,目前得大小是0

操作之後

vim檢視一下

所有指令全部寫入檔案

在redis.conf中,可以調整AOF備份形式:

always          一寫指令就備份一次。這樣做雖然安全,但是系統性能會降低。不推薦使用
everysec         每一秒中備份一次。不管一秒鐘變化了多少key,只備份一次,效能得到一定的保護。推薦使用。
no            會檢視當前伺服器狀態,如果狀態良好,就進行備份(隨機)。這種備份方式資料是沒有保證的。

對比下來,效能:always<everysec<no,而資料安全:always>everysec>no。

舉例說明一下,這裡就暫時不操作了,您可以拿redis的自增來操作:incr num ,執行此命令10次,然後檢視一下aof檔案,發現aof檔案儲存的是最終的數值,而且是set命令,這樣就節省了空間,下面說一下就是把AOF備份檔案中所有的備份資料的內容進行一個處理。

在啟動redis客戶端的時候,使用bgrewriteaof指令,就可以對aof備份檔案的內容進行

優化壓縮處理。截圖對比一下處理先後的大小

完畢