Redis—主從同步

Redis主從同步:數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。這使得Redis可執行單層樹複製。存盤能夠有意無心的對數據進行寫操做。因爲徹底實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈 記錄。同步對讀取操做的可擴展性和數據冗餘頗有幫助。redis

持久化保證了即便 redis 服務重啓也會丟失數據,由於 redis 服務重啓後會將硬盤上持久化的數據恢復到內存中,可是當 redis 服務器的硬盤損壞了可能會致使數據丟失,若是經過 redis 的主從複製機制就能夠避免這種單點故障,以下圖:shell

工做原理:數據庫

  • Redis的主從結構能夠採用一主多從或者級聯結構,Redis主從複製能夠根據是不是全量分爲全量同步和增量同步。vim

  • 主 redis 中的數據有兩個副本(replication)即從 redis1 和從 redis2,即便一臺 redis 服務器宕機其它兩臺 redis 服務也能夠繼續提供服務。緩存

  • 主 redis 中的數據和從 redis 上的數據保持實時同步,當主 redis 寫入數據時經過主從複製機制會複製到兩個從 redis 服務上。服務器

  • 只有一個主 redis,能夠有多個從 redis。性能

  • 主從複製不會阻塞 master,在同步數據時,master 能夠繼續處理 client 請求。測試

  • 一個 redis 能夠便是主又是從,以下圖:3d

主從複製過程

2.8之後實現PSYNC的機制,實現斷線重連code

一、完整複製過程

在 redis2.8 版本以前主從複製過程以下圖:

  • slave 服務啓動,slave 會創建和 master 的鏈接,發送 sync 命令。
  • master 啓動一個後臺進程將數據庫快照保存到 RDB 文件中
注意:此時若是生成 RDB 文件過程當中存在寫數據操做會致使 RDB 文件和當前主 redis 數據不一致,因此此時 master 主進程會開始收集寫命令並緩存起來。
  • master 就發送 RDB 文件給 slave
  • slave 將文件保存到磁盤上,而後加載到內存恢復
  • master 把緩存的命令轉發給 slave

注意:後續 master 收到的寫命令都會經過開始創建的鏈接發送給 slave。

當 master 和 slave 的鏈接斷開時 slave 能夠自動從新創建鏈接。若是 master 同時收到多個 slave 發來的同步鏈接命令,只會啓動一個進程來寫數據庫鏡像,而後發送給全部 slave。

完整複製的問題:

在 redis2.8 以前從 redis 每次同步都會從主 redis 中複製所有的數據,若是從 redis 是新建立的從主 redis  中複製所有的數據這是沒有問題的,可是,若是當從 redis 中止運行,再啓動時可能只有少部分數據和主 redis 不一樣步,此時啓動 redis  仍然會從主 redis 複製所有數據,這樣的性能確定沒有隻複製那一小部分不一樣步的數據高。

二、部分複製

從機鏈接主機後,會主動發起 PSYNC 命令,從機會提供 master 的 runid(機器標識,隨機生成的一個串) 和  offset(數據偏移量,若是offset主從不一致則說明數據不一樣步),主機驗證 runid 和 offset 是否有效,runid  至關於主機身份驗證碼,用來驗證從機上一次鏈接的主機,若是 runid 驗證未經過則,則進行全同步,若是驗證經過則說明曾經同步過,根據  offset 同步部分數據。

主從複製實踐

一、準備三個redis數據庫配置文件

背景: 一主兩從

  • 6380爲主,6381和6382 爲從
cd /opt/redis_conf
vim redis-6380.conf
# 寫入如下配置
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
protected-mode no
  • 再建立兩個配置文件6381和6382
sed "s/6380/6381/g" redis-6380.conf > redis-6381.conf
sed "s/6380/6382/g" redis-6380.conf > redis-6382.conf
  • 建立數據文件目錄
[root@qishi666 redis_conf]# mkdir -p /data/6380
[root@qishi666 redis_conf]# mkdir -p /data/6381
[root@qishi666 redis_conf]# mkdir -p /data/6382

二、啓動redis數據庫

[root@qishi666 redis_conf]# redis-server redis-6380.conf 
[root@qishi666 redis_conf]# redis-server redis-6381.conf 
[root@qishi666 redis_conf]# redis-server redis-6382.conf

三、確保這三個redis數據庫是徹底獨立的數據庫

四、給兩個從服務器配置文件再添加一行配置(很重要)

在6381和6382配置文件添加這一行配置,表示指定主服務器爲6380
slaveof 127.0.0.1 6380

五、重啓數據庫

pkill redis
redis-server /opt/redis_conf/redis-6380.conf
redis-server /opt/redis_conf/redis-6381.conf
redis-server /opt/redis_conf/redis-6382.conf

六、查看主從數據庫狀態

redis-cli -p 6380 info
redis-cli -p 6380 info replication

七、添加數據進行測試

八、手動進行主從複製故障切換

  • 關閉6381的從庫身份
redis-cli -p 6381
info replication
slaveof no one
  • 將6382設爲6381的從庫
6382鏈接到6381:
[root@db03 ~]# redis-cli -p 6382
127.0.0.1:6382> SLAVEOF no one
127.0.0.1:6382> SLAVEOF 127.0.0.1 6381

相關文章
相關標籤/搜索