0121. Best Time to Buy and Sell Stock (E)
阿新 • • 發佈:2020-09-18
redis主從複製
1 在開啟主從賦值的時候,使用的是RDB的方式同步主從資料的
2 同步開始之後,通過主庫命令傳播的方式,主動複製的方式實現
3 2.8版本以後實現了psync的機制實現斷線重連
使用非同步複製。
一個主伺服器可以有多個從伺服器。
從伺服器也可以有自己的從伺服器。
複製功能不會阻塞主伺服器。
可以通過複製功能來讓主伺服器免於執行持久化操作,由從伺服器去執行持久化操作即可。
redis主從複製原理
1. 從伺服器向主伺服器傳送 SYNC 命令。 2. 接到 SYNC 命令的主伺服器會呼叫BGSAVE 命令,建立一個 RDB 檔案,並使用緩衝區記錄接下來執行的所有寫命令。也就是儲存快照,然後記錄到快取,從庫不需要請求,只需要接收就可以了。 3. 當主伺服器執行完 BGSAVE 命令時,它會向從伺服器傳送 RDB 檔案,而從伺服器則會接收並載入這個檔案。 4. 主伺服器將緩衝區儲存的所有寫命令傳送給從伺服器執行。
從伺服器每秒一次的頻率,ping 主伺服器一次,並報告複製流的處理情況
主伺服器會記錄各個從伺服器最後一次向他傳送ping的時間
使用者可以通過配置,指定網路延遲的最大值 min-slaves-max-lag
以及執行寫操作所需的至少從伺服器數量 min-slaves-to-write
如果至少有min-slaves-to-write個伺服器,並且這些伺服器延遲值都少於min-slaves-max-lag秒
那麼主伺服器就會執行客戶端的寫操作
redis主從會有一個斷線重連的機制,當主從斷開後,主會保留沒有傳送的資料,當從伺服器好了他會將沒有傳輸的資料傳輸過去。
主伺服器只在有至少 N 個從伺服器的情況下,才執行寫操作 從 Redis 2.8 開始, 為了保證資料的安全性, 可以通過配置, 讓主伺服器只在有至少 N 個當前已連線從伺服器的情況下, 才執行寫命令。 不過, 因為 Redis 使用非同步複製, 所以主伺服器傳送的寫資料並不一定會被從伺服器接收到, 因此, 資料丟失的可能性仍然是存在的。 通過以下兩個引數保證資料的安全: min-slaves-to-write <number of slaves> #至少有 N 臺從庫與主庫完成同步了則認為主從同步成功 min-slaves-max-lag <number of seconds> #網路延時的最大值,如果大於這個值,認為不成功的
redis主從複製配置[一主兩從]
注意: redis沒有做資料持久化的時候不要做主從複製,因為一旦主庫宕機了,資料都沒了,然後通過主從複製將從庫資料也重寫了,這樣會導致重大事故
環境:
主節點:6380
從節點:6381 6382
mkdir /nosql/638{0..2} vim /nosql/6380/redis.conf port 6380 daemonize yes pidfile /nosql/6380/redis.pid loglevel notice logfile "/nosql/6380/redis.log" dbfilename dump.rdb dir /nosql/6380 protected-mode no vim /nosql/6381/redis.conf port 6381 daemonize yes pidfile /nosql/6381/redis.pid loglevel notice logfile "/nosql/6381/redis.log" dbfilename dump.rdb dir /nosql/6381 protected-mode no vim /nosql/6382/redis.conf port 6382 daemonize yes pidfile /nosql/6382/redis.pid loglevel notice logfile "/nosql/6382/redis.log" dbfilename dump.rdb dir /nosql/6382 protected-mode no 啟動: redis-server /nosql/6380/redis.conf redis-server /nosql/6381/redis.conf redis-server /nosql/6382/redis.conf 檢查: [root@k8s-master1 redis]# ps -ef|grep redis root 54840 1 0 19:34 ? 00:00:00 redis-server *:6380 root 54844 1 0 19:34 ? 00:00:00 redis-server *:6381 root 54848 1 0 19:34 ? 00:00:00 redis-server *:6382
開啟主從
6381/6382命令列:
[root@k8s-master1 redis]# redis-cli -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6380 #從哪個機器哪個埠進行復制
OK
127.0.0.1:6381> exit
[root@k8s-master1 redis]# redis-cli -p 6382
127.0.0.1:6382> SLAVEOF 127.0.0.1 6380 #從哪個機器哪個埠進行復制
OK
127.0.0.1:6382> exit
#查詢主從狀態:
主狀態:
[root@k8s-master1 redis]# redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:2 #可以看到從庫數量 下面可以看到從庫相應狀態資訊
slave0:ip=127.0.0.1,port=6381,state=online,offset=169,lag=1
slave1:ip=127.0.0.1,port=6382,state=online,offset=169,lag=1
master_repl_offset:169
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:168
從狀態:
[root@k8s-master1 redis]# redis-cli -p 6381
127.0.0.1:6381> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:113
slave_priority:100
slave_read_only:1 #從庫預設不可以被寫入操作
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:6381> exit
------------------------------------------------------------------------
[root@k8s-master1 redis]# redis-cli -p 6382
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:141
slave_priority:100
slave_read_only:1 #從庫預設不可以被寫入操作
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:6382> exit
測試主庫down了從庫替換
#主動停止主庫
[root@k8s-master1 redis]# redis-cli -p 6380
127.0.0.1:6380> shutdown
not connected> exit
#檢查從庫狀態
[root@k8s-master1 redis]# redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down #可以檢測到master主庫down了
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:701
master_link_down_since_seconds:35
slave_priority:100
slave_read_only:1
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
現在需要用 6381從庫來替代6380主庫,配置如下:
[root@k8s-master1 redis]# redis-cli -p 6381 #選擇一個從庫連線
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:701
master_link_down_since_seconds:35
slave_priority:100
slave_read_only:1
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:6381> SLAVEOF no one
OK
從6382檢視狀態:
[root@k8s-master1 redis]# redis-cli -p 6382
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:701
master_link_down_since_seconds:307
slave_priority:100
slave_read_only:1
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
可以看到它還在連6380,現在需要把他改為連線到新的主庫 6381:
127.0.0.1:6382> SLAVEOF no one
OK
127.0.0.1:6382> SLAVEOF 127.0.0.1 6381
OK
redis 哨兵模式
將原有實驗切換回來:
[root@k8s-master1 redis]# redis-server /nosql/6381/redis.conf
[root@k8s-master1 redis]# redis-cli -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK
127.0.0.1:6381> exit
[root@k8s-master1 redis]# redis-server /nosql/6382/redis.conf
[root@k8s-master1 redis]# redis-cli -p 6382
127.0.0.1:6382> SLAVEOF 127.0.0.1 6380
OK
127.0.0.1:6382> exit
主庫:
[root@k8s-master1 redis]# redis-cli -p 6380
127.0.0.1:6380> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=127,lag=0
slave1:ip=127.0.0.1,port=6382,state=online,offset=127,lag=0
master_repl_offset:127
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:126
問題:在監控到一個主庫出現問題時我們都是自己來通過命令切換,那有沒有不需要人工干預
自動切換呢? 接下來了解以下 哨兵模式 它就是解決這個問題的。
sentinel搭建
mkdir /nosql/26380
cd /nosql/26380
vim sentinel.conf 新增以下內容,儲存退出
#------------------------------------------
port 26380
dir "/nosql/26380"
sentinel monitor mymaster 127.0.0.1 6380 1
sentinel down-after-milliseconds mymaster 5000
#------------------------------------------
啟動:
redis-sentinel /nosql/26380/sentinel.conf &
啟動成功提醒:
67226:X 18 Sep 20:29:09.262 # Sentinel ID is 19c19134085099bf08c1d498e050fd51cc651de9
67226:X 18 Sep 20:29:09.262 # +monitor master mymaster 127.0.0.1 6380 quorum 1
67226:X 18 Sep 20:29:09.262 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:29:09.264 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:29:11.135 * +sentinel sentinel 8dce82a8f5e8b64c7f7d506c62a4d608d692a587 127.0.0.1 26379 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:29:11.140 # +new-epoch 2
66500:X 18 Sep 20:29:11.275 * +sentinel sentinel 19c19134085099bf08c1d498e050fd51cc651de9 127.0.0.1 26380 @ mymaster 127.0.0.1 6380
停止主庫測試:
[root@k8s-master1 26380]# redis-cli -p 6380
127.0.0.1:6380> shutdown
not connected> exit
提示資訊:
[root@k8s-master1 26380]# redis-cli -p 6380
127.0.0.1:6380> shutdown
not connected> exit
[root@k8s-master1 26380]# 67226:X 18 Sep 20:31:04.775 # +sdown master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.775 # +odown master mymaster 127.0.0.1 6380 #quorum 1/1
67226:X 18 Sep 20:31:04.775 # +new-epoch 3
67226:X 18 Sep 20:31:04.775 # +try-failover master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.776 # +vote-for-leader 19c19134085099bf08c1d498e050fd51cc651de9 3
66500:X 18 Sep 20:31:04.778 # +new-epoch 3
66500:X 18 Sep 20:31:04.778 # +vote-for-leader 19c19134085099bf08c1d498e050fd51cc651de9 3
67226:X 18 Sep 20:31:04.779 # 8dce82a8f5e8b64c7f7d506c62a4d608d692a587 voted for 19c19134085099bf08c1d498e050fd51cc651de9 3
66500:X 18 Sep 20:31:04.802 # +sdown master mymaster 127.0.0.1 6380
66500:X 18 Sep 20:31:04.802 # +odown master mymaster 127.0.0.1 6380 #quorum 1/1
66500:X 18 Sep 20:31:04.802 # Next failover delay: I will not start a failover before Fri Sep 18 20:37:05 2020
67226:X 18 Sep 20:31:04.852 # +elected-leader master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.852 # +failover-state-select-slave master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.915 # +selected-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.915 * +failover-state-send-slaveof-noone slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:04.970 * +failover-state-wait-promotion slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:05.798 # +promoted-slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:05.798 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:05.859 * +slave-reconf-sent slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
66500:X 18 Sep 20:31:05.860 # +config-update-from sentinel 19c19134085099bf08c1d498e050fd51cc651de9 127.0.0.1 26380 @ mymaster 127.0.0.1 6380
66500:X 18 Sep 20:31:05.860 # +switch-master mymaster 127.0.0.1 6380 127.0.0.1 6382
66500:X 18 Sep 20:31:05.860 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6382
66500:X 18 Sep 20:31:05.860 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
67226:X 18 Sep 20:31:06.812 * +slave-reconf-inprog slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:06.812 * +slave-reconf-done slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:06.868 # +failover-end master mymaster 127.0.0.1 6380
67226:X 18 Sep 20:31:06.868 # +switch-master mymaster 127.0.0.1 6380 127.0.0.1 6382
67226:X 18 Sep 20:31:06.868 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6382
67226:X 18 Sep 20:31:06.868 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
66500:X 18 Sep 20:31:10.898 # +sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
67226:X 18 Sep 20:31:11.895 # +sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
可以看到master切換為了 127.0.0.1 6382
[root@k8s-master1 26380]# redis-cli -p 6382
127.0.0.1:6382> info replication
# Replication
role:master <------------- 6382成了主
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=30950,lag=0
master_repl_offset:31216
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:31215
重新啟動6380
[root@k8s-master1 26380]# redis-server /nosql/6380/redis.conf
提示:
67226:X 18 Sep 20:36:45.117 # -sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
66500:X 18 Sep 20:36:45.165 # -sdown slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
67226:X 18 Sep 20:36:55.047 * +convert-to-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6382
檢視資訊:
[root@k8s-master1 26380]# redis-cli -p 6382
127.0.0.1:6382> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=65917,lag=1 #
slave1:ip=127.0.0.1,port=6380,state=online,offset=65917,lag=1 # 發現失聯的伺服器又重新加入到叢集了。
master_repl_offset:65917
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:65916
Sentinel管理命令:
redis-cli -p 26380 連線
PING :返回 PONG
SENTINEL masters :列出所有被監視的主伺服器
SENTINEL slaves <master name>
SENTINEL get-master-addr-by-name <master name> : 返回給定名字的主伺服器的 IP 地址和埠號。
SENTINEL reset <pattern> : 重置所有名字和給定模式 pattern 相匹配的主伺服器。
SENTINEL failover <master name> : 當主伺服器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移。