緣起:php
今天早晨收到報警,服務不幹活了,趕忙起來看問題。。。redis
爲了儘快讓服務可用,嘗試重啓服務,發現服務起不來,報錯數據庫
redis connection failed!
看起來是redis掛了,可是發現redis的進程還在。進一步看服務的錯誤日誌:緩存
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the d
ata set are disabled. Please check Redis logs for details about the error.
redis持久化失敗,服務配置了redis rdb持久化方式,爲啥失敗呢?內存和硬盤看了下,果真硬盤滿了。清理硬盤ok了。安全
redis持久化策略(RDB/AOF)app
一、RDB快照(snapshots)性能
缺省狀況狀況下,Redis把數據快照存放在磁盤上的二進制文件中,文件名爲dump.rdb。你能夠配置Redis的持久化策略,例如數據集中每N秒鐘有超過M次更新,就將數據寫入磁盤;或者你能夠手工調用命令SAVE或BGSAVE。spa
數據保存的目錄:操作系統
工做原理設計
寫時複製(copy-on-write/COW)技術:
寫入時複製(Copy-on-write)是一個被使用在程式設計領域的最佳化策略。其基礎的觀念是,若是有多個呼叫者(callers)同時要求相同資源,他們會共同取得相同的指標指向相同的資源,直到某個呼叫者(caller)嘗試修改資源時,系統纔會真正複製一個副本(private copy)給該呼叫者,以免被修改的資源被直接察覺到,這過程對其餘的呼叫只都是通透的(transparently)。此做法主要的優勢是若是呼叫者並無修改該資源,就不會有副本(private copy)被創建。
二、APPEND ONLY MODE(AOF)
快照模式並不十分健壯,當系統中止,或者無心中Redis被kill掉,最後寫入Redis的數據就會丟失。這對某些應用也許不是大問題,但對於要求高可靠性的應用來講,Redis就不是一個合適的選擇。
Append-only文件模式是另外一種選擇。
你能夠在配置文件中打開AOF模式:
選項:
一、appendfsync no
當設置appendfsync爲no的時候,Redis不會主動調用fsync去將AOF日誌內容同步到磁盤,因此這一切就徹底依賴於操做系統的調試了。對大多數Linux操做系統,是每30秒進行一次fsync,將緩衝區中的數據寫到磁盤上。
二、appendfsync everysec
當設置appendfsync爲everysec的時候,Redis會默認每隔一秒進行一次fsync調用,將緩衝區中的數據寫到磁盤。可是當這一 次的fsync調用時長超過1秒時。Redis會採起延遲fsync的策略,再等一秒鐘。也就是在兩秒後再進行fsync,這一次的fsync就無論會執行多長時間都會進行。這時候因爲在fsync時文件描述符會被阻塞,因此當前的寫操做就會阻塞。
因此,結論就是:在絕大多數狀況下,Redis會每隔一秒進行一次fsync。在最壞的狀況下,兩秒鐘會進行一次fsync操做。
這一操做在大多數數據庫系統中被稱爲group commit,就是組合屢次寫操做的數據,一次性將日誌寫到磁盤。
三、appednfsync always
當設置appendfsync爲always時,每一次寫操做都會調用一次fsync,這時數據是最安全的,固然,因爲每次都會執行fsync,因此其性能也會受到影響
建議採用 appendfsync everysec(缺省方式)
快照模式能夠和AOF模式同時開啓,互補影響
三、AOF重寫
AOF文件是可識別的純文本,它的內容就是一個個的Redis標準命令,
AOF日誌也不是徹底按客戶端的請求來生成日誌的,好比命令 INCRBYFLOAT 在記AOF日誌時就被記成一條SET記錄,由於浮點數操做可能在不一樣的系統上會不一樣,因此爲了不同一份日誌在不一樣的系統上生成不一樣的數據集,因此這裏只將操做後的結果經過SET來記錄。
每一條寫命令都生成一條日誌,AOF文件會很大。
AOF重寫是從新生成一份AOF文件,新的AOF文件中一條記錄的操做只會有一次,而不像一份老文件那樣,可能記錄了對同一個值的屢次操做。其生成過程和RDB相似,也是fork一個進程,直接遍歷數據,寫入新的AOF臨時文件。在寫入新文件的過程當中,全部的寫操做日誌仍是會寫到原來老的 AOF文件中,同時還會記錄在內存緩衝區中。當重完操做完成後,會將全部緩衝區中的日誌一次性寫入到臨時文件中。而後調用原子性的rename命令用新的 AOF文件取代老的AOF文件
命令:BGREWRITEAOF, 咱們應該常常調用這個命令來來重寫
數據恢復:
寫數據的流程: