記錄一次由於硬盤寫滿形成的redis沒法鏈接

緣起: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次更新,就將數據寫入磁盤;或者你能夠手工調用命令SAVEBGSAVEspa

數據保存的目錄:操作系統

 

工做原理設計

  • Redis forks.
  • 子進程開始將數據寫到臨時RDB文件中。
  • 當子進程完成寫RDB文件,用新文件替換老文件。
  • 這種方式可使Redis使用copy-on-write技術。

寫時複製(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, 咱們應該常常調用這個命令來來重寫

 

數據恢復:

  • 若是隻配置AOF,重啓時加載AOF文件恢復數據;
  • 若是同時 配置了RBD和AOF,啓動是隻加載AOF文件恢復數據;
  • 若是隻配置RBD,啓動是講加載dump文件恢復數據。

 

寫數據的流程:

    1. 客戶端向服務端發送寫操做(數據在客戶端的內存中)。
    2. 數據庫服務端接收到寫請求的數據(數據在服務端的內存中)。
    3. 服務端調用write這個系統調用,將數據往磁盤上寫(數據在系統內存的緩衝區中)。
    4. 操做系統將緩衝區中的數據轉移到磁盤控制器上(數據在磁盤緩存中)。
    5. 磁盤控制器將數據寫到磁盤的物理介質中(數據真正落到磁盤上)。
相關文章
相關標籤/搜索