0x00 Redis簡介
Redis是一款開源的、高性能的鍵-值存儲(key-value store)。它常被稱作是一款資料結構伺服器(data structure server)。
Redis的鍵值可以包括字元串(strings)類型,同時它還包括哈希(hashes)、清單(lists)、集合(sets)和 有序集合(sorted sets)等資料類型。 對于這些資料類型,你可以執行原子操作。例如:對字元串進行附加操作(append);遞增哈希中的值;向清單中增加元素;計算集合的交集、并集與差集等。
為了獲得優異的性能,Redis采用了記憶體中(in-memory)資料集(dataset)的方式。同時,Redis支援資料的持久化,你可以每隔一段時間将資料集轉存到磁盤上(snapshot),或者在日志尾部追加每一條操作指令(append only file,aof)。
Redis同樣支援主從複制(master-slave replication),并且具有非常快速的非阻塞首次同步( non-blocking first synchronization)、網絡斷開自動重連等功能。同時Redis還具有其它一些特性,其中包括簡單的事物支援、釋出訂閱 ( pub/sub)、管道(pipeline)和虛拟記憶體(vm)等 。
Redis具有豐富的用戶端,支援現階段流行的大多數程式設計語言。
Redis 下載下傳位址:http://www.redis.cn/download.html
Redis 線上測試工具:http://try.redis.io/
0x01 Redis單機安裝
1. 線上擷取安裝包或者直接把redis下載下傳好的安裝包拖入要安裝的主機。
wget http://download.redis.io/releases/redis-3.2.6.tar.gz
2. 解壓
tar xzvf redis-3.2.6.tar.gz
3. 進入解壓檔案夾,開始編譯安裝
cd redis-3.2.6
make & make install
4. 編譯完成後,在Src目錄下,有四個可執行檔案redis-server、redis-benchmark、redis-cli和redis.conf。然後拷貝到一個目錄下
mkdir /usr/redis
cp redis-server /usr/redis
cp redis-benchmark /usr/redis
cp redis-cli /usr/redis
cp redis.conf /usr/redis
cd /usr/redis
5. 啟動Redis服務
./redis-server &
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yM5QzNycDZ3YTNzY2Y0MGOyYzX3QTMxETM0IzLcVDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
然後用用戶端測試一下是否啟動成功
redis-cli
6. 停止和解除安裝Redis
pkill redis //停止redis
// 解除安裝redis:
rm -rf /usr/local/redis //删除安裝目錄
rm -rf /usr/bin/redis-* //删除所有redis相關指令腳本
rm -rf /root/download/redis-4.0.4 //删除redis解壓檔案夾
0x02 Redis僞叢集安裝
1. 安裝ruby環境
yum install ruby
yum install rubygems
2.将redis叢集管理工具redis-trib.rb上傳至伺服器,或者線上安裝ruby的包
gem install redis-3.0.0.gem
在local下建立redis-cluster檔案夾,在該檔案夾中建立6個redis執行個體,端口号從7001~7006
複制redis安裝目錄bin檔案夾
在redis-cluster檔案夾下将redis01複制5份
修改redis01至redis06中的redis.conf 檔案,将端口依次改為70001~7006,并打開cluster-enabled yes行前的注釋
3. 把建立叢集的ruby腳本redis-trib.rb複制到redis-cluster檔案夾下
4. 啟動6個redis執行個體
5. 建立叢集(192.168.242.134是你自己ip,建立過程中輸入yes确認)
./redis-trib.rb create --replicas 1
192.168.242.134:7001
192.168.242.134:7002
192.168.242.134:7003
192.168.242.134:7004
192.168.242.134:7005
192.168.242.134:7006
6. 測試叢集(-c 不能缺)
進入叢集任一檔案夾下輸入
redis01/redis-cli -h 192.168.25.153 -p 7002 -c
0x03 Redis之Sentinel高可用主從複制安裝部署
1. Sentinel介紹
1.1 主從複制的問題
Redis
主從複制可将主節點資料同步給從節點,從節點此時有兩個作用:
- 一旦主節點當機,從節點作為主節點的備份可以随時頂上來。
- 擴充主節點的讀能力,分擔主節點讀壓力。
但是問題來了:
- 一旦主節點當機,從節點晉升成主節點,同時需要修改應用方的主節點位址,還需要指令所有從節點去複制新的主節點,整個過程需要人工幹預。
- 主節點的寫能力受到單機的限制。
- 主節點的存儲能力受到單機的限制。
第一個問題,我們接下來講的
Sentinel
就可以解決。而後兩個問題,
Redis
也給出了方案
Redis Cluster
。
1.2 Redis Sentinel的高可用
Redis Sentinel
是一個分布式架構,包含若幹個
Sentinel
節點和
Redis
資料節點,每個
Sentinel
節點會對資料節點和其餘
Sentinel
節點進行監控,當發現節點不可達時,會對節點做下線辨別。
如果被辨別的是主節點,他還會選擇和其他
Sentinel
節點進行“協商”,當大多數的
Sentinel
節點都認為主節點不可達時,他們會選舉出一個
Sentinel
節點來完成自動故障轉移工作,同時将這個變化通知給
Redis
應用方。
整個過程完全自動,不需要人工介入,是以可以很好解決
Redis
的高可用問題。
接下來我們就通過部署一個
Redis Sentinel
執行個體來了解整體架構。
2. Redis Sentinel部署
我們部署的拓撲結構如圖所示:
分别有3個
Sentinel
節點,1個主節點,2個從節點組成一個
Redis Sentinel
。
2.1 啟動主節點
配置:
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
啟動主節點:
sudo redis-server redis-6379.conf
使用
PING
指令檢測是否啟動:
redis-cli -h 127.0.0.1 -p 6379 ping
PONG
2.2 啟動兩個從節點
配置(兩個從節點配置相同,除了檔案名有區分):
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379 // 從屬主節點
啟動兩個從節點:
sudo redis-server redis-6380.conf
sudo redis-server redis-6381.conf
使用
PING
指令檢測是否啟動:
redis-cli -h 127.0.0.1 -p 6380 ping
redis-cli -h 127.0.0.1 -p 6381 ping
2.3 确認主從關系
主節點視角
redis-cli -h 127.0.0.1 -p 6379 INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=85,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=85,lag=0
......
從節點視角(6380端口)
redis-cli -h 127.0.0.1 -p 6380 INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
......
确立中從關系,如下圖所示:
2.4 部署Sentinel節點
3個Sentinel節點的部署方法是相同的(端口不同)。以
26379
為例。
配置
// Sentinel節點的端口
port 26379
dir /var/redis/data/
logfile "26379.log"
// 目前Sentinel節點監控 127.0.0.1:6379 這個主節點
// 2代表判斷主節點失敗至少需要2個Sentinel節點節點同意
// mymaster是主節點的别名
sentinel monitor mymaster 127.0.0.1 6379 2
//每個Sentinel節點都要定期PING指令來判斷Redis資料節點和其餘Sentinel節點是否可達,如果超過30000毫秒且沒有回複,則判定不可達
sentinel down-after-milliseconds mymaster 30000
//當Sentinel節點集合對主節點故障判定達成一緻時,Sentinel上司者節點會做故障轉移操作,選出新的主節點,原來的從節點會向新的主節點發起複制操作,限制每次向新的主節點發起複制操作的從節點個數為1
sentinel parallel-syncs mymaster 1
//故障轉移逾時時間為180000毫秒
sentinel failover-timeout mymaster 180000
啟動(兩種方法)
redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel
sudo redis-sentinel sentinel-26379.conf --sentinel
确認
redis-cli -h 127.0.0.1 -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=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=1 //sentinels=1表示啟動了1個Sentinel
部署三個
Sentinel
節點之後,真個拓撲結構如圖所示:
- 當部署号
之後,會有如下變化Redis Sentinel
- Sentinel節點自動發現了從節點、其餘Sentinel節點。
- 去掉了預設配置,例如:
、parallel-syncs
。failover-timeout
- 新添加了紀元(epoch)參數。
我們拿端口
26379
的舉例,啟動所有的Sentinel和資料節點後,配置檔案如下:
port 26379
dir "/var/redis/data"
sentinel myid 70a3e215c1a34b4d9925d170d9606e615a8874f2
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
daemonize yes
logfile "26379.log"
// 發現了兩個從節點
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
// 發送了連個Sentinel節點
sentinel known-sentinel mymaster 127.0.0.1 26381 e1148ad6caf60302dd6d0dbd693cb3448e209ac2
sentinel known-sentinel mymaster 127.0.0.1 26380 39db5b040b21a52da5334dd2d798244c034b4fc3
sentinel current-epoch 0
2.5 故障轉移實驗
先檢視一下節點的程序
pid
ps -aux | grep redis
root 18225 0.1 0.0 40208 11212 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6379
root 18234 0.0 0.0 38160 8364 ? Ssl 22:10 0:04 redis-server 127.0.0.1:6380
root 18244 0.0 0.0 38160 8308 ? Ssl 22:10 0:04 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 23:05 0:02 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 23:07 0:02 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 23:07 0:02 redis-sentinel *:26381 [sentinel]
我們幹掉端口
6379
的主節點。
➜ sudo kill -9 18225
➜ ps -aux | grep redis
root 18234 0.0 0.0 38160 8364 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6380
root 18244 0.0 0.0 38160 8308 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 23:05 0:03 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 23:07 0:03 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 23:07 0:03 redis-sentinel *:26381 [sentinel]
此時,
Redis Sentinel
對主節點進行客觀下線(Objectively Down, 簡稱 ODOWN)的判斷,确認主節點不可達,則通知從節點中止複制主節點的操作。
當主節點下線時長超過配置的下線時長
30000
秒,
Redis Sentinel
執行故障轉移操作。
此時,我們檢視一下Sentinel節點監控的主節點資訊:
127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6380" //可以看到主節點已經成為6380端口的節點
7) "runid"
8) "084850ab4ff6c2f2502b185c8eab5bdd25a26ce2"
9) "flags"
10) "master"
..............
看一下Sentinel節點監控的從節點資訊:
127.0.0.1:26379> sentinel slaves mymaster
1) 1) "name"
2) "127.0.0.1:6379" //ip:port
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) ""
9) "flags"
10) "s_down,slave,disconnected" //端口6379的原主節點已經斷開了連接配接
..............
2) 1) "name"
2) "127.0.0.1:6381"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6381"
7) "runid"
8) "24495fe180e4fd64ac47467e0b2652894406e9e4"
9) "flags"
10) "slave" //本來的從節點,還是從節點的role
..............
由以上資訊可得,端口為
6380
的Redis資料節點成為新的主節點,端口為
6379
的舊主節點斷開連接配接。如圖所示:
我們在試着重新開機端口
6379
的資料節點。
➜ sudo redis-server redis-6379.conf
➜ ps -aux | grep redis
root 18234 0.1 0.0 40208 11392 ? Ssl 5月22 0:06 redis-server 127.0.0.1:6380
root 18244 0.1 0.0 40208 10356 ? Ssl 5月22 0:07 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 5月22 0:05 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 5月22 0:05 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 5月22 0:05 redis-sentinel *:26381 [sentinel]
menwen 22475 0.0 0.0 14216 5920 pts/2 S+ 5月22 0:00 redis-cli -p 26379
// 6379的資料節點已重新開機
root 22617 0.0 0.0 38160 8304 ? Ssl 00:00 0:00 redis-server 127.0.0.1:6379
看看發生什麼:
127.0.0.1:26379> sentinel slaves mymaster
1) 1) "name"
2) "127.0.0.1:6379" //6379端口的節點重新開機後,變成了"活"的從節點
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "de1b5c28483cf150d9550f8e338886706e952346"
9) "flags"
10) "slave"
..............
2) 1) "name" //6381端口的節點沒有變化,仍是從節點
2) "127.0.0.1:6381"
..............
他被降級成為端口
6380
的從節點。
從上面的邏輯架構和故障轉移試驗中,可以看出
Redis Sentinel
的以下幾個功能。
- 監控:
節點會定期檢測Sentinel
資料節點和其餘Redis
節點是否可達。Sentinel
- 通知:
節點會将故障轉移通知給應用方。Sentinel
- 主節點故障轉移:實作從節點晉升為主節點并維護後續正确的主從關系。
- 配置提供者:在
結構中,用戶端在初始化的時候連接配接的是Redis Sentinel
節點集合,從中擷取主節點資訊。Sentinel
3. Sentinel配置說明
- sentinel monitor mymaster 127.0.0.1 6379 2
- 目前Sentinel節點監控 127.0.0.1:6379 這個主節點
- 2代表判斷主節點失敗至少需要2個Sentinel節點節點同意
- mymaster是主節點的别名
- sentinel down-after-milliseconds mymaster 30000
- 每個Sentinel節點都要定期PING指令來判斷Redis資料節點和其餘Sentinel節點是否可達,如果超過30000毫秒且沒有回複,則判定不可達
- sentinel parallel-syncs mymaster 1
- 當Sentinel節點集合對主節點故障判定達成一緻時,Sentinel上司者節點會做故障轉移操作,選出新的主節點,原來的從節點會向新的主節點發起複制操作,限制每次向新的主節點發起複制操作的從節點個數為1。
- sentinel failover-timeout mymaster 180000
- 故障轉移逾時時間為180000
- sentinel auth-pass \ \
- 如果
監控的主節點配置了密碼,可以通過Sentinel
配置通過添加主節點的密碼,防止sentinel auth-pass
節點無法對主節點進行監控。Sentinel
- 例如:
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
- sentinel notification-script \ \
- 在故障轉移期間,當一些警告級别的
事件發生(指重要事件,如主觀下線,客觀下線等)時,會觸發對應路徑的腳本,想腳本發送相應的事件參數。Sentinel
- 例如:
sentinel notification-script mymaster /var/redis/notify.sh
- sentinel client-reconfig-script \ \
- 在故障轉移結束後,觸發應對路徑的腳本,并向腳本發送故障轉移結果的參數。
- 例如:
。sentinel client-reconfig-script mymaster /var/redis/reconfig.sh