Cookie物件及實現記住使用者名稱案例
一、複製介紹
主從複製,是把一臺redis伺服器上資料複製到其他伺服器的機制,其中前者被稱為主節點(master),後者被稱為從節點(slave)。
主從複製的主要主要作用:
- 資料冗餘:資料熱備,多機備份。
- 故障恢復:當主節點出現問題時,可以讓從節點提供服務,是一種功能的冗餘。
- 負載均衡:可以讓主節點寫,從節點多,可以把壓力分配到多個從節點,從而實現負載均衡。
- 高可用基石:主從複製是實現哨兵和叢集的基礎。
預設情況下,每個redis伺服器都是master節點,每一個master可以有多個slave節點,但是一個salve節點只能有一個master節點。
二、複製配置
2.1 建立複製
2.1.1 命令
- 在配置檔案中加入:slaveof {masterHost} {masterPort}
- 在redis-server啟動命令後加入 -- slaveof {masterHost} {masterPort}
- 直接使用命令(在客戶端執行): slaveof {masterHost} {masterPort}
2.1.2 演示
準備節點
預設6380埠作為master節點,再啟動一個6380節點作為salve節點。
複製一個配置檔案,命名為redis6380.conf
配置新的埠號
兩個redis例項已經啟動。
執行復制命令
啟動兩個例項
執行slaveof命令
檢視效果
master節點寫入,讀取
slave節點讀取資料
至此,複製搭建成功,資料已經成功從master複製到了slave,並且通過salve讀取成功。
2.2 斷開復制
3.2.1 直接斷開
直接使用slaveof no one命令即可斷開和master的複製關係
斷開復制關係後的資料
- 原有已經複製的資料會保留
- master後續寫入的資料將不再同步
可以看到原有的資料保留了
斷開後在原有master寫入
資料將不再同步到6380
3.2.2 切換到其他master
可以通過切換到其他master的方式斷開和當前master的繫結。但是和slave no one不同的是,切換新的master後,從原有master複製過來的資料會被清空。
三、拓撲結構
一對一,一對多,樹狀結構。
四、複製過程
4.1儲存主節點
執行slaveof後從節點只是儲存了主節點的地址資訊變直接返回,複製流程還沒有正式開始。
4.2 主從建立socket連線
從節點內部通過每秒執行的定時任務來處理相關邏輯,當定時任務發現存在新的主節點後,會嘗試和主節點建立網路連線。
從節點會建立一個socket去連線主節點,後續資料同步都是基於這個socket進行。
如果從節點無法建立連線,定時任務會無限重試到連線成功或者複製被取消為止。
4.3 傳送ping命令
連線建立成功後從節點會向主節點發送ping請求進行首次通訊,主要有如下目的:
- 檢測之前建立的socket是否可用。
- 檢測主節點當前是否可接受處理命令
傳送ping命令後如果從節點沒有收到pong回覆或者超時(比如網路超時,或者主節點阻塞無法處理等),從節點會斷開復制,下次定時任務發起後重新連線。
4.4 許可權驗證
如果主節點設定了requirepass引數,則需要密碼驗證,從節點必須配置masterauth引數保證與主節點相同的密碼才能通過驗證,如果驗證失敗,從節點會斷開復制,下次定時任務發起後重新連線。
4.5 資料同步
主從複製連線建立成功後,便開始資料同步,屬於資料的初始化,主節點會把持有的所有資料傳送給從節點,主題是實現方式是從節點給主節點發送psync命令(2.8之前是sync命令)。這塊是耗時最長的步驟,分為全量同步和部分同步。
4.6 命令持續同步
當主節點把當前的資料同步給從節點後,便完成了複製的建立流程,後續主節點會持續的把命令傳送給從節點,保證主從一致。
五、資料同步原理
主從建立連線成功後,從節點會向主節點發送psync命令來完成資料同步,同步過程分為:全量複製和部分複製。
- 全量複製:一般用於初次複製場景,主節點一次性把全部資料發給從節點,是一個比較重的操作
- 部分複製:用於處理在主從複製中因網路閃斷等原因造成的資料丟失的場景,當主從再次連線後,如果主節點完整儲存了中斷期間的資料,主節點會補發丟失的資料給從節點,補發的資料遠遠小於全量資料,部分複製有效避免了全量複製的過高開銷。
5.1 psync命令需要的元件
psync命令執行需要以下元件的支援:
- 主從複製偏移量
- 主節點複製擠壓緩衝區
- 主節點執行id
5.1.1 主從複製偏移量
master節點處理完寫入命令後,會把命令的位元組長度做累加記錄。
從節點再接收到主節點發送的命令後,也會累加自身的偏移量。
通過對比master的偏移量和slave的偏移量來看slave和master的資料差異大小。
5.1.2 主節點複製積壓緩衝區
複製緩衝區是儲存在主節點上的一個固定長度佇列,預設大小為1MB,當有slave時候回建立緩衝區,這時主節點響應寫命令時,不但會把命令傳送給從節點,還會寫入複製擠壓緩衝區。
擠壓緩衝區是一個先進先出的佇列,如果超過容量,之前的資料會被覆蓋。大小是可以配置的。擠壓緩衝區主要為了部分複製做準備。可以通過info replication來檢視:
repl_backlog_active:1 //開啟複製緩衝區
repl_backlog_size:1048576 //緩衝區最大長度
repl_backlog_first_byte_offset:4505 //起始變異量,計算當前緩衝區可用範圍
repl_backlog_histlen:5460 //已儲存資料的有效長度
5.1.3 主節點執行id
每個redis節點(主從)啟動後都會生成一個40位的16進位制的字串作為執行id,用於唯一識別一個redis節點。從節點會儲存主節點的執行id用於識別自己正在複製的是哪一個主節點。redis重啟後id會改變。
初次複製時,從節點會儲存主節點的runid。
5.2 psync命令
從節點通過給主節點發送psync命令實現部分複製或者全量複製。命令格式為:
psync {runid} {offset}
- runid:所輔助主節點的runid,
- offset:當前從節點的資料偏移量
第一次複製時沒有offset和主節點的runid,會發送psync -1命令
5.3 全量複製
- 首次複製傳送 psync ? -1
- master 繼續請求發現是全量複製,恢復fullresync {runid} {offset}
- slave儲存主節點響應的runid和 offset
- 主節點執行bgsave,並且把從選擇開始的命令同時寫入一個緩衝區(複製緩衝區)
- 主節點執行完bgsave後把最終生成的rdb發給salve。
- salve收到主節點發送過來的rdb後開始清空自身資料
- salve把主節點的rdb載入自己的rdb,此時salve的資料更新至主節點執行bgsave時候的狀態。
- 主節點將複製緩衝區的命令傳送給salve
- slave執行接收到的複製緩衝區的命令,至此salve的資料更新至主節點的最新狀態
- 如果slave開啟了aof,則會立即做bgrewriteaof,確保全量複製後aof持久化檔案立即可用。
5.4 部分複製
部分複製時redis針對全量複製開銷過高做出的一種優化措施,使用psync {runid}{offset}命令實現。
當主從複製的過程中,如果出現網路閃斷或者命令丟失等異常情況,從節點會要求主節點補發資料,如果此時主節點的複製積壓緩衝區記憶體中剛好存在這部分資料(就是斷網這段時間沒有同步到從節點的資料),則直接發給從節點,最終保持了和從節點的一直,也避免了大規模的全量複製。
- 如果主從節點之間網路出現中斷,如果超過repl-timeout時間,主節點會認為從節點故障並中斷複製連線。
- 主從斷開後,主節點依然在響應命令,這個時候新的命令無法同步到從節點,主從出現了不一致。上面也解釋了主節點會預設將命令寫入到複製積壓緩衝區,預設為1M,超出後會覆蓋。
- 網路恢復了,從節點再次連線主節點,連線建立成功。
- 從節點儲存了主節點的runid和自身的複製偏移量(offset),通過psync {runid} {offset}命令和主節點進行互動
- 主節點如果發現滿足部分複製的條件(後面詳細解釋這個條件),則返回continue給從節點
- 主節點根據偏移量把複製積壓緩衝區的資料發給從節點,最終保證主從複製進入正常。
主節點判斷判斷滿足部分複製的條件
- runid必須和自身一致
- 從節點發過來的偏移量之後的資料都在自身的複製積壓緩衝區內,這個很好理解,比如從節點發過來的offset是10(代表10以後的資料都沒有同步),但是緩衝區的offset是15(說明15之前的的資料已經不在緩衝區了),這個時候就沒辦法進行部分複製
如果不滿足部分複製條件,則主節點會返回fullsync給從節點,從節點會開啟全量複製。
由此可見覆制積壓緩衝區的大小比較重要,如果太小,會被覆蓋,最終導致主從網路恢復後無法進行部分複製,這個值得大小應該要基於網路的中斷時間,已經主節點的qps和命令的大小來進行計算,然後進行合理的設定。
六、主從心跳
6.1 流程
主從心跳檢測示意圖
-
master會週期性的ping slave,週期時間通過repl-ping-replica-period引數來控制,預設是10秒
-
slave每隔1秒迴向master傳送replconf ack {offset}命令:
-
實時監測主從節點的網路狀態
-
上報自身的資料複製偏移量,如果主節點發現從節點有資料缺失,主節點會從自身的複製積壓緩衝區中拉取資料發給從節點。
-
實現從節點的數量和延遲性功能,通過min-replicas-to-write(最小可用的從節點個數)和min-replicas-max-lag(允許的最小延遲秒,一般為0,或者1)引數定義。
-
如果master開啟了這兩個引數,那麼如果可用的從節點小於min-replicas-to-write或者延遲大於min-replicas-max-lag,master會拒絕資料寫入。示意圖如下。
-
-
6.2 repl -timeout引數
redis.conf有個repl-timeout引數:
-
slave角度,如果在repl-timeout時間內沒有收到傳輸的rdb snapshot資料,
-
slave角度,如果在repl-timeout沒有收到master傳送的資料包或者ping。
-
master角度,如果在repl-timeout時間沒有收到REPCONF ACK確認資訊。
當redis檢測到repl-timeout超時(預設值60s),將會關閉主從之間的連線,redis slave會重新建立主從連線的請求。這個值一定要大於repl-ping-replica-period引數
為了降低主從延遲,一般建議把redis的主從節點部署在相同的機房。
七、全量複製場景
全量複製非常重,應該儘量避免,下面是一些會導致全量複製的操作。
- 第一次建立複製,無法避免,建議低峰時候進行
- runid不匹配,從節點會儲存主節點的runid,如果主節點重啟,則主節點的runid會改變,發現和從節點儲存的runid不一致時,會進行全量複製,應該避免重啟,比如可以採用debug reload命令,或者採用故障轉移功能,當主節點發生故障後,可以將從節點提升為主節點,或者採用哨兵或者叢集方案
- 複製積壓緩衝區不足(repl-backlog-size),這個緩衝區預設大小為1M,當超過1m後覆蓋,主從中斷再次連線後如果從節點的offset在複製積壓緩衝區找不到,則會導致全量複製,這個緩衝區的大小要基於網路狀況,命令大小,以及qps進行計算配置。
七、一些配置和命令
- salve-read-only=yes。 從節點只讀,如果從節點修改,會造成主從資料不一致
- repl-disable-tcp-nodelay 是否關閉tcp_nodelay,預設為no,建議配置為yes。這個是伺服器tcp的一個功能,tcp nagle演算法
- debug reload,不會導致runid改變,但是會情況記憶體資料,再次從rdb載入。
- 。。。