# Redis集群搭建的三種方式
## 一、單節點實例
單節點實例還是比較簡單的,平時做個測試,寫個小程序如果需要用到緩存的話,啟動一個
Redis 還是很輕松的,做為一個 key/value 數據庫也是可以勝任的
## 二、主從模式(master/slaver)
**redis 主從模式配置**
**主從模式:**
redis 的主從模式,使用異步復制,slave 節點異步從 master 節點復制數據,master
節點提供讀寫服務,slave 節點只提供讀服務(這個是默認配置,可以通過修改配置文件
slave-read-only 控制)。master 節點可以有多個從節點。配置一個 slave 節點只需要在
redis.conf 文件中指定 slaveof master-ip master-port 即可。
從節點開啟主從復制,有 3 種方式:
**配置文件**
在從服務器的配置文件中加入:slaveof
**啟動命令**
redis-server 啟動命令后加入:slaveof
**客戶端命令**
Redis 服務器啟動后直接通過客戶端執行命令:slaveof,則該 Redis
實例成為從節點。
上述 3 種方式是等效的,下面以客戶端命令的方式為例,看一下當執行了 slaveof 后,Redis
主節點和從節點的變化。
本示例:一個 master 節點有兩個 slave 節點
**配置:**
**1,cd /usr/local/redis/redis-4.0.2**
切換到當前 redis 安裝路徑
**2, mkdir config**
新建一個文件夾,存放 redis 的配置文件
**3,在 config 下,新建三個配置文件,如下:**
> cd config
> vi master-6739.conf
> bind 0.0.0.0
> port 6379
> logfile "6379.log"
> dbfilename "dump-6379.rdb"
> daemonize yes
> rdbcompression yes
> vi slave-6380.confbind 0.0.0.0
> port 6380
> logfile "6380.log"
> dbfilename "dump-6380.rdb"
> daemonize yes
> rdbcompression yes
> slaveof 192.168.81.135 6379
> vi slave-6381.conf
> bind 0.0.0.0
> port 6381
> logfile "6381.log"
> dbfilename "dump-6381.rdb"
> daemonize yes
> rdbcompression yes
> slaveof 192.168.81.135 6379
**master-6739.conf**,為主節點配置文件,**slave-6380.conf,slave-6381.conf**為從節點配置文件
在從節點的配置文件中使用:slaveof 指定 master 節點
**4,啟動三臺 reids 服務**
~~~
[root@localhost redis-4.0.2]# ./src/redis-server config/master-6379.conf
[root@localhost redis-4.0.2]# ./src/redis-server config/slave-6380.conf
[root@localhost redis-4.0.2]# ./src/redis-server config/slave-6381.conf
復制代碼
~~~
查看一下 redis 服務
## 測試主從模式:
**a,先分別連上三臺 Redis 服務,獲取 key 為 name 的值,通過-p 指定連接那個端口的 redis 服務**
~~~
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6379
127.0.0.1:6379> get name
(nil)
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6380
127.0.0.1:6380> get name
(nil)
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6381
127.0.0.1:6381> get name
(nil)
#獲取的值都為空
復制代碼
~~~
**b,給 master 節點 set 一個 key**
~~~
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6379
127.0.0.1:6379> set name cmy
OK
127.0.0.1:6379> get name
"cmy"
復制代碼
~~~
**c,slave 節點直接讀取 key 為 name 的值**
~~~
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6380
127.0.0.1:6380> get name
"cmy"
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6381
127.0.0.1:6381> get name
"cmy"
復制代碼
~~~
**d,slave 節點只提供讀服務,不能進行寫入操作**
~~~
127.0.0.1:6381> set age 23
(error) READONLY You can't write against a read only slave.
復制代碼
~~~
**注意**
使用主從模式時應注意 matser 節點的持久化操作,matser 節點在未使用持久化的情況詳情
下如果宕機,并自動重新拉起服務,從服務器會出現丟失數據的情況。
**首先,禁止 matser 服務持久化**
~~~
127.0.0.1:6379> CONFIG SET save ""
復制代碼
~~~
OK
**在 master 節點 set 一個值**
~~~
127.0.0.1:6379> set age 23
復制代碼
~~~
OK
slave 節點可以 get 到 age 的值
~~~
127.0.0.1:6380> get age
"23"
復制代碼
~~~
關掉 master 節點服務
~~~
127.0.0.1:6379> shutdown
not connected>
復制代碼
~~~
slave 節點此時仍可以 get 到 age 的值
~~~
127.0.0.1:6380> get age
"23"
復制代碼
~~~
重啟 master 服務,此時獲取不到 age 的值
~~~
[root@localhost redis-4.0.2]# ./src/redis-server config/master-6379.conf
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6379
127.0.0.1:6379> get age
(nil)
復制代碼
~~~
slave 節點此時在獲取 age 的值為空,數據丟失
~~~
[root@localhost redis-4.0.2]# ./src/redis-cli -p 6380
127.0.0.1:6380> get age
(nil)
復制代碼
~~~
數據丟失的原因:因為 master 服務掛了之后,重啟服務后,slave 節點會與 master 節點進行
一次完整的重同步操作,所以由于 master 節點沒有持久化,就導致 slave 節點上的數據也會
丟失掉。所以在配置了 Redis 的主從模式的時候,應該打開主服務器的持久化功能。
到這,redis 的主從模式就已經完成了
**談談我認為主從模式的必要性:**
主從模式的一個作用是備份數據,這樣當一個節點損壞(指不可恢復的硬件損壞)時,數據
因為有備份,可以方便恢復。
另一個作用是負載均衡,所有客戶端都訪問一個節點肯定會影響 Redis 工作效率,有了主從
以后,查詢操作就可以通過查詢從節點來完成。
**對主從模式必須的理解(結論已經驗證過,可以自行驗證):**
一個 Master 可以有多個 Slaves
默認配置下,master 節點可以進行讀和寫,slave 節點只能進行讀操作,寫操作被禁止
不要修改配置讓 slave 節點支持寫操作,沒有意義,原因一,寫入的數據不會被同步到其他
節點;原因二,當 master 節點修改同一條數據后,slave 節點的數據會被覆蓋掉
slave 節點掛了不影響其他 slave 節點的讀和 master 節點的讀和寫,重新啟動后會將數據從
master 節點同步過來
master 節點掛了以后,不影響 slave 節點的讀,Redis 將不再提供寫服務,master 節點啟動
后 Redis 將重新對外提供寫服務。
master 節點掛了以后,不會 slave 節點重新選一個 master
**對有密碼的情況說明一下,當 master 節點設置密碼時:**
客戶端訪問 master 需要密碼
啟動 slave 需要密碼,在配置中進行配置即可
客戶端訪問 slave 不需要密碼
**主從節點的缺點**
主從模式的缺點其實從上面的描述中可以得出:
master 節點掛了以后,redis 就不能對外提供寫服務了,因為剩下的 slave 不能成為 master
這個缺點影響是很大的,尤其是對生產環境來說,是一刻都不能停止服務的,所以一般的生
產壞境是不會單單只有主從模式的。所以有了下面的 sentinel 模式。三、sentinel 模式
Redis 哨兵模式,用現在流行的話可以說就是一個“哨兵機器人”,給“哨兵機器人”進行相
應的配置之后,這個"機器人"可以 7\*24 小時工作,它能能夠自動幫助你做一些事情,如監
控,提醒,自動處理故障等。
**Redis-sentinel 簡介**
Redis-sentinel 是 Redis 的作者 antirez,因為 Redis 集群的被各大公司使用,每個公司要寫自 己的集群管理工具,于是 antirez 花了幾個星期寫出了 Redis-sentinel。
Redis 的 Sentinel 系統用于管理多個 Redis 服務器(instance),Redis 的 Sentinel 為 Redis 提供了高可用性。使用哨兵模式創建一個可以不用人為干預而應對各種故障的 Redis 部署。
**該系統執行以下三個任務:**
監控(Monitoring):Sentinel 會不斷地檢查你的主服務器和從服務器是否允許正常。
提醒(Notification):當被監控的某個 Redis 服務器出現問題時,Sentinel 可以通過 API 向管 理員或者其他應用程序發送通知。
自動故障遷移(Automatic failover): (1)當一個主服務器不能正常工作時,Sentinel 會開
始一次自動故障遷移操作,他會將失效主服務器的其中一個從服務器升級為新的主服務器,
并讓失效主服務器的其他從服務器改為復制新的主服務器;(2)客戶端試圖連接失敗的主服
務器時,集群也會向客服端返回新主服務器的地址,是的集群可以使用新主服務器代替失效
服務器。
**sentinel 的分布式特性**
Redis Sentinel 是一個分布式系統,
你可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來接收關于主服務器是否下線的信息, 并使用投 票協議(agreement protocols)來決定是否執行自動故障遷移, 以及選擇哪個從服務器作為 新的主服務器。
單個 sentinel 進程來監控 redis 集群是不可靠的,當 sentinel 進程宕掉后(sentinel 本身也有單 點問題,single-point-of-failure)整個集群系統將無法按照預期的方式運行。所以有必要將
**sentinel 集群,這樣有幾個好處:**
* 有一些 sentinel 進程宕掉了,依然可以進行 redis 集群的主備切換;
* 如果只有一個 sentinel 進程,如果這個進程運行出錯,或者是網絡堵塞,那么將無法實現 redis
**集群的主備切換(單點問題);**
如果有多個 sentinel,redis 的客戶端可以隨意地連接任意一個 sentinel 來獲得關于 redis 集群 中的信息
一個健壯的部署至少需要三個哨兵實例。
三個哨兵實例應該放置在客戶使用獨立方式確認故障的計算機或虛擬機中。例如不同的物理
機或不同可用區域的虛擬機。【本次講解是一個機器上進行搭建,和多級是一個道理背景
最近項目需求,接觸到了 Redis 的搭建,簡單記錄下搭建過程中遇到的坑
## 總體配置
~~~
192.168.1.100:6379 -> master
192.168.1.101:6379 -> slave
192.168.1.102:6379 -> slave
192.168.1.100:26379 -> sentinel
192.168.1.101:26379 -> sentinel
192.168.1.102:26379 -> sentinel
復制代碼
~~~
## 搭建步驟
**1.安裝 redis**
~~~
# 解壓
tar -xvf /usr/local/redis-3.2.11.tar.gz
mkdir -p /usr/local/redis/bin
cp
/usr/local/redis/src/{redis-benchmark,redis-check-aof,redis-check-rdb,redis-cli,redis-sentinel,redi
s-server,redis-trib.rb} /usr/local/redis/bin
mkdir -p /u01/redis/{6379/{log,data,pid,conf},26379/{log,data,pid,conf}
# 添加環境變量
echo "export PATH=/usr/local/redis/bin:$PATH" >> /etc/profile
source /etc/profile
復制代碼
~~~
**2.redis-6379 配置**
redis 節 點 配 置 基 本 如 下 , 把 如 下 配 置 分 別 cp 到 三 臺 虛 擬 機 的
~~~
/u01/redis/6379/conf/redis_6379.conf
bind 0.0.0.0
protected-mode no
daemonize yes
pidfile "/u01/redis/6379/pid/redis_6379.pid"
port 6379
tcp-backlog 511
timeout 0tcp-keepalive 0
loglevel notice
logfile "/u01/redis/6379/log/redis_6379.log"
databases 16
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/u01/redis/6379/data"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
min-slaves-to-write 1
min-slaves-max-lag 10
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
復制代碼
~~~
## 啟動服務
~~~
# 在三臺虛擬機上分別執行
redis-server /u01/redis/6379/conf/redis_6379.conf
復制代碼
~~~
## 建立主從關系
~~~
# 在 192.168.1.101
redis-cli -p 6379 SLAVEOF 192.168.1.100 6379
# 在 192.168.1.102
redis-cli -p 6379 SLAVEOF 192.168.1.100 6379查看 Replication
192.168.1.101:6379> info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=192.168.1.102,port=6379,state=online,offset=9577826,lag=1
slave1:ip=192.168.1.103,port=6379,state=online,offset=9577965,lag=0
master_repl_offset:9577965
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:8529390
repl_backlog_histlen:1048576
192.168.1.102:6379> info replication
# Replication
role:slave
master_host:192.168.1.101
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:9600220
slave_priority:100
slave_read_only:1
connected_slaves:0
min_slaves_good_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.1.103:6379> info replication
# Replication
role:slave
master_host:192.168.1.101
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:9612675slave_priority:100
slave_read_only:1
connected_slaves:0
min_slaves_good_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
復制代碼
~~~
**3.sentinel-6379 配置**
sentinel 節 點 配 置 基 本 如 下 , 把 如 下 配 置 分 別 cp 到 三 臺 虛 擬 機 的
~~~
/u01/redis/26379/conf/sentinel_26379.conf
復制代碼
~~~
sentinel monitor mymaster 后監控的是 redis 中的 master 節點,也就是 192.168.1.100,所以
這個文件在三臺機器上是相同的
~~~
port 26379
bind 0.0.0.0
daemonize yes
protected-mode no
dir "/u01/redis/26379/tmp"
logfile "/u01/redis/26379/log/sentinel_26379.log"
sentinel monitor mymaster 192.168.1.100 6379 1
復制代碼
~~~
等待啟動完畢后觀察/u01/redis/26379/conf/sentinel\_26379.conf 文件變化
查看 sentinel 狀態用 info sentinel
~~~
redis-cli -h 192.168.1.100 -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=zhuanche01,status=ok,address=192.168.1.100:6379,slaves=2,sentinels=3
復制代碼
~~~
## 總結
我搭建的時候遇到了 192.168.1.101、192.168.1.102 上的 sentinel 啟動后一段時間出錯的問題,
后來發現是沒有監控 master
再就是出問題了多看 log
## 四、cluster 模式cluster 的出現是為了解決單機 Redis 容量有限的問題,將 Redis 的數據根據一定的規則分配
到多臺機器。對 cluster 的一些理解:
cluster 可以說是 sentinel 和主從模式的結合體,通過 cluster 可以實現主從和 master 重選功
能,所以如果配置兩個副本三個分片的話,就需要六個 Redis 實例。
因為 Redis 的數據是根據一定規則分配到 cluster 的不同機器的,當數據量過大時,可以新增
機器進行擴容
這種模式適合數據量巨大的緩存要求,當數據量不是很大使用 sentinel 即可。