Redis系列1-redis主從、哨兵模式、集羣模式搭建

Redis做爲一款開源的、高性能的鍵值對存儲。支持主從複製,並經過哨兵模式(sentinel)提升了高可用性,以及集羣(Redis Cluster)模式保證了高併發性。node

1、redis主從

Redis自己提供數據持久化的功能(兩種方式:RDB和AOF),把數據保存到磁盤上,保證了即便服務器重啓的狀況下也不會形成數據丟失。因爲數據是保存在一臺服務器上的,若是因爲某些緣由致使系統硬盤損壞,也會致使數據丟失。鑑於這種狀況,通常的作法是把數據備份到不一樣的服務器上,即便有一臺服務器出現故障,其它服務器也能夠提供服務。redis

Redis提供了一主(master)多從(slave)數據庫的方式來進行數據的備份。一個主數據庫能夠有多個從數據庫,一個從數據庫只能有一個主數據庫。通常狀況下,主數據是可讀寫的,從數據只能讀,而且從數據庫同步主數據庫新增的數據。數據庫

Redis主從是一種備份關係,主數據庫寫入數據,同步到從數據庫。若是主數據損壞了,從數據庫能夠做爲主數據庫繼續提供服務。vim

下面就來搭建一個一主二從的主從複製環境。演示環境是在一臺centos 7服務器上模擬的,真實環境須要把主從服務器放置在不一樣的服務器上。centos

1.建立3個redis服務,對應的端口分別是6001,6002,6003,其中6001做爲主庫,6002,6003做爲6001的從庫(備份庫)

在當前目錄新增3個目錄,名稱以端口命名:ruby

mkdir 6001 6002 6003
2.配置主從關係

配置主從關係有兩種方式,一種是經過修改redis.conf配置文件,另外一種是經過命令修改相應配置項。把redis.conf文件分別複製到對應的目錄下服務器

  • 修改redis.conf併發

主庫配置:app

cd ./6001 
vim redis.conf //redis.conf 主庫主要配置項 
​
bind 192.168.80.129//本機IP地址 
port 6001 
requirepass 123456 //設置密碼 
masterauth 123456 //連接主庫密碼

 

從庫配置(以6002端口爲例,6003修改相應端口便可):運維

cd ./6002 
vim redis.conf 
​
bind 192.168.80.129 
port 6002 
requirepass 123456 
masterauth 123456 //鏈接主庫的密碼 對應主庫中
requirepass slaveof 192.168.80.129 6001//主庫 ip 端口

 

  • 命令方式更改主從配置

//分別修改3個redis服務的端口和ip
6001:
bind 192.168.80.129
port 6001
6002:
bind 192.168.80.129
port 6002
6003:
bind 192.168.80.129
port 6003
//開啓redis服務
./redis-server ./6001/redis.conf
./redis-server ./6002/redis.conf
./redis-server ./6003/redis.conf
//使用redis-cli鏈接6002
./redis-cli -h 192.168.80.129 -p 6002 -a 123456
192.168.80.129:6002> slaveof 192.168.80.129 6001
OK
192.168.80.129:6002> config set masterauth 123456
OK
192.168.80.129:6002> info replication
# Replication
role:slave
master_host:192.168.80.129
master_port:6001
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:28
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:131038188755eea59eb4a84de0e2702c977a438b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
//查看6001
192.168.80.129:6001> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.80.129,port=6002,state=online,offset=42,lag=1
master_replid:131038188755eea59eb4a84de0e2702c977a438b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42

 

能夠看到6002已是6001的從服務了,按照6002配置6003爲6001的從服務器,查詢6001的狀態:

192.168.80.129:6001> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.80.129,port=6002,state=online,offset=1022,lag=1
slave1:ip=192.168.80.129,port=6003,state=online,offset=1022,lag=0
master_replid:131038188755eea59eb4a84de0e2702c977a438b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1022
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1022

 

有2個從服務器6002,6003

>>>測試

經過第二步已經成功建立了一主二從的主從複製環境,主服務是可讀寫的,從服務是隻讀的。

在6002上是禁止寫入的:

192.168.80.129:6003> set name 123
(error) READONLY You can't write against a read only slave.

 

在6001上寫入數據:

192.168.80.129:6001> set name test
OK

 

在6002上查看數據已經同步到6002從數據庫上:

192.168.80.129:6002> get name
"test"

 

到這裏,一個主從複製、讀寫分離的環境就完成了,主服務器負責寫入,從服務器服務讀取。然而若是主服務器因爲某種緣由down掉的話,整個服務就沒有辦法寫入,須要運維人員手動恢復主數據庫後才能正常提供服務。下面哨兵模式的登場就有效的解決了主服務down掉人工介入的問題。

2、Redis哨兵(sentinel)

設置Redis主從後,若是主數據斷開後,須要人工手動設置一個從數據庫提高爲主數據庫繼續提供服務,然而這種人工介入的方式,須要耗費必定的時間。爲了實現此過程的自動化,Redis提供了哨兵模式(sentinel)。哨兵負責監控主從數據的運行狀態,若是檢測到主數據庫出現異常,就自動選擇一個從數據庫升級爲主數據庫。

哨兵保證Redis的高可用性(HA),保證特殊故障後可以自動切換,若是主庫異常,自動推選出一個從庫做爲新的主庫繼續提供服務。

下面讓咱們在主從模式的基礎上,添加哨兵機制,主庫down掉後,推選出一個從庫做爲新的主庫,繼續提供服務。

1.將sentinel.conf配置文件複製到目錄下,修改相應配置:
vim sentinel.conf
//修改以下配置項
port 16001
sentinel monitor mymaster 192.168.80.129 6001 1
sentinel auth-pass mymaster 123456

 

2.開啓哨兵
./redis-sentinel ./sentinel.conf
//顯示以下信息,啓動成功,自動檢測到6001下的從服務器
120502:X 18 Apr 11:26:35.565 # Sentinel ID is 0676c2efd784d10801da4e51f17a35ddb2018e54
120502:X 18 Apr 11:26:35.565 # +monitor master mymaster 192.168.80.129 6001 quorum 1
120502:X 18 Apr 11:26:35.566 * +slave slave 192.168.80.129:6002 192.168.80.129 6002 @ mymaster 192.168.80.129 6001
120502:X 18 Apr 11:26:35.567 * +slave slave 192.168.80.129:6003 192.168.80.129 6003 @ mymaster 192.168.80.129 6001

 

哨兵啓動成功後,模擬6001down掉,查看服務狀態:

./redis-cli -h 192.168.80.129 -p 6001 -a 6001 shutdown //或是直接kill id
//查看哨兵服務日誌,以下:成功將6003提高爲主庫
120502:X 18 Apr 11:30:20.478 # +switch-master mymaster 192.168.80.129 6001 192.168.80.129 6003
120502:X 18 Apr 11:30:20.478 * +slave slave 192.168.80.129:6002 192.168.80.129 6002 @ mymaster 192.168.80.129 6003
120502:X 18 Apr 11:30:20.478 * +slave slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003//使用redis-cli鏈接6003,查看信息以下:6003作爲新的主庫,6002爲其從庫
192.168.80.129:6003> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.80.129,port=6002,state=online,offset=26318,lag=0
master_replid:2902c22b9c0c34000c9b3af52dbd812242774a90
master_replid2:695a9c210b17f18e6fc39503b28af3ee341bae2c
master_repl_offset:26461
second_repl_offset:15804
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:26461

 

從新開啓6001服務,6001會成爲6003主庫的從庫:

./redis-server ./6001/redis.conf
//哨兵輸入以下信息,6001成功成爲6003的從庫
120502:X 18 Apr 11:44:16.161 # +sdown slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003
120502:X 18 Apr 11:46:46.411 * +reboot slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003
120502:X 18 Apr 11:46:46.467 # -sdown slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003//查看6003的信息,擁有6001,6002兩個從服務:
192.168.80.129:6003> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.80.129,port=6002,state=online,offset=89380,lag=1
slave1:ip=192.168.80.129,port=6001,state=online,offset=89380,lag=1
master_replid:2902c22b9c0c34000c9b3af52dbd812242774a90
master_replid2:695a9c210b17f18e6fc39503b28af3ee341bae2c
master_repl_offset:89380
second_repl_offset:15804
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:89380

 

3、Redis集羣(cluster)

雖然Redis提供了主從備份、哨兵模式自動切換主從數據庫。可是每一個Redis實例是全量存儲的,存儲的都是完整的數據。這就形成了單個Redis併發有限,而且致使內存佔用太大,rdb文件文件過大,從很大的rdb文件中同步恢復數據會很慢。Redis集羣模式出現就解決了這個問題,採用分佈式存儲,最大化的使用內存。Redis集羣共有16384個哈希槽(slot),每一個Redis節點都會分配一部分slot,經過CRC(16)校驗後16384取模,獲得給定key的哈希槽,就把對應的能夠存儲在相應的節點上。

Redis集羣保證了高併發性,同時集羣致使了數據的分散,不一樣的key存放到不一樣的槽中。

下面使用Redis自帶的redis-trib.rb工具來逐步搭建Redis Cluster。實戰環境須要把redis部署在不一樣的服務器上,咱們演示是在一臺centos 7服務器上,用不一樣的端口來進行部署。因爲Redis集羣中至少須要3個主節點,每一個主節點至少一個從節點(備份),因此須要建立6個節點:

建立6個文件夾,分別命名爲:7001,7002,7003,7004,7005,7006

mkdir 7001 7002 7003 7004 7005 7006

 

一、添加配置信息

把redis.conf配置文件複製到對應的6個文件夾中,並按以下內容配置:

以7001爲例,其它文件內參考以下項修改相應的端口:

bind 192.168.80.129 //配置本機ip
port 7001 //配置端口
daemonize yes //以守護進程方式啓動
pidfile /var/run/redis_7001.pid
dbfilename dump7001.rdb
masterauth 123456 //訪問主機密碼
requirepass 123456 //訪問本實例密碼
appendonly yes //開啓aof
appendfilename "appendonly7001.aof"
cluster-enabled yes //開啓集羣模式
cluster-config-file nodes-7001.conf

 

二、編寫啓動、中止服務腳本:

啓動腳本,命名:start-server.sh

./redis-server ./7001/redis.conf
./redis-server ./7002/redis.conf
./redis-server ./7003/redis.conf
./redis-server ./7004/redis.conf
./redis-server ./7005/redis.conf
./redis-server ./7006/redis.conf

 

中止腳本,命名:stop-server.sh

./redis-cli -c -h 192.168.80.129 -c 7001 -a 123456 shutdown
./redis-cli -c -h 192.168.80.129 -c 7002 -a 123456 shutdown
./redis-cli -c -h 192.168.80.129 -c 7003 -a 123456 shutdown
./redis-cli -c -h 192.168.80.129 -c 7004 -a 123456 shutdown
./redis-cli -c -h 192.168.80.129 -c 7005 -a 123456 shutdown
./redis-cli -c -h 192.168.80.129 -c 7006 -a 123456 shutdown

 

保存以後,須要設置可執行權限:

chmod +x start-server.sh 
chmod +x stop-server.sh

 

三、安裝redis-trib.rb工具所需環境

因爲redis-trib.rb是使用ruby語言編寫的,在使用工具建立集羣前,須要安裝對應的依賴環境。

yum install ruby 
yum install rubygems 
gem install redis

 

建立集羣

./start-server.sh //開啓redis實例
 ps -ef|grep redis //查看redis的狀態
 root     120202      1  0 09:35 ?        00:00:26 ./redis-server 192.168.80.129:7005 [cluster]
 root     122327      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7002 [cluster]
 root     122332      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7003 [cluster]
 root     122337      1  0 09:06 ?        00:00:28 ./redis-server 192.168.80.129:7004 [cluster]
 root     122350      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7006 [cluster]
​
 ./redis-trib.rb create --replicas 1 192.168.80.129:7001 192.168.80.129:7002 192.168.80.129:7003 192.168.80.129:7004 192.168.80.129:7005 192.168.80.129:7006
 

使用create命令建立集羣,--replicas 1參數表示爲每一個主服務器分配1個從服務器。

在redis.conf配置文件中咱們設置了requirepass,須要修改/usr/local/rvm/gems/ruby-2.5.3/gems/redis-4.1.0/lib/redis/client.rb文件中password

DEFAULTS = {
      :url => lambda { ENV["REDIS_URL"] },
      :scheme => "redis",
      :host => "127.0.0.1",
      :port => 6379,
      :path => nil,
      :timeout => 5.0,
      :password => 123456,
      :db => 0,
      :driver => nil,
      :id => nil,
      :tcp_keepalive => 0,
      :reconnect_attempts => 1,
      :reconnect_delay => 0,
      :reconnect_delay_max => 0.5,
      :inherit_socket => false
    }

建立成功後,隨便鏈接一個redis實例,查看集羣全部節點信息:

./redis-cli -c -h 192.168.80.129 -p 7001 -a 123456
cluster nodes
4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555485726804 6 connected
b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555485726000 3 connected 10923-16383
53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555485725000 4 connected
7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 myself,master - 0 1555485726000 8 connected 0-5460
01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 master - 0 1555485725000 2 connected 5461-10922
bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 slave 7f7041c5ef11f5165c7d913596243ca1428

 

從上面信息能夠看出,三個主庫(7001,7002,7003),三個從庫(7004,7005,7006)。三個主庫分配的slot分別是:

70010-5460

70025461-10922

700310923-16383

 

結束7001主庫,查看集羣全部節點狀態:

92.168.80.129:7002> cluster nodes
b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555488472000 3 connected 10923-16383
bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 master - 0 1555488474017 9 connected 0-5460
53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555488473000 4 connected
01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 myself,master - 0 1555488470000 2 connected 5461-10922
4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555488473006 6 connected
7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 master,fail - 1555488452052 1555488450000 8 disconnected

 

其中7001的狀態已是fail,7005已升級爲主庫繼續提供服務。顯然redis cluster自己就集成了主從備份和哨兵模式,主數據庫down掉後,從服務器自動被推選爲新的主服務器,查看集羣狀態以下:

192.168.80.129:7002> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:8
cluster_my_epoch:2
cluster_stats_messages_ping_sent:33577
cluster_stats_messages_pong_sent:25592
cluster_stats_messages_meet_sent:4
cluster_stats_messages_fail_sent:8
cluster_stats_messages_auth-ack_sent:2
cluster_stats_messages_sent:59183
cluster_stats_messages_ping_received:25590
cluster_stats_messages_pong_received:24893
cluster_stats_messages_meet_received:2
cluster_stats_messages_fail_received:2
cluster_stats_messages_publish_received:278
cluster_stats_messages_auth-req_received:2
cluster_stats_messages_received:50767

 

再次啓動7001,7001已成爲7005的從庫

[root@localhost cluster]# ./redis-server ./7001/redis.conf
60511:C 17 Apr 16:10:44.760 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
60511:C 17 Apr 16:10:44.760 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=60511, just started
60511:C 17 Apr 16:10:44.760 # Configuration loaded
[root@localhost cluster]# ./redis-cli -c -h 192.168.80.129 -p 7001 -a 123456
Warning: Using a password with '-a' option on the command line interface may not be safe.
192.168.80.129:7001> cluster nodes
7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 myself,slave bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 0 1555488653000 8 connected
bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 master - 0 1555488657756 9 connected 0-5460
53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555488653732 4 connected
b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555488656752 3 connected 10923-16383
4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555488655743 6 connected
01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 master - 0 1555488656000 2 connected 5461-10922

 

PS:若是有一個主數據庫異常後,沒有從數據庫能夠恢復,整個集羣就會down掉。

本小節主要簡單的介紹下redis集羣的搭建,以及模擬一個主機down掉以後從機自動切換成主機的過程,更多有關redis集羣內容會單獨的章節進行分析總結。

相關文章
相關標籤/搜索