redis(4)--redis集群之主從復制


集群

先來簡單了解下redis中提供的集群策略, 雖然redis有持久化功能能夠保障redis服務器宕機也能恢復並且只有少量
的數據損失,但是由於所有數據在一台服務器上,如果這台服務器出現硬盤故障,那就算是有備份也仍然不可避免數據丟失的問題。

在實際生產環境中,我們不可能只使用一台redis服務器作為我們的緩存服務器,必須要多台實現集群,避免出現單點故障;

主從復制

復制的作用是把redis的數據庫復制多個副本部署在不同的服務器上,如果其中一台服務器出現故障,也能快速遷
移到其他服務器上提供服務。 復制功能可以實現當一台redis服務器的數據更新后,自動將新的數據同步到其他服務器上

主從復制就是我們常見的master/slave模式, 主數據庫可以進行讀寫操作,當寫操作導致數據發生變化時會自動將
數據同步給從數據庫。而一般情況下,從數據庫是只讀的,並接收主數據庫同步過來的數據。 一個主數據庫可以有多個從數據庫

 

配置

在redis中配置master/slave是非常容易的,只需要在從數據庫的配置文件中加入slaveof 主數據庫地址 端口。 而master 數據庫不需要做任何改變
准備三台服務器,分別安裝redis , server1(192.168.25.129) server2(192.168.25.130) server3(192.168.25.131)
\1. 在server2的redis.conf文件中增加 slaveof server1-ip 6379 (即:slaveof 192.168.25.129 6379)

 在server3的redis.conf文件中增加 slaveof server1-ip 6379 (即:slaveof 192.168.25.129 6379)
\2. 啟動server1,然后啟動server2,server3
\3. 訪問server2的redis客戶端,輸入 INFO replication

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.25.129
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1556958915
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

則證明從服務器沒有起來,可以yum install telnet安裝telnet命令,安裝成功后,用telnet 192.168.25.129 6379 試一下能不能訪問,如果不能訪問則查看主節點配置(server1 的redis.config)

vim redis.config 查找下圖標黃的配置

# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1

# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
#    "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379

# TCP listen() backlog.
#
# In high requests-per-second environments you need an high backlog in order
# to avoid slow clients connections issues. Note that the Linux kernel

  

  redis3.2版本后新增protected-mode配置,默認是yes,即開啟。設置外部網絡連接redis服務,設置方式如下:

  1、關閉protected-mode模式,此時外部網絡可以直接訪問

  2、開啟protected-mode保護模式,需配置bind ip或者設置訪問密碼

  

  而bind 127.0.0.1 限制訪問地址,設置為 0.0.0.0 表示都可以訪問,如果是127.0.0.1 表示localhost訪問 

  修改后配置從新啟動主、從服務器。可以看到:

  

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.25.129
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:57
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

 

\4. 通過在master機器上輸入命令,比如set foo bar 、 在slave服務器就能看到該值已經同步過來了

 在server1主節點上,設置key,並且get key

127.0.0.1:6379> set lf 1994
OK
127.0.0.1:6379> get lf
"1994"
在server2、server3從節點上get key,一樣可以拿到值

127.0.0.1:6379> get lf
"1994"

 

原理

全量復制

Redis全量復制一般發生在Slave初始化階段,這時Slave需要將Master上的所有數據都復制一份。具體步驟

 在server2上設置監聽:replconf listening-port 6379

 返回ok后,再輸入:sync進行監聽:

 在server1主節點,設置一個key和value 

127.0.0.1:6379> set hello helloword
OK

 觀察server2

127.0.0.1:6379> replconf listening-port 6379
OK
127.0.0.1:6379> sync
Entering slave output mode...  (press Ctrl-C to quit)
SYNC with master, discarding 88 bytes of bulk transfer...
SYNC done. Logging commands from master.
"PING"
"SELECT","0"
"set","hello","helloword"
"PING"
"PING"
"PING"
"PING"
"PING"

  

完成上面幾個步驟后就完成了slave服務器數據初始化的所有操作,savle服務器此時可以接收來自用戶的讀請求。
master/slave 復制策略是采用樂觀復制,也就是說可以容忍在一定時間內master/slave數據的內容是不同的,但是兩者的數據會最終同步。
具體來說,redis的主從同步過程本身是異步的,意味着master執行完客戶端請求的命令后會立即返回結果給客戶端,然后異步的方式把命令同步給slave。
這一特征保證啟用master/slave后 master的性能不會受到影響。

但是另一方面,如果在這個數據不一致的窗口期間,master/slave因為網絡問題斷開連接,而這個時候,master是無法得知某個命令最終同步給了多少個slave數據庫。
不過redis提供了一個配置項來限制只有數據至少同步給多少個slave的時候,master才是可寫的:
min-slaves-to-write 3 表示只有當3個或以上的slave連接到master,master才是可寫的
min-slaves-max-lag 10 表示允許slave最長失去連接的時間,如果10秒還沒收到slave的響應,則master認為該slave以斷開

增量復制

從redis 2.8開始,就支持主從復制的斷點續傳,如果主從復制過程中,網絡連接斷掉了,那么可以接着上次復制的地方,繼續復制下去,而不是從頭開始復制一份
master node會在內存中創建一個backlog,master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。如果master和slave網絡連接斷掉了,slave會讓master從上次的replica offset開始繼續復制
但是如果沒有找到對應的offset,那么就會執行一次全量同步

無硬盤復制

前面我們說過,Redis復制的工作原理基於RDB方式的持久化實現的,也就是master在后台保存RDB快照,slave接收到rdb文件並載入,但是這種方式會存在一些問題
\1. 當master禁用RDB時,如果執行了復制初始化操作,Redis依然會生成RDB快照,當master下次啟動時執行該RDB文件的恢復,但是因為復制發生的時間點不確定,所以恢復的數據可能是任何時間點的。
就會造成數據出現問題

\2. 當硬盤性能比較慢的情況下(網絡硬盤),那初始化復制過程會對性能產生影響因此2.8.18以后的版本,Redis引入了無硬盤復制選項,
可以不需要通過RDB文件去同步,直接發送數據,通過以下配置來開啟該功能
repl-diskless-sync yes
master**在內存中直接創建rdb,然后發送給slave,不會在自己本地落地磁盤了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM