上一篇部落格我們聊了下redis的rdb持久化、安全連線、資源限制相關配置;回顧請參考:https://www.cnblogs.com/qiuhom-1874/p/13394411.html;今天我們來聊一聊redis主從複製、aof持久化、叢集、慢日誌相關配置;
REPLICATION 相關配置
slaveof <masterip> <masterport>:該指令用於指定redis主從複製中的master的ip地址和埠;
示例:
提示:redis預設工作在master模式,配置了這個指令以後,redis預設會從master自動降級為slave角色;
提示:以上配置表示讓本機redis從屬於192.168.0.41 ;也就是說192.168.0.41是master,本節點為slave;
masterauth <master-password>:該指令用於指定連線master的密碼
示例:
提示:以上配置表示指定連線master認證密碼為admin123.com;這個密碼是我們在master上設定的requirepass 指令後面的密碼;通常建議一個叢集中的redis密碼和版本都弄成相同的;
驗證:重啟redis,連線redis看看是否自動降級為slave?
檢視同步日誌
主節點日誌
從節點日誌
提示:從上面的日誌資訊可以瞭解到,redis的主從複製主要經歷了這幾個操作,第一slave連線master,併傳送sync命令;第二是master接收到slave的sync命令後,開始執行bgsave命令生成rdb快照檔案,並使用緩衝區記錄此後執行的所有命令;第三master執行完bgsave後,向所有的slave傳送快照,並在傳送期間繼續記錄被執行寫操作的命令;第四是slave接收到master的快照後,slave會丟棄之前存在的所有舊資料,然後將接收到的快照檔案載入到記憶體;第五master傳送完快照檔案後,開始向slave傳送緩衝區接收到寫操作命令;第六slave完成master傳送過來的快照檔案載入到記憶體後,開始接收master傳送過來的緩衝區寫操作命令,然後將這些命令在slave上執行;第七後期的同步操作,slave會傳送自己的slave_repl_offset位置給master,master會根據從伺服器傳送過來的slave_repl_offset位置,把這之後的資料以rdb快照的方式傳送給從伺服器;
驗證:檢視slave中的資料是否和master中的資料一樣?
提示:從上面的結果看,master和salve都是空的,沒有資料
驗證:在master上寫入資料,看看slave上是否能夠及時的同步過來?
提示:可以看到在主伺服器上執行寫操作,是能夠及時的同步到從節點;
slave/replica-serve-stale-data:該指令用於指定當主從複製失去連線,或者主從節點正在同步資料,是否從從節點響應客戶端的讀請求,預設是yes表示從庫會繼續響應客戶端的讀請求;如果設定的no,除去指定點命令之外的任何請求都會返回一個錯誤“sync with master in progress”
示例:設定slave-serve-stale-data為no 重啟redis ,然後將主庫當機,在從庫執行讀操作,看看是否可以讀?
重啟redis,在從庫上執行讀操作
提示:在主庫正常的情況下,從庫可以正常的執行讀操作。
把主庫當機,看看從庫是否還可以執行讀操作?
提示:當主庫當機時,從庫上執行讀操作就報錯了;
slave/replica-read-only:該指令用於指定從庫是否可以讀;預設是從庫只讀,不可寫;
repl-diskless-sync:該指令用於指定否使用socket方式複製資料;redis同步資料的方式有兩種,一種是socket方式,所謂socker方式複製資料是指在複製資料是master在做快照時,不將快照存入磁碟,直接將rdb檔案通過socket方式傳送給從節點;這種方式如果是在多個從節點上同步資料,它是序列復制,也就是說第一個slave同步完成後,再同步第二個slave;disk是指主節點將rdb儲存到磁碟,然後在傳送給從節點;disk方式同步資料在多個slave情景中,它可以共享rdb檔案,主節點不用重複生成多個相同的rdb傳送給slave;通常情況只有在磁碟速度緩慢但是網路相對較快的情況下才使用 socket 方式,否則都是用disk方式;
repl-diskless-sync-delay:該指令用於指定disk方式同步資料的延遲時間,單位秒;設定為0 表示關閉延遲,關閉延遲則意味著一旦有同步請求,在同步開始到結束前,master不會再接收新的slave的同步請求,直到本次同步完成;
repl-ping-slave-period:該指令用於指定slave根據master指定的時間進行週期性的 PING 監測,單位秒;
repl-timeout:該指令用於指定複製連結超時時間,單位秒;通常這個超時時間要大於上面的repl-ping-slave-period指令指定的時間,否則會經常報同步連線超時;
repl-disable-tcp-nodelay:該指令用於指定socket模式下是否在slave套接字傳送sync之後禁用TCP-NODELAY,如果該指令的值為yes,則表示禁用TCP-NODELAY,這樣設定後,redis會使用更少的TCP包和頻寬向slave傳送資料;但是這將使資料傳輸到 slave上有延遲,Linux 核心的預設配置會達到 40 毫秒;如果該指令的值為no,資料傳輸到 salve 的延遲將會減少但要使用更多的頻寬;
repl-backlog-size:該指令用於指定複製緩衝區大小,只有在 slave 連線之後才分配記憶體,預設是1MB;
repl-backlog-ttl:該指令用於指定多少時間master沒有slave連線,master就情況backlog緩衝區;預設是3600秒;
replica-priority:該指令用於指定當master不可用時,sentinel會根據slave的優先順序選舉一個新master,最低的優先順序的 slave,當選 master。而配置成 0,永遠不會被選舉。該選項預設是100
min-slaves-to-write:該指令用於指定最少slave數量,如果啟用這個選項,master檢測從服務的數量小於我們指定數量,將拒絕寫請求;
示例:
提示:在slave小於我們指定的最小slave數量時,master上執行寫操作命令就提示我們沒有足夠的slave節點;
min-slaves-max-lag:該指令用於指定slave的最大延遲時間;如果slave的延遲時間超出我們指定的時間,master就拒絕寫操作;
示例
提示:可以看到延遲時間小於我們指定的時間,主伺服器上可以正常執行寫操作;通常用min-slaves-max-lag和min-slaves-to-write這兩個選項來防止主庫不安全時主庫寫操作的命令執行;這兩個選項一起使用只要有一個不滿足條件,主庫將拒絕寫操作;
slave/replica-announce-ip:該指令用於指定當在埠轉發或NAT網路環境中,slave有多個ip地址,可以使用該選項指定slave的ip地址;
slave/replica-announce-port:該指令用於指定當在埠轉發或NAT網路環境中,指定slave的埠;
APPEND ONLY MODE相關配置
appendonly:該指令 用於指定是否開啟AOF日誌記錄,預設是no不開啟; 預設 redis 使用的是 rdb 方式持久化,這種方式如果redis在做完快照後突然當機,會導致做快照期間寫的資料丟失(因為做快照期間的資料還在記憶體);AOF持久化是Redis 會把每次寫入的資料在接收後都寫入 appendonly.aof 檔案(有點類似mysql中的binlog),每次啟動時 Redis 都會先把這個檔案的資料讀入記憶體裡,先忽略 RDB 檔案(優先順序高於RDB)。
appendfilename:該指令用於指定AOF檔名稱,預設是appendonly.aof;該檔案儲存在 dir 指令指定的目錄下,同rdb檔案在同一個目錄下;
示例:
提示:以上配置表示開啟AOF日誌持久化,並保持為appendonly.aof
驗證:重啟redis服務,看看對應目錄是否有對應的aof檔案生成?
連線redis,執行寫操作命令,看看appendonly.aof中是否記錄?
[root@node1 ~]# redis-cli -a admin123.com 127.0.0.1:6379> KEYS * (empty list or set) 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> quit [root@node1 ~]# file /var/lib/redis/appendonly.aof /var/lib/redis/appendonly.aof: ASCII text, with CRLF line terminators [root@node1 ~]# cat /var/lib/redis/appendonly.aof *2 $6 SELECT $1 0 *3 $3 set $2 k1 $2 v1 *3 $3 set $2 k2 $2 v2 [root@node1 ~]#
提示:可以看到AOF是一個文字檔案,從AOF檔案中可以清晰看到我們執行的set命令;
appendfsync:該指令用於指定AOF持久化策略的配置;no表示不自信fsync,有作業系統同步資料到磁碟,always表示每次寫入都執行fsync,以保證資料同步到磁碟,everysec表示每秒執行一次fsync同步資料到磁碟;預設是everysec;
no-appendfsync-on-rewrite:該指令用於指定在 aof rewrite 期間,是否對 aof 新記錄的 append 暫緩使用檔案同步策略,主要考慮磁碟 IO 開支和請求阻塞時間。預設為 no,表示"不暫緩",新的 aof 記錄仍然會被立即同步,Linux 的預設 fsync 策略是 30 秒,如果為 yes 可能丟失 30 秒資料,但由於 yes 效能較好而且會避免出現阻塞因此比較推薦。
auto-aof-rewrite-percentage:該指令用於指定當 AOF log 增長超過指定百分比例時,重寫 log file, 設定為 0 表示不自動重寫 Aof 日誌,重寫是為了使 aof 體積保持最小,而確保儲存最完整的資料。
auto-aof-rewrite-min-size:該指令用於指定觸發AOF重寫的最小檔案大小;
aof-load-truncated:該指令用於指定是否載入由於其他原因導致的末尾異常的 AOF 檔案;比如主程式被 kill/斷電等原因造成的AOF檔案異常;預設是yes表示載入;
aof-use-rdb-preamble:redis4.0 新增 RDB-AOF 混合持久化格式,在開啟了這個功能之後,AOF 重寫產生的檔案將同時包含 RDB 格式的內容和 AOF 格式的內容,其中 RDB 格式的內容用於記錄已有的資料,而 AOF 格式的記憶體則用於記錄最近發生了變化的資料,這樣 Redis 就可以同時兼有 RDB 持久化和AOF 持久化的優點(既能夠快速地生成重寫檔案,也能夠在出現問題時,快速地載入資料)。
LUA SCRIPTING相關配置
lua-time-limit:該指令用於指定lua指令碼的最大執行時間,單位是毫秒;預設是5000毫秒;
REDIS CLUSTER相關配置
cluster-enabled:該指令用於指定是否開啟叢集模式,預設是單機模式;
cluster-config-file:該指令用於指定由 node 節點自動生成的叢集配置檔案;
cluster-node-timeout:該指令用於指定叢集中 node 節點連線超時時間;
cluster-replica-validity-factor:該指令用於指定叢集有效因子,這個選項的值×cluster-node-timeout選項的值就等於節點當選master的有效時間;在執行故障轉移的時候可能有些節點和 master 斷開一段時間資料比較舊,這些節點就不適用於選舉為 master,超過這個時間的就不會被進行故障轉移;
cluster-migration-barrier:該指令用於指定一個主節點擁有的至少正常工作的從節點,即如果主節點的 slave 節點故障後會將多餘的從節點分配到當前主節點成為其新的從節點。預設是1;
cluster-require-full-coverage:該指令用於指定叢集槽位不全時,是否不再對外提供服務;當叢集槽位覆蓋,如果一個主庫當機且沒有備庫就會出現叢集槽位不全,那麼 yes 情況下 redis 叢集槽位驗證不全就不再對外提供服務,而 no 則可以繼續使用但是會出現查詢資料查不到的情況(因為有資料丟失)。
SLOW LOG 相關配置
slowlog-log-slower-than:該指令用於指定大於多少時間的命令執行時間為慢日誌;單位微妙;該指令值為負數表示禁用慢日誌,為 0 會記錄每個命令操作。
slowlog-max-len:該指令用於指定慢日誌佇列長度,超出該佇列長度會覆蓋最早的記錄,以此滾動刪除;
示例
提示:以上配置表示記錄每個命令的操作為慢日誌中,慢日誌的最大佇列長度為10;
驗證:重啟redis,連線redis執行命令,看看是否都將執行的命令都記錄為慢日誌中?
[root@node1 ~]# systemctl restart redis [root@node1 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 511 192.168.0.41:6379 *:* LISTEN 0 511 127.0.0.1:6379 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node1 ~]# redis-cli -a admin123.com 127.0.0.1:6379> KEYS * 1) "k2" 2) "k1" 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> set k3 v3 OK 127.0.0.1:6379> SLOWLOG len (integer) 10 127.0.0.1:6379> SLOWLOG get 1) 1) (integer) 78 2) (integer) 1596294355 3) (integer) 2 4) 1) "REPLCONF" 2) "ACK" 3) "137" 2) 1) (integer) 77 2) (integer) 1596294354 3) (integer) 2 4) 1) "REPLCONF" 2) "ACK" 3) "137" 3) 1) (integer) 76 2) (integer) 1596294353 3) (integer) 3 4) 1) "REPLCONF" 2) "ACK" 3) "137" 4) 1) (integer) 75 2) (integer) 1596294352 3) (integer) 88 4) 1) "REPLCONF" 2) "ACK" 3) "137" 5) 1) (integer) 74 2) (integer) 1596294351 3) (integer) 3 4) 1) "REPLCONF" 2) "ACK" 3) "137" 6) 1) (integer) 73 2) (integer) 1596294350 3) (integer) 2 4) 1) "REPLCONF" 2) "ACK" 3) "137" 7) 1) (integer) 72 2) (integer) 1596294349 3) (integer) 3 4) 1) "REPLCONF" 2) "ACK" 3) "137" 8) 1) (integer) 71 2) (integer) 1596294348 3) (integer) 2 4) 1) "REPLCONF" 2) "ACK" 3) "137" 9) 1) (integer) 70 2) (integer) 1596294347 3) (integer) 3 4) 1) "REPLCONF" 2) "ACK" 3) "137" 10) 1) (integer) 69 2) (integer) 1596294346 3) (integer) 3 4) 1) "REPLCONF" 2) "ACK" 3) "123" 127.0.0.1:6379>
提示:從上面的日誌可以看到慢日誌的對了長度只有10,但是我們執行的命令沒有在裡面看到,原因是我們開啟了主從複製,後臺一直在執行REPLCONF ACK命令,把我們執行的命令給覆蓋了;
驗證:關閉主從複製,連線redis,再執行命令,看看是否記錄我們執行的命令?
[root@node1 ~]# systemctl restart redis [root@node1 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 511 192.168.0.41:6379 *:* LISTEN 0 511 127.0.0.1:6379 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::* [root@node1 ~]# redis-cli -a admin123.com 127.0.0.1:6379> KEYS * 1) "k1" 2) "k3" 3) "k5" 4) "k2" 5) "k4" 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> del k3 (integer) 1 127.0.0.1:6379> del k4 (integer) 1 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> SLOWLOG len (integer) 8 127.0.0.1:6379> SLOWLOG get 3 1) 1) (integer) 8 2) (integer) 1596295476 3) (integer) 4 4) 1) "SLOWLOG" 2) "len" 2) 1) (integer) 7 2) (integer) 1596295454 3) (integer) 52 4) 1) "info" 2) "replication" 3) 1) (integer) 6 2) (integer) 1596295447 3) (integer) 10 4) 1) "del" 2) "k4" 127.0.0.1:6379> SLOWLOG get 1) 1) (integer) 9 2) (integer) 1596295482 3) (integer) 48 4) 1) "SLOWLOG" 2) "get" 3) "3" 2) 1) (integer) 8 2) (integer) 1596295476 3) (integer) 4 4) 1) "SLOWLOG" 2) "len" 3) 1) (integer) 7 2) (integer) 1596295454 3) (integer) 52 4) 1) "info" 2) "replication" 4) 1) (integer) 6 2) (integer) 1596295447 3) (integer) 10 4) 1) "del" 2) "k4" 5) 1) (integer) 5 2) (integer) 1596295442 3) (integer) 8 4) 1) "del" 2) "k3" 6) 1) (integer) 4 2) (integer) 1596295439 3) (integer) 7 4) 1) "get" 2) "k2" 7) 1) (integer) 3 2) (integer) 1596295437 3) (integer) 7 4) 1) "get" 2) "k1" 8) 1) (integer) 2 2) (integer) 1596295412 3) (integer) 31 4) 1) "KEYS" 2) "*" 9) 1) (integer) 1 2) (integer) 1596295408 3) (integer) 1410 4) 1) "COMMAND" 10) 1) (integer) 0 2) (integer) 1596295408 3) (integer) 4 4) 1) "AUTH" 2) "admin123.com" 127.0.0.1:6379>
提示:可以看到關閉主從複製以後,重啟master後,再連線redis執行命令,在慢日誌中就可以清楚看到我們執行的命令;slowlog len命令用於獲取當前slowlog的對列長度;slowlog get命令用於獲取指定個數的慢日誌,如果沒有指定慢日誌條目數表示獲取當前佇列所有日誌;