亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文詳解Redis中的持久化

 更新時間:2022年09月19日 10:35:48   作者:Wang1???????  
這篇文章主要介紹了一文詳解Redis中的持久化,持久化功能有效地避免因進程退出造成的數(shù)據(jù)丟失問題,當下次重啟時利用之前持久化的文件即可實現(xiàn)數(shù)據(jù)恢復

1. 前言

為什么要進行持久化?:持久化功能有效地避免因進程退出造成的數(shù)據(jù)丟失問題,當下次重啟時利用之前持久化的文件即可實現(xiàn)數(shù)據(jù)恢復。

持久化都有那些方式?:Redis支持RDB和AOF兩種持久化機制。

2. RDB

RDB持久化是把當前進程數(shù)據(jù)生成快照保存到硬盤的過程,觸發(fā)RDB持久化過程分為手動觸發(fā)自動觸發(fā)。

2.1 手動觸發(fā)

手動觸發(fā)分別對應savebgsave命令:

  • save 命令::阻塞當前Redis服務器,直到RDB過程完成為止,對于內(nèi)存比較大的實例會造成長時間阻塞,線上環(huán)境不建議使用。
  • bgsave 命令:Redis進程執(zhí)行fork操作創(chuàng)建子進程,RDB持久化過程由子進程負責,完成后自動結(jié)束。阻塞只發(fā)生在fork階段,一般時間很短。

顯然bgsave命令是針對save阻塞問題做的優(yōu)化。因此Redis內(nèi)部所有的涉及RDB的操作都采用bgsave的方式,而save命令已經(jīng)廢棄。

2.2 自動觸發(fā)

  • 使用save相關配置,如save m n。表示m秒內(nèi)數(shù)據(jù)集存在n次修改時,自動觸發(fā)bgsave。
  • 如果從節(jié)點執(zhí)行全量復制操作,主節(jié)點自動執(zhí)行bgsave生成RDB文件并發(fā)送給從節(jié)點。
  • 執(zhí)行debug reload命令重新加載Redis時,也會自動觸發(fā)save操作。
  • 默認情況下執(zhí)行shutdown命令時,如果沒有開啟AOF持久化功能則自動執(zhí)行bgsave。

3. bgsave大致流程

流程說明:

  • 執(zhí)行bgsave命令,Redis父進程判斷當前是否存在正在執(zhí)行的子進程,如RDB/AOF子進程,如果存在bgsave命令直接返回。
  • 父進程執(zhí)行fork操作創(chuàng)建子進程,fork操作過程中父進程會阻塞,通過info stats命令查看latest_fork_usec選項,可以獲取最近一個fork操作的耗時,單位為微秒。
  • 父進程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父進程,可以繼續(xù)響應其他命令。
  • 子進程創(chuàng)建RDB文件,根據(jù)父進程內(nèi)存生成臨時快照文件,完成后對原有文件進行原子替換。執(zhí)行lastsave命令可以獲取最后一次生成RDB的時間,對應info統(tǒng)計的rdb_last_save_time選項。
  • 進程發(fā)送信號給父進程表示完成,父進程更新統(tǒng)計信息,具體見info Persistence下的rdb_*相關選項。

關于RDB文件:

  • 存儲位置:RDB文件保存在dir配置指定的目錄下,文件名通過dbfilename配置指定。可以通過執(zhí)行config set dir{newDir}和config set dbfilename{newFileName}運行期動態(tài)執(zhí)行,當下次運行時RDB文件會保存到新目錄。
  • 壓縮:Redis默認采用LZF算法對生成的RDB文件做壓縮處理,壓縮后的文件遠遠小于內(nèi)存大小,默認開啟,可以通過參數(shù)config set rdbcompression{yes|no}動態(tài)修改。
  • 校驗:如果Redis加載損壞的RDB文件時拒絕啟動,并打印 # Short read or OOM loading DB. Unrecoverable error, aborting now. (可以使用Redis提供的redis-check-dump工具檢測RDB文件并獲取對應的錯誤報告)。

4. RDB持久化方式的優(yōu)缺點

優(yōu)點:

  • RDB是一個緊湊壓縮的二進制文件,代表Redis在某個時間點上的數(shù)據(jù)快照。非常適用于備份,全量復制等場景。比如每6小時執(zhí)行bgsave備份,并把RDB文件拷貝到遠程機器或者文件系統(tǒng)中(如hdfs),用于災難恢復。(數(shù)據(jù)緊湊,便于存儲)
  • Redis加載RDB恢復數(shù)據(jù)遠遠快于AOF的方式。(恢復速度快)

缺點:

  • RDB方式數(shù)據(jù)沒辦法做到實時持久化/秒級持久化。因為bgsave每次運行都要執(zhí)行fork操作創(chuàng)建子進程,屬于重量級操作,頻繁執(zhí)行成本過高。(成本高)
  • RDB文件使用特定二進制格式保存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法兼容新版RDB格式的問題。(不兼容)

5. AOF

AOF(append only file)持久化:以獨立日志的方式記錄每次寫命令,重啟時再重新執(zhí)行AOF文件中的命令達到恢復數(shù)據(jù)的目的。主要作用是解決了數(shù)據(jù)持久化的實時性。

6. AOF的使用方式

  • 開啟AOF功能需要設置配置:appendonly yes,默認不開啟。
  • AOF文件名通過appendfilename配置設置,默認文件名是appendonly.aof。(路徑同RDB)
  • 主要流程有命令寫入(append)、文件同步(sync)、文件重寫(rewrite)、重啟加載(load)。

7. AOF流程剖析

流程描述:

  • 所有的寫入命令會追加到aof_buf(緩沖區(qū))中。
  • AOF緩沖區(qū)根據(jù)對應的策略向硬盤做同步操作。
  • 隨著AOF文件越來越大,需要定期對AOF文件進行重寫,達到壓縮的目的。
  • 當Redis服務器重啟時,可以加載AOF文件進行數(shù)據(jù)恢復。

7.1 命令寫入

AOF命令寫入的內(nèi)容直接是文本協(xié)議格式。例如set hello world這條命令,在AOF緩沖區(qū)會追加如下文本:

*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n

為什么使用文本協(xié)議格式?

  • 文本協(xié)議具有很好的兼容性。(兼容性好)
  • 開啟AOF后,所有寫入命令都包含追加操作,直接采用協(xié)議格式,避免了二次處理開銷。(處理簡單)
  • 文本協(xié)議具有可讀性,方便直接修改和處理。(方便修改)

為什么要追加到aof_buf中而不是直接寫入硬盤?

  • 如果每次寫AOF文件命令都直接追加到硬盤,那么Redis的性能就會受到硬盤讀寫速度的影響,而硬盤的讀寫速度相對于內(nèi)存則是數(shù)量級上的差距,所以如果每次直接寫入硬盤則勢必會大幅度影響Redis的運行速度。(影響運行速度)
  • 使用緩沖區(qū)暫存,Redis還可以提供多種緩沖區(qū)同步硬盤的策略,在性能和安全性方面做出平衡。(可以針對具體場景干預刷盤策略,以達到更好的效果)

7.2 文件同步

Redis提供了多種AOF緩沖區(qū)同步文件策略,由參數(shù)appendfsync控制。

系統(tǒng)調(diào)用write和fsync的幾點說明:

  • write :會觸發(fā)延遲寫(delayed write)機制。Linux在內(nèi)核提供頁緩沖區(qū)用來提高硬盤IO性能。write操作在寫入系統(tǒng)緩沖區(qū)后直接返回。同步硬盤操作依賴于系統(tǒng)調(diào)度機制,例如:緩沖區(qū)頁空間寫滿或達到特定時間周期。同步文件之前,如果此時系統(tǒng)故障宕機,緩沖區(qū)內(nèi)數(shù)據(jù)將丟失。(寫緩沖,定期由操作系統(tǒng)刷盤)
  • fsync :針對單個文件操作(比如AOF文件),做強制硬盤同步,fsync將阻塞直到寫入硬盤完成后返回,保證了數(shù)據(jù)持久化。(立即將緩沖數(shù)據(jù)刷盤)

策略的幾點說明:

  • always:每次寫入都要同步AOF文件,在一般的SATA硬盤上,Redis只能支持大約幾百TPS寫入,顯然跟Redis高性能特性背道而馳,不建議配置。
  • no:由于操作系統(tǒng)每次同步AOF文件的周期不可控,而且會加大每次同步硬盤的數(shù)據(jù)量,雖然提升了性能,但數(shù)據(jù)安全性無法保證。
  • everysec:是建議的同步策略,也是默認配置,做到兼顧性能和數(shù)據(jù)安全性。(在系統(tǒng)突然宕機的情況下丟失1~2秒的數(shù)據(jù))

7.3 重寫機制

為什么要重寫?:

  • 隨著命令不斷寫入AOF,文件會越來越大。
  • 會包含越來越多無用的命令記錄。(比如最近一次對一個值的更新操作,那么在此之前記錄的更新操作都會作廢)
  • 更小的AOF文件可以更快地被Redis加載。

怎么重寫?:

  • AOF文件重寫就是把Redis進程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令同步到新AOF文件。

重寫后那些優(yōu)化讓文件變小了?:

  • 進程內(nèi)已經(jīng)超時的數(shù)據(jù)不再寫入文件。(去除失效數(shù)據(jù))
  • 舊的AOF文件含有無效命令,如del key1、hdel key2、srem keys、set a111、set a222等。重寫使用進程內(nèi)數(shù)據(jù)直接生成,這樣新的AOF文件只保留最終數(shù)據(jù)的寫入命令。(去除無用命令)
  • 多條寫命令可以合并為一個,如:lpush list a、lpush list b、lpush list c可以轉(zhuǎn)化為:lpush list a b c;為了防止單條命令過大造成客戶 端緩沖區(qū)溢出,對于list、set、hash、zset等類型操作,以64個元素為界拆分為多條。(使用批量命令)

重寫有那些觸發(fā)方式?:

  • 手動觸發(fā) :直接調(diào)用bgrewriteaof命令。
  • 自動觸發(fā) :根據(jù)auto-aof-rewrite-min-size和auto-aof-rewritepercentage參數(shù)確定自動觸發(fā)時機。
    • auto-aof-rewrite-min-size:表示運行AOF重寫時文件最小體積,默認為64MB。(根據(jù)當前文件大小)
    • auto-aof-rewrite-percentage:代表當前AOF文件空間(aof_current_size)和上一次重寫后AOF文件空間(aof_base_size)的比值。(根據(jù)文件大小的增量)

自動觸發(fā)時機:

aof_current_size > auto-aof-rewrite-minsize && (aof_current_size-aof_base_size)/aof_base_size >= auto-aof-rewrite-percentage

aof_current_size 和 aof_base_size 可以在info Persistence統(tǒng)計信息中查看。

重寫流程概述:

流程描述:

  • 執(zhí)行AOF重寫請求。

    • 如果當前進程正在執(zhí)行AOF重寫,請求不執(zhí)行并返回 ERR Background append only file rewriting already in progress 。
    • 如果當前進程正在執(zhí)行bgsave操作,重寫命令延遲到bgsave完成之后再執(zhí)行,返回 Background append only file rewriting scheduled
  • 父進程執(zhí)行fork創(chuàng)建子進程,開銷等同于bgsave過程。
  • (1)主進程fork操作完成后,繼續(xù)響應其他命令。所有修改命令依然寫入AOF緩沖區(qū)并根據(jù)appendfsync策略同步到硬盤,保證原有AOF機制正確性。(2)由于fork操作運用寫時復制技術(Copy On Write),子進程只能共享fork操作時的內(nèi)存數(shù)據(jù)。由于父進程依然響應命令,Redis使用“AOF重寫緩沖區(qū)”保存這部分新數(shù)據(jù),防止新AOF文件生成期間丟失這部分數(shù)據(jù)。
  • 子進程根據(jù)內(nèi)存快照,按照命令合并規(guī)則寫入到新的AOF文件。每次批量寫入硬盤數(shù)據(jù)量由配置aof-rewrite-incremental-fsync控制,默認為32MB,防止單次刷盤數(shù)據(jù)過多造成硬盤阻塞。
  • (1)新AOF文件寫入完成后,子進程發(fā)送信號給父進程,父進程更新統(tǒng)計信息,具體見info persistence的aof_*相關統(tǒng)計。(2)父進程把AOF重寫緩沖區(qū)的數(shù)據(jù)寫入到新的AOF文件(3)并使用新AOF文件替換老文件,完成AOF重寫。

7.4 重啟加載

流程描述:

  • AOF持久化開啟且存在AOF文件時,優(yōu)先加載AOF文件,并輸出 DB loaded from append only file: xxx seconds 。
  • AOF關閉或者AOF文件不存在時,加載RDB文件,并輸出 DB loaded from disk: xxx seconds 。
  • 加載AOF或RDB文件成功后,Redis啟動成功。
  • AOF或RDB文件存在錯誤時,Redis啟動失敗并打印錯誤信息。

關于文件校驗:

加載損壞的AOF文件時會拒絕啟動,并會輸出:

Bad file format reading the append only file: make a backup of your AOF file,then use ./redis-check-aof --fix <filename>

對于錯誤格式的AOF文件:先進行備份,然后采用redis-check-aof --fix命令進行修復,修復后使用diff-u對比數(shù)據(jù)的差異,找出丟失的數(shù)據(jù),有些可以人工修改補全。

對于AOF文件結(jié)尾不完整:比如機器突然掉電導致AOF尾部文件命令寫入不全。Redis為我們提供了aof-load-truncated配置來兼容這種情況,默認開啟。加載AOF時,當遇到此問題時會忽略并繼續(xù)啟動,同時打印如下警告日志:

# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 397856725 !!!
# AOF loaded anyway because aof-load-truncated is enabled

8. 問題定位與優(yōu)化

8.1 關于fork操作

當Redis做RDB或AOF重寫時,一個必不可少的操作就是執(zhí)行fork操作創(chuàng)建子進程,對于大多數(shù)操作系統(tǒng)來說fork是個重量級操作雖然fork創(chuàng)建的子進程不需要拷貝父進程的物理內(nèi)存空間,但是會復制父進程的空間內(nèi)存頁表,因此fork操作耗時跟進程總內(nèi)存量息息相關??梢栽趇nfo stats統(tǒng)計中查latest_fork_usec指標獲取最近一次fork操作耗時,單位微秒。

減少fork耗時的措施:

  • 優(yōu)先使用物理機或者高效支持fork操作的虛擬化技術,避免使用Xen。
  • 控制Redis實例最大可用內(nèi)存,fork耗時跟內(nèi)存量成正比,線上建議每個Redis實例內(nèi)存控制在10GB以內(nèi)。
  • 合理配置Linux內(nèi)存分配策略,避免物理內(nèi)存不足導致fork失敗。
  • 降低fork操作的頻率,如適度放寬AOF自動觸發(fā)時機,避免不必要的全量復制等。

8.2 關于子進程開銷

