六、Redis事務及其持久化
redis持久化
redis的持久化有兩種,一種rdb一種是aof
Rdb
Rdb持久化Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。整個過程中,主程序是不進行任何IO操作的。這就確保了極高的效能。如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
RDB的缺點是最後一次持久化後的資料可能丟失。我們預設的就是RDB,一般情況下不需要修改這個配置!有時候在生產環境我們會將這個檔案進行備份!rdb儲存的檔案是dump.rdb 都是在我們的配置檔案中快照中進行配置的!
觸發機制
1、save的規則滿足的情況下,會自動觸發rdb規則
2、執行 flflushall 命令,也會觸發我們的rdb規則!
3、退出redis,也會產生 rdb 檔案!
備份就自動生成一個 dump.rdb
恢復rdb檔案!
1、只需要將rdb檔案放在我們redis啟動目錄就可以,redis啟動的時候會自動檢查dump.rdb 恢復其中的資料!
優缺點
優點:
1、適合大規模的資料恢復! 2、對資料的完整性要不高!
缺點:
1、需要一定的時間間隔程序操作!如果redis意外宕機了,這個最後一次修改資料就沒有的了!2、fork程序的時候,會佔用一定的內容空間
AOF
以日誌的形式來記錄每個寫操作,將Redis執行過的所有指令記錄下來(讀操作不記錄),只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,換言之,redis重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作.
預設是不開啟的,我們需要手動進行配置!我們只需要將 appendonly 改為yes就開啟了 aof!重啟,redis 就可以生效了!如果這個 aof 檔案有錯位,這時候 redis 是啟動不起來的嗎,我們需要修復這個aof檔案redis 給我們提供了一個工具 redis-check-aof --fix ;
配置檔案說明:
appendonly no # 預設是不開啟aof模式的,預設是使用rdb方式持久化的,在大部分所有的情況下, rdb完全夠用! appendfilename "appendonly.aof" # 持久化的檔案的名字 appendfsync always # 每次修改都會 sync。消耗效能 appendfsync everysec # 每秒執行一次 sync,可能會丟失這1s的資料! appendfsync no # 不執行 sync,這個時候作業系統自己同步資料,速度最快! rewrite 重寫
優點:
1、每一次修改都同步,檔案的完整會更加好!
2、每秒同步一次,可能會丟失一秒的資料
3、從不同步,效率最高的!
缺點:
1、相對於資料檔案來說,aof遠遠大於 rdb,修復的速度也比 rdb慢!
2、Aof 執行效率也要比 rdb 慢,所以我們redis預設的配置就是rdb持久化!
擴充套件
1、RDB 持久化方式能夠在指定的時間間隔內對你的資料進行快照儲存
2、AOF 持久化方式記錄每次對伺服器寫的操作,當伺服器重啟的時候會重新執行這些命令來恢復原始
的資料,AOF命令以Redis 協議追加儲存每次寫的操作到檔案末尾,Redis還能對AOF檔案進行後臺重
寫,使得AOF檔案的體積不至於過大。
3、只做快取,如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化
4、同時開啟兩種持久化方式
在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF
檔案儲存的資料集要比RDB檔案儲存的資料集要完整。
RDB 的資料不實時,同時使用兩者時伺服器重啟也只會找AOF檔案,那要不要只使用AOF呢?作者
建議不要,因為RDB更適合用於備份資料庫(AOF在不斷變化不好備份),快速重啟,而且不會有
AOF可能潛在的Bug,留著作為一個萬一的手段。
5、效能建議
因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠
了,只保留 save 900 1 這條規則。
如果Enable AOF ,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自
己的AOF檔案就可以了,代價一是帶來了持續的IO,二是AOF rewrite 的最後將 rewrite 過程中產
生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。只要硬碟許可,應該儘量減少AOF rewrite
的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上,預設超過原大小100%大小重
寫可以改到適當的數值。
如果不Enable AOF ,僅靠 Master-Slave Repllcation 實現高可用性也可以,能省掉一大筆IO,也
減少了rewrite時帶來的系統波動。代價是如果Master/Slave 同時倒掉,會丟失十幾分鐘的資料,
啟動指令碼也要比較兩個 Master/Slave 中的 RDB檔案,載入較新的那個,微博就是這種架構。
redis事務
Redis事務不同於其他資料庫的事務,他是一種弱事務,它的用法很簡單,不需要記太多的事務隔離級別和事務的傳播性,這就要求我們不能把redis事務當作一個正常的事務去操作。
multi(開啟事務)、exec(執行事務)、discard(回滾事務)
示例用法
set name zhangsan
# 開啟事務
multi
set name lisi
set name wangwu
# 提交事務
exec
1234567
redis的事務具備原子性麼?
set name zhangsan
multi
set name lisi
# 原子性的事務將會回滾
incr name #錯誤的命令
exec
# 如果具備原子性,則name還是之前的值,如果不是則說明事務沒有進行回滾,不具備原子性。
get name
12345678
※:redis的事務只滿足事務的隔離型,不保證原子性
watch指令
watch指令一般都是搭配multi一起使用的,用來監控一個變數在事務執行過程中,是否被外界修改了,如果修改的話,exec將會執行失敗,watch要在事務開啟之前執行
watch name
multi
exec
redis為什麼不支援原子性(回滾)
只有當被呼叫的Redis命令有語法錯誤時,這條命令才會執行失敗(在將這個命令放入事務佇列期間,Redis能夠發現此類問題),或者對某個鍵執行不符合其資料型別的操作:實際上,這就意味著只有程式錯誤才會導致Redis命令執行失敗,這種錯誤很有可能在程式開發期間發現,一般很少在生產環境發現。
Redis已經在系統內部進行功能簡化,這樣可以確保更快的執行速度,因為Redis不需要事務回滾的能力