存儲
redis使用了兩種文件格式:全量數(shù)據(jù)和增量請求蒋纬。
全量數(shù)據(jù)格式是把內存中的數(shù)據(jù)寫入磁盤猎荠,便于下次讀取文件進行加載;
增量請求文件則是把內存中的數(shù)據(jù)序列化為操作請求蜀备,用于讀取文件進行replay得到數(shù)據(jù)关摇,序列化的操作包括SET、RPUSH碾阁、SADD输虱、ZADD。
redis的存儲分為內存存儲脂凶、磁盤存儲和log文件三部分宪睹,配置文件中有三個參數(shù)對其進行配置。
save seconds updates艰猬,save配置横堡,指出在多長時間內,有多少次更新操作冠桃,就將數(shù)據(jù)同步到數(shù)據(jù)文件命贴。這個可以多個條件配合,比如默認配置文件中的設置,就設置了三個條件胸蛛。
appendonly
yes/no
污茵,appendonly配置,指出是否在每次更新操作后進行日志記錄葬项,如果不開啟泞当,可能會在斷電時導致一段時間內的數(shù)據(jù)丟失。因為redis本身同步數(shù)據(jù)文件是按上面的save條件來同步的民珍,所以有的數(shù)據(jù)會在一段時間內只存在于內存中襟士。
appendfsync no/always/everysec ,appendfsync配置嚷量,no表示等操作系統(tǒng)進行數(shù)據(jù)緩存同步到磁盤陋桂,always表示每次更新操作后手動調用fsync()將數(shù)據(jù)寫到磁盤,everysec表示每秒同步一次蝶溶。
Redis的持久化
Redis雖然是基于內存的存儲系統(tǒng)嗜历,但是它本身是支持內存數(shù)據(jù)的持久化的,而且提供兩種主要的持久化策略:RDB快照和AOF日志抖所。
Redis的RDB快照
Redis支持將當前數(shù)據(jù)的快照存成一個數(shù)據(jù)文件的持久化機制梨州,即RDB快照。這種方法是非常好理解的田轧,但是一個持續(xù)寫入的數(shù)據(jù)庫如何生成快照呢暴匠?Redis借助了fork命令的copy on write機制。在生成快照時涯鲁,將當前進程fork出一個子進程巷查,然后在子進程中循環(huán)所有的數(shù)據(jù),將數(shù)據(jù)寫成為RDB文件抹腿。
我們可以通過Redis的save指令來配置RDB快照生成的時機岛请,比如你可以配置當10分鐘以內有100次寫入就生成快照,也可以配置當1小時內有1000次寫入就生成快照警绩,也可以多個規(guī)則一起實施崇败。這些規(guī)則的定義就在Redis的配置文件中,你也可以通過Redis的CONFIG SET命令在Redis運行時設置規(guī)則肩祥,不需要重啟Redis后室。
Redis的RDB文件不會壞掉,因為其寫操作是在一個新進程中進行的混狠,當生成一個新的RDB文件時岸霹,Redis生成的子進程會先將數(shù)據(jù)寫到一個臨時文件中,然后通過原子性rename系統(tǒng)調用將臨時文件重命名為RDB文件将饺,這樣在任何時候出現(xiàn)故障贡避,Redis的RDB文件都總是可用的痛黎。同時,Redis的RDB文件也是Redis主從同步內部實現(xiàn)中的一環(huán)刮吧。
Redis的AOF日志
AOF日志的全稱是append only file湖饱,從名字上我們就能看出來,它是一個追加寫入的日志文件杀捻。
AOF是一個寫文件操作井厌,其目的是將操作日志寫到磁盤上,所以它也同樣會遇到我們上面說的寫操作的5個流程致讥。那么寫AOF的操作安全性又有多高呢仅仆。實際上這是可以設置的,在Redis中對AOF調用write(2)寫入后垢袱,何時再調用fsync將其寫到磁盤上蝇恶,通過appendfsync選項來控制,下面appendfsync的三個設置項惶桐,安全強度逐漸變強。
1)appendfsync no
當設置appendfsync為no的時候潘懊,Redis不會主動調用fsync去將AOF日志內容同步到磁盤姚糊,所以這一切就完全依賴于操作系統(tǒng)的調試了。對大多數(shù)Linux操作系統(tǒng)授舟,是每30秒進行一次fsync救恨,將緩沖區(qū)中的數(shù)據(jù)寫到磁盤上。
2)appendfsync everysec
當設置appendfsync為everysec的時候释树,Redis會默認每隔一秒進行一次fsync調用肠槽,將緩沖區(qū)中的數(shù)據(jù)寫到磁盤。但是當這一次的fsync調用時長超過1秒時奢啥。Redis會采取延遲fsync的策略秸仙,再等一秒鐘。也就是在兩秒后再進行fsync桩盲,這一次的fsync就不管會執(zhí)行多長時間都會進行寂纪。這時候由于在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞赌结。所以結論就是捞蛋,在絕大多數(shù)情況下,Redis會每隔一秒進行一次fsync柬姚。在最壞的情況下拟杉,兩秒鐘會進行一次fsync操作。這一操作在大多數(shù)數(shù)據(jù)庫系統(tǒng)中被稱為group commit量承,就是組合多次寫操作的數(shù)據(jù)搬设,一次性將日志寫到磁盤穴店。
3)appednfsync always
當設置appendfsync為always時,每一次寫操作都會調用一次fsync焕梅,這時數(shù)據(jù)是最安全的迹鹅,當然,由于每次都會執(zhí)行fsync贞言,所以其性能也會受到影響斜棚。