CPU:

  • 分析:子進程負責把進程內(nèi)的數(shù)據(jù)分批寫入文件,這個過程屬于CPU密集操作,通常子進程對單核CPU利用率接近90%。
  • 優(yōu)化:
    • Redis是CPU密集型服務,不要做綁定單核CPU操作。由于子進程非常消耗CPU,會和父進程產(chǎn)生單核資源競爭。
    • 不要和其他CPU密集型服務部署在一起,造成CPU過度競爭。
    • 如果部署多個Redis實例,盡量保證同一時刻只有一個子進程執(zhí)行重寫工作。

內(nèi)存:

  • 分析:得益于Linux的寫時復制機制(copy on write),父子進程會共享相同的物理內(nèi)存頁,當父進程處理寫請求時會把要修改的頁創(chuàng)建副本,而子進程在fork操作過程中共享整個父進程內(nèi)存快照。(重寫時共享同一份物理內(nèi)存區(qū)域,內(nèi)存主要開銷在于 拷貝的頁表 和 應用 copy on write 時某些頁的拷貝 以及在進行AOF重寫所使用的 aof_rewrite_buf占用的大小 )
  • 優(yōu)化:
    • 如果部署多個Redis實例,盡量保證同一時刻只有一個子進程在工作。
    • 避免在大量寫入時做子進程重寫操作,這樣將導致父進程維護大量頁副本,造成內(nèi)存消耗。
    • Linux kernel在2.6.38內(nèi)核增加了Transparent Huge Pages(THP),支持huge page(2MB)的頁分配,默認開啟。當開啟時可以降低fork創(chuàng) 建子進程的速度,但執(zhí)行fork之后,如果開啟THP,復制頁單位從原來4KB變?yōu)?MB,會大幅增加重寫期間父進程內(nèi)存消耗。

硬盤:

  • 分析:子進程主要職責是把AOF或者RDB文件寫入硬盤持久化,所以在執(zhí)行重寫的時候勢必會增加硬盤的寫入壓力。根據(jù)Redis重寫AOF或RDB的數(shù)據(jù)量,結(jié)合系統(tǒng)工具如sar、iostat、iotop等,可分析出重寫期間硬盤負載情況。
  • 優(yōu)化:
    • 不要和其他高硬盤負載的服務部署在一起。如:存儲服務、消息隊列服務等。
    • AOF重寫時會消耗大量硬盤IO,可以開啟配置no-appendfsyncon-rewrite,默認關閉。表示在AOF重寫期間不做fsync操作,注意!配置no-appendfsync-on-rewrite=yes時,在極端情況下可能丟失整個AOF重寫期間的數(shù)據(jù),需要根據(jù)數(shù)據(jù)安全性決定是否配置。
    • 當開啟AOF功能的Redis用于高流量寫入場景時,Redis的性能會受到硬盤寫入性能的影響。
    • 對于單機配置多個Redis實例的情況,可以配置不同實例分盤存儲AOF文件,分攤硬盤寫入壓力。

8.3 關于AOF追加阻塞

描述:當開啟AOF持久化時,常用的同步硬盤的策略是everysec,用于平衡性能和數(shù)據(jù)安全性。對于這種方式,Redis使用另一條線程每秒執(zhí)行fsync同步硬盤。當系統(tǒng)硬盤資源繁忙時,會造成Redis主線程阻塞。

問題定位:

  • 發(fā)生AOF阻塞時,Redis輸出日志,用于記錄AOF fsync阻塞導致拖慢Redis服務的行為: Asynchronous AOF fsync is taking too long (disk is busy). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redi
  • 每當發(fā)生AOF追加阻塞事件發(fā)生時,在info Persistence統(tǒng)計中,aof_delayed_fsync指標會累加,查看這個指標方便定位AOF阻塞問題。
  • AOF同步最多允許2秒的延遲,當延遲發(fā)生時說明硬盤存在高負載問題。

