首頁  >  文章  >  資料庫  >  redis怎麼實現持久化

redis怎麼實現持久化

silencement
silencement原創
2019-06-04 17:05:063412瀏覽

redis怎麼實現持久化

redis作為當下web程式設計必不可少的服務,它的特點的是顯而易見,相對memcached而言,做緩存,重啟資料不遺失,非常好用。那麼問題來了,它是怎麼做到的呢?

RDB

RDB就是持久化的一種手段,把記憶體中資料在某些條件下寫到磁碟中去。那麼在哪些條件下寫入呢?不可能無腦寫入,來一個寫一個,影響性能,也不能等老半天才寫一個,萬一中間宕機了,數據全丟失,還不如用memcached。在redis的配置裡有著這樣的一段配置:

save 900 1

save 300 10

save 60 10000

很關鍵的一段配置,這時RDB持久化的核心。意思是:

1.如果900秒時,有1個key變化(插入或更新),我就同步到磁碟一下

2.如果300秒時,有10個key變化(插入或更新),我就同步到磁碟一下

3.如果60秒時,有10000個key變化(插入或更新),我就同步到磁碟一下

#這些時間點和變化的數量是怎麼知道的,這時有另外兩個極為關鍵的東西,一個叫dirty計數器,一個叫lastsave(上次save的時間),dirty計數器專門記錄從上次save後變化key的數量,lastsave記錄執行save的時間,舉個例子剛開始時間是time1,dirty是0,這時有20個key發生了變化,dirty是20,然後現在的時間是time2,time2-time1 > ;= 300,滿足第二個條件,這時記憶體中的資料會save一下,同時dirty清為0,然後再等待條件觸發。

如果我60秒內有10萬個key,那麼問題來了,一下大量磁碟io來臨,這時redis主進程就會阻塞,期間的所有的命令都不執行,這哪能行,於是就來了一個叫bgsave的,它是redis主進程fork出來的一個子進程,專門執行rdb的持久化工作的。

儲存的檔案格式是二進位格式的,萬一資料庫宕機,復原不需要人為幹預,redis會自動讀取磁碟檔案。

AOF

與RDB不同,AOF儲存的是你執行的指令,當aof功能開啟的時候,執行的更新指令不會直接寫到aof文件中去,而是先寫到一個aof buf中,我們知道不能一直往buf中寫,buf也是內存啊,那麼何時才能同步到磁碟中去呢? redis中也有這樣一段配置

appendfsync always

appendfsync everysec

appendfsync no

##意思是:

1.只要有更新的命令我就同步

2.如果上次同步時間距離現在超過一秒就同步

3.不同步,等待作業系統自己判斷(什麼時候有空我才同步)

分析下,第一種io頻繁,io壓力大,但丟失數據的機率最小,第二種io壓力不是很大,最多也就丟失1秒左右的數據,第三中io壓力很小,遺失資料機率太大。綜合考慮,一般第二種。但還有個問題,我執行了100次INCR num,依道理num就是100,aof中也有100個同樣的指令,沒毛病,那麼請問執行100次INCR num和SET num 100有什麼差別,同樣的結果前者多了99倍的空間,很浪費啊,於是就出現了AOF重寫,它是怎麼做到的。很簡單:先從資料庫讀取現在的值,再用一筆記錄代替,這就是AOF重寫的原理。重寫很花時間,所以也是子進程來處理。重寫的過程中,如果有新的命令來臨怎麼辦,老辦法,寫buf緩衝,重寫完成後,把buf中的命令追加到新的aof中,然後用新的aof替代老的aof,就實現了重寫。

本文來自

redis教學,歡迎學習。

以上是redis怎麼實現持久化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn