一、持久化
所謂的持久化就是把內存中的數據寫到磁盤中去,防止服務宕機后內存數據丟失。Redis4.0之前提供了兩種持久化方式:RDB(默認) 和AOF,Redis4.x之后新增了一種混合持久化(本文所用的Redis版本是redis‐5.0.2)
1、RDB
RDB是Redis Database縮寫,在默認情況下,Redis將內存數據庫快照保存在名字為dump.rdb的二進制文件中。可以對Redis進行設置,讓它在“ N秒內至少有M個鍵值改動”這一條件被滿足時,自動保存一次數據。比如下圖,900秒內有1個鍵值或者300秒內有10個鍵值或者60秒內有10000個鍵值改動,自動保存一次數據;關閉RDB只需要將所有的save保存策略注釋掉即可。
還可以手動執行命令生成RDB快照,進入Redis客戶端執行命令save或bgsave可以生成dump.rdb文件,每次命令執行都會將所有Redis內存快照到一個新的rdb文件里,並覆蓋原有rdb快照文件。save是同步命令,bgsave是異步命令,bgsave會從redis主進程fork(fork()是linux函數)出一個子進程專門用來生成rdb快照文件。Redis配置自動生成rdb文件后台使用的是bgsave方式。
命令 | save | bgsave |
IO類型 | 同步 | 異步 |
是否阻塞redis其它命令 | 是 | 否(在生成子進程執行調用fork函數時會短暫阻塞) |
復雜度 | O(n) | O(n) |
優點 | 不會消耗額外內存 | 不阻塞客戶端命令 |
缺點 | 阻塞客戶端命令 | 需要fork子進程,消耗內存 |
2、AOF
AOF是append-only file縮寫,RDB快照並不是非常耐久(durable):如果Redis因為某些原因而造成故障停機,那么服務器將丟失最近寫入、且仍未保存到快照中的那些數據。從Redis1.1版本開始,Redis增加了一種完全耐久的持久化方式:AOF持久化。可以通過修改如下配置文件來打開AOF功能:
修改了配置文件,先執行bin/redis-cli shutdown停止Redis,然后執行bin/redis-server redis.conf啟動Redis,此時appendonly生效;從現在開始, 每當Redis執行一個改變鍵值的命令時(比如 SET),這個命令就會被追加到AOF文件的末尾。這樣的話,當 Redis重新啟動時,程序就可以通過重新執行AOF文件中的命令來達到重建數據的目的。你可以配置 Redis 多久才將數據 fsync到磁盤一次。
① appendfsync always:每次有新命令追加到AOF文件時就執行一次fsync,非常慢,也非常安全。
② appendfsync everysec:每秒fsync一次,足夠快(和使用 RDB 持久化差不多),並且在故障時只會丟失 1 秒鍾的數據。
③ appendfsync no:從不 fsync,將數據交給操作系統來處理。更快,也更不安全的選擇。
推薦(並且也是默認)的措施為每秒fsync一次,這種fsync策略可以兼顧速度和安全性。配置文件如下:
執行如下命令:
(1)啟動客戶端,連接Redis bin/redis-cli 並執行set toby xu
(2) 到dir(redis.conf這個配置文件里面的數據持久化的目錄屬性)所在的目錄下查看,如下圖:
(3)vim appendonly.aof,文件的內容在后面的RESP(Redis序列化協議)中詳解講解,Redis序列化協議官網地址:https://redis.io/topics/protocol
AOF重寫:
(1)AOF文件里可能有太多沒用指令,所以AOF會定期根據內存的最新數據生成新的aof文件,當然可以手工執行bgrewriteaof命令也能重寫AOF,比如執行如下命令:
(2)重寫后AOF文件里變成:
如下兩個配置可以控制AOF自動重寫頻率:
① auto-aof-rewrite-min-size 64mb :aof文件至少要達到64M才會自動重寫。
② auto-aof-rewrite-percentage 100 :aof文件自上一次重寫后文件大小增長了100%則再次觸發重寫。
當然AOF還可以手動重寫,進入redis客戶端執行如上圖命令bgrewriteaof重寫AOF注意,AOF重寫Redis會fork出一個子進程去做,不會對Redis正常命令處理有太多影響。
3、RDB和AOF對比
Redis啟動時如果既有RDB文件又有AOF文件則優先選擇AOF文件恢復數據,因為AOF一般來說數據更全一點。
持久化方式 | RDB | AOF |
啟動優先級 | 低 | 高 |
文件大小 | 小 | 大 |
恢復速度 | 快 | 慢 |
數據安全性 | 容易丟數據 | 根據策略決定 |
4、Redis4.0混合持久化
重啟Redis時,我們很少使用 RDB來恢復內存狀態,因為會丟失大量數據。我們通常使用AOF日志重放,但是重放AOF日志性能相對RDB來說要慢很多,這樣在 Redis 實例很大的情況下,啟動需要花費很長的時間。 Redis4.0為了解決這個問題,帶來了一個新的持久化選項——混合持久化。配置如下:
如果開啟了混合持久化,AOF在重寫時,不再是單純將內存數據轉換為RESP命令寫入AOF文件,而是將重寫這一刻之前的內存做RDB快照處理,並且將RDB快照內容和增量的AOF修改內存數據的命令存在一起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會進行改名,原子的覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換。於是在Redis重啟的時候,可以先加載RDB的內容,然后再重放增量AOF文件就可以完全替代之前的AOF全量文件重放,因此重啟效率大幅得到提升。
二、Redis主從
1、主從復制概念
主從復制,是指將一台Redis服務器的數據,復制到其他的Redis服務器。前者稱為主節點(master),后者稱為從節點(slave),數據的復制是單向的,只能由主節點到從節點。
2、主從復制的原理
(1)全量復制
將主節點中的所有數據都發送給從節點,是一個非常重型的操作,當數據量較大時,會對主從節點和網絡造成很大的開銷。全量復制流程圖如下:
① slave會發出一個同步命令,剛開始是Psync命令,表示要求master主機同步數據
② master收到psync命令后,會通過執行bgsave生成最新的RDB快照文件,持久化期間,master會繼續接收客戶端的請求,它會把寫請求緩存在內存中
③ 發送RDB文件給slave
④ master再將之前緩存在內存中的命令發送給slave
⑤ 刷新舊的數據。slave在載入主節點的數據之前要先將老數據清除
⑥ 加載RDB文件將數據庫狀態更新至主節點執行bgsave時的數據庫狀態和緩沖區數據的加載
⑦ master同步長連接持續把寫命令發送給slave,以保證數據的一致
(2)部分復制
部分復制是Redis 2.8以后出現的,用於處理在主從復制中因網絡閃斷等原因造成的數據丟失場景,當slave再次連上master后,如果條件允許,master會補發丟失數據給slave。因為補發的數據遠遠小於全量數據,可以有效避免全量復制的過高開銷。部分復制流程圖如下:
① 如果網絡抖動(連接斷開 connection lost)
② master還是會寫repl_back_buffer(復制緩沖區)
③ slave會繼續嘗試連接主機
④ slave會把自己當前run_id和偏移量傳輸給master,並且執行pysnc命令同步
⑤ slave發送過來的offset在repl_back_buffer中,則master會將緩存中從offset以后的數據一次性同步給slave,否則全量復制
⑥ master同步長連接持續把寫命令發送給slave,以保證數據的一致
3、主從搭建
其中slave的主要配置如下:
port 6380 pidfile /var/run/redis_6380.pid dir /usr/local/redis-5.0.2/6380 replicaof 192.168.160.146 6379 replica-serve-stale-data yes replica-read-only yes
(1)在6379 set toby xu
(2)在6380 keys *
至此Redis主從搭建完成!!!!!