流程概述:

  • 主線程負責寫入AOF緩沖區(qū)。
  • AOF線程負責每秒執(zhí)行一次同步磁盤操作,并記錄最近一次同步時間。
  • 主線程負責對比上次AOF同步時間:
    • 如果距上次同步成功時間在2秒內(nèi),主線程直接返回。
    • 如果距上次同步成功時間超過2秒,主線程將會阻塞,直到同步操作完成。

也就是說:

  • everysec配置最多可能丟失2秒數(shù)據(jù),不是1秒。
  • 如果系統(tǒng)fsync緩慢,將會導致Redis主線程阻塞影響效率。

到此這篇關于一文詳解Redis中的持久化的文章就介紹到這了,更多相關Redis持久化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于redis實現(xiàn)世界杯排行榜功能項目實戰(zhàn)

    基于redis實現(xiàn)世界杯排行榜功能項目實戰(zhàn)

    前段時間,做了一個世界杯競猜積分排行榜。對世界杯64場球賽勝負平進行猜測,猜對+1分,錯誤+0分,一人一場只能猜一次。下面通過本文給大家分享基于redis實現(xiàn)世界杯排行榜功能項目實戰(zhàn),感興趣的朋友一起看看吧
    2018-10-10
  • RedisTemplate的使用與注意事項小結(jié)

    RedisTemplate的使用與注意事項小結(jié)

    本文詳細介紹了RedisTemplate的用途和使用方法,RedisTemplate是Spring提供的一個工具類,用于操作Redis數(shù)據(jù)庫,其API提供了豐富的方法來實現(xiàn)對Redis各種操作,本文就來詳細的介紹一下,感興趣的可以來了解一下
    2024-10-10
  • redis 替代php文件存儲session的實例

    redis 替代php文件存儲session的實例

    這篇文章主要介紹了redis 替代php文件存儲session的實例的相關資料,希望通過本文能幫助到大家,讓大家掌握這樣的方法,需要的朋友可以參考下
    2017-10-10
  • Redis5之后版本的高可用集群搭建的實現(xiàn)

    Redis5之后版本的高可用集群搭建的實現(xiàn)

    這篇文章主要介紹了Redis5之后版本的高可用集群搭建的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Redis之sql緩存的具體使用

    Redis之sql緩存的具體使用

    本文主要介紹了Redis之sql緩存的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Redis高并發(fā)超賣問題解決方案圖文詳解

    Redis高并發(fā)超賣問題解決方案圖文詳解

    Redis是一種基于內(nèi)存的數(shù)據(jù)存儲系統(tǒng),被廣泛用于解決高并發(fā)問題,下面這篇文章主要給大家介紹了關于Redis高并發(fā)超賣問題解決方案的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-02-02
  • 高并發(fā)技巧之Redis和本地緩存使用技巧分享

    高并發(fā)技巧之Redis和本地緩存使用技巧分享

    在這篇文章中,我主要介紹的是分布式緩存和本地緩存的使用技巧,包括緩存種類介紹,各種的使用場景,以及如何使用,最后再給出實戰(zhàn)案例,需要的可以參考一下
    2022-10-10
  • Redis 事務與過期時間詳細介紹

    Redis 事務與過期時間詳細介紹

    這篇文章主要介紹了Redis 事務與過期時間詳細介紹的相關資料,需要的朋友可以參考下
    2017-05-05
  • Redis中?HyperLogLog數(shù)據(jù)類型使用小結(jié)

    Redis中?HyperLogLog數(shù)據(jù)類型使用小結(jié)

    Redis使用HyperLogLog的主要作用是在大數(shù)據(jù)流(view,IP,城市)的情況下進行去重計數(shù),這篇文章主要介紹了Redis中?HyperLogLog數(shù)據(jù)類型使用總結(jié),需要的朋友可以參考下
    2023-03-03
  • dubbo服務使用redis注冊中心的系列異常解決

    dubbo服務使用redis注冊中心的系列異常解決

    這篇文章主要為大家介紹了dubbo服務在使用redis注冊中心遇到的一系列異常的解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03

最新評論