對 redis 主從同步初認識

前言:

最近在學習 redis,然後看到了 redis 主從同步這塊,正好手上有一個 Centos 服務器和一臺 Ubuntu 筆記本,並且都被我裝了 redis,那就試試唄。

主從同步:

主從同步可以防止主機(Master)壞掉導致網站不能正常工作,這種方法即把從機(Slave)設置爲主機即可。

redis 支持主從同步,數據可以從主服務器向任意數量的從服務器上同步,同步使用的是發佈/訂閱機制,並且配置很簡單。Redis 主從同步的優點如下:

1、Master 可以有多個 Slave;
2、多個 Slave 連接到相同的 Master,Slave 還可以鏈接其他 Slave 形成圖形結構;
3、 不會阻塞 Master。當一個或者多個 Slave 與 Master 進行初次同步數據的時候,Master 可以繼續處理客戶端的請求,相反,Slave 在初次同步數據時會阻塞從而不能處理客戶端的請求(2.2版本後不再阻塞);
4、主從同步用來提高系統的伸縮性,比如多個 Slave 專門用於客戶端的讀請求,而 Master 用來收集數據,達到讀寫分離;
5、 可以在 Master 服務器上禁止數據的持久化(只需要註釋配置文件 redis.conf 中所有 save 配置選項),只在 Slave 服務器上進行數據的持久化。

Redis 主從同步原理:

Redis 主從同步設置很簡單,設置好 Slave 服務器後,Slave 自動和 Master 建立連接,發送 SYNC 命令(同步命令)。無論是第一次同步建立的連接還是連接斷開後重新建立的鏈接,Master 都會啓動一個後臺進程,將內存數據以快照的方式寫入文件中,同時 Master 主進程開始收集新的寫命令並且緩存起來。Master 後臺進程完成內存快照操作後,把數據文件發給 Slave,Slave 將文件保存到磁盤上,然後把數據加載到內存中。接着 Master 把緩存的命令發給 Slave,後續 Master 收到的寫命令都通過開始建立的連接發送給 Slave。當 Master 與 Slave 斷開連接,Slave 自動重新建立連接。如果 Master 同時收到多個 Slave 發來的同步請求,其只啓動一個進程寫數據庫鏡像,然後發送給所有的 Slave。

Redis 主從同步原理圖示:

這裏寫圖片描述

Redis 主從同步過程分兩個階段,第一階段如下:

1) Slave 服務器主動鏈接到 Master 服務器。

2) Slave 服務器發送 SYNC 命令到 Master 服務器請求同步。

3) Master 服務器備份內存數據庫到 rdb 文件。

4) Master 服務器把 rdb 去文件傳輸給 Slave 服務器。

5) Slave 服務器清空數據庫數據,把 rdb 文件數據導入數據庫中。

完成上面的第一階段之後,接下來 Master 服務器把用戶所有更改數據的操作,通過命令的形式轉發給所有 Slave 服務器,Slave 服務器只需執行 Master 服務器發送過來的命令就可以達到同步的效果。

配置 Master、Slave:

現在我有一個 Centos 服務器(IP:115.159.147.258)和一臺 Ubuntu 筆記本,都安裝了 Redis 服務,我將 Centos 配置爲 Master,將 Ubuntu 配置爲 Slave。

配置非常簡單,只需在 Slave 的 Redis 配置文件中指定 Master 的 ip 和 port:

#格式:slaveof <masterip> <masterport>
slaveof 115.159.147.258 6379
#設置slave爲只讀模式(默認也是隻讀的)
slave-read-only yes

重啓 ubuntu 上的 Redis,使配置生效:

systemctl restart redis

如果不想修改配置文件,我們還可以使用命令行的方式:

# Ubuntu 啓動 redis 命令行(客戶端 redis-cli)
/usr/bin/redis-cli
# 127.0.0.1:6379> slaveof 115.159.147.258 6379
OK

使用命令行的方式就不用重啓 Redis。

現在我的 Centos 就是 Master,Ubuntu 就是 Slave 了。

配置完了之後,我們可以分別在 Centos(Master)和 Ubuntu(Slave)分別執行命令:

info replication 

命令查看信息。

#Centos(Master)輸出:
# Replication
role:master
connected_slaves:1
slave0:ip=202.206.209.238,port=6379,state=online,offset=17358,lag=1
.......

#Ubuntu(Slave)輸出:
# Replication
role:slave
master_host:115.159.147.258
master_posr:6379
master_link_status:up
.......

從以上的輸出中可以看出他們的關係了吧。。。。

測試:

我們在 Master 上存一些數據,看看在 Slave 中是否已經同步了。

# Centos :
127.0.0.1:6379> set name lsgogroup
OK
127.0.0.1:6379> set age 20
OK

然後在 Slave 中讀取數據

# Ubuntu:
127.0.0.1:6379> get name
"lsgogroup"
127.0.0.1:6379> get age
"20"

可以看出,數據同步成功,你可以在 Master 中修改一下數據,看看 Slave 中是否會變化。

PS:如果你嘗試在 Slave 中修改數據,比如執行 set name lsgozj,看看會不會提示:(error)READONLY You can’t write against a read only slave。

爲什麼會這樣?

因爲我們前面修改配置文件時設置了 slave-read-only yes,其實默認也是隻讀的。爲什麼要設置 Slave 爲只讀呢?因爲這是爲了實現讀寫分離:多個 Slave 專門用於客戶端的讀請求,而 Master 用來收集數據。

升級 Slave 爲 Master:

Master 不可用的情況下,停止 Master,將 Slave 的設定無效化後,Slave 升級爲 Master。

就是說當 Master 不可用的時候,我們使某臺 Slave 服務器不再作爲從服務器,由於該臺 Slave 服務器保存的數據基本上是最新的,可以把他作爲 Master 來用。

通過註釋前面的配置項然後從其或者在命令行運行 slaveof no one 達到將 Slave 升級爲 Master。

本博客參考自《PHP 核心技術與最佳實踐》,同時更多的關於 redis 主從同步的只是大家可以參考《Redis系列之(二):Redis主從同步,讀寫分離 》

發佈了75 篇原創文章 · 獲贊 171 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章