可用高性能分佈式緩存解決方案(Rdeis)前端
本文將從如下幾個方面詳細講解redis,看過上篇(福祿篇)的能夠直接跳過簡介,這裏只是保證文章的可讀性.linux
(在word上寫完才拷貝過來的(幾天才寫完),因此可能看起來不太舒服)git
v redis簡介github
v sentinel 功能redis
v twemproxy特性算法
v twemproxy + redis + sentinel 實現redis集羣高可用架構圖sql
v 環境部署數據庫
v redis 主從配置json
v sentinel 配置後端
v twemproxy 配置
Redis 是徹底開源免費的,遵照BSD協議,內存中的數據結構存儲系統,它能夠用做數據庫、緩存和消息中間件,是一個高性能的key-value數據庫。
Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用。
2.1.2 多種數據結構存儲
Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
2.1.3 master-slave
Redis支持數據的備份,即master-slave模式的數據備份。
– Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
– Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
– Redis的全部操做都是原子性的,同時Redis還支持對幾個操做全並後的原子性執行。
– Redis還支持 publish/subscribe, 通知, key 過時等等特性。
redis sentinel 是redis 官方推薦的redis 高可用(HA)解決方案
sentinel 的功能:
· 監控(Monitoring),sentinel 時刻監控着redis master-slave 是否正常運行
· 通知(Notification),sentinel 能夠經過api 來通知管理員,被監控的redis master-slave 出現了問題
· 自動故障轉移(Automatic failover),當redis master 出現故障不可用狀態,sentinel 會開始一次故障轉移,將其中一個 slave 提高爲新的master ,將其餘的slave 將從新配置使用新的master同步,並使用Redis的服務器應用程序在鏈接時收到使用新的地址鏈接
· 配置提供者(Configuration provider) ,sentinel 做爲在集羣中的權威來源,客戶端鏈接到sentinel來獲取某個服務的當前Redis主服務器的地址和其餘信息。當故障轉移發生時,Sentinel 會報告新地址。
Twemproxy,也叫nutcraker。是一個twtter開源的一個redis 和memcache 快速/輕量級代理服務器;Twemproxy是一個快速的單線程代理程序,支持Memcached ASCII協議和更新的Redis協議
Twemproxy 經過引入一個代理層,能夠將其後端的多臺 Redis 或 Memcached 實例進行統一管理與分配,使應用程序只須要在 Twemproxy 上進行操做,而不用關心後面具體有多少個真實的 Redis 或 Memcached 存儲
twemproxy 的特性:
支持失敗節點自動刪除
- 能夠設置從新鏈接該節點的時間
- 能夠設置鏈接多少次以後刪除該節點
· 支持設置HashTag
- 經過HashTag能夠本身設定將兩個key哈希到同一個實例上去
· 減小與redis的直接鏈接數
- 保持與redis的長鏈接
- 減小了客戶端直接與服務器鏈接的鏈接數量
· 自動分片到後端多個redis實例上
- 多種hash算法:md五、crc1六、crc32 、crc32a、fnv1_6四、fnv1a_6四、fnv1_3二、fnv1a_3二、hsieh、murmur、jenkins
- 多種分片算法:ketama(一致性hash算法的一種實現)、modula、random
- 能夠設置後端實例的權重
· 避免單點問題
- 能夠平行部署多個代理層,經過HAProxy作負載均衡,將redis的讀寫分散到多個twemproxy上。
· 支持狀態監控
- 可設置狀態監控ip和端口,訪問ip和端口能夠獲得一個json格式的狀態信息串
- 可設置監控信息刷新間隔時間
· 使用 pipelining 處理請求和響應
- 鏈接複用,內存複用
- 將多個鏈接請求,組成reids pipelining統一貫redis請求
· 並非支持全部redis命令
- 不支持redis的事務操做
- 使用SIDFF, SDIFFSTORE, SINTER, SINTERSTORE, SMOVE, SUNION and SUNIONSTORE命令須要保證key都在同一個分片上。
· 前端使用twemproxy (主備節點)作代理,將其後端的多臺Redis實例分片進行統一管理與分配
· 每個分片節點的redis slave 都是redis master的副本且只讀
· redis sentinel 持續不斷的監控每一個分片節點的master,當master出現故障且不可用狀態時,sentinel 會通知/啓動自動故障轉移等動做
· sentinel 能夠在發生故障轉移動做後觸發相應腳本(經過 client-reconfig-script 參數配置 ),腳本獲取到最新的master來修改 twemproxy 配置並重啓 twemproxy
(簡單化用兩臺主機)
ip |
系統 |
部署軟件 |
twemproxy服務 |
redis服務 |
sentinel服務 |
192.168.2.104 |
linux |
twemproxy |
192.168.2.104:16379 |
_ |
192.168.2.104:26379 |
192.168.2.104 |
linux |
redis |
_ |
192.168.2.104:6379 |
192.168.2.104:26379 |
192.168.2.106 |
linux |
redis |
_ |
192.168.2.106:6379 |
192.168.2.106:26379 |
分別在三臺服務器都安裝 redis (192.168.2.104,192.168.16.23,192.168.16.24 )
## 下載 && 解壓並安裝
wget http://download.redis.io/releases/redis-3.2.3.tar.gz
tar zxf redis-3.2.3.tar.gz
cd redis-3.2.3
make && make install
## 檢查bin文件 及 版本(默認bin文件路徑爲 /usr/local/bin/ ,也能夠在編譯時候加上 --prefix 參數自定義目錄)
[root@vm16-22 ~]# ll /usr/local/bin/redis*
-rwxr-xr-x 1 root root 4589115 Feb 23 15:07 /usr/local/bin/redis-benchmark
-rwxr-xr-x 1 root root 22177 Feb 23 15:07 /usr/local/bin/redis-check-aof
-rwxr-xr-x 1 root root 45395 Feb 23 15:07 /usr/local/bin/redis-check-dump
-rwxr-xr-x 1 root root 4698322 Feb 23 15:07 /usr/local/bin/redis-cli
lrwxrwxrwx 1 root root 12 Feb 23 15:07 /usr/local/bin/redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 6471190 Feb 23 15:07 /usr/local/bin/redis-server
[root@vm16-22 ~]# /usr/local/bin/redis-server -v
Redis server v=3.0.6 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=a1df4a293d9213e9
在 192.168.2.104 服務器安裝 twemproxy
安裝twemproxy 前,須要安裝autoconf,automake,libtool 軟件包
一、編譯安裝autoconf
## 下載 && 解壓並安裝
wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar zxf autoconf-2.69.tar.gz
./configure
make && make install
二、編譯安裝automake
## 下載 && 解壓並安裝
wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz
tar zxf automake-1.15.tar.gz
./configure
make && make install
三、編譯安裝libtool
## 下載 && 解壓並安裝
wget https://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz
tar zxf libtool-2.4.6.tar.gz
cd libtool-2.4.6
./configure
make && make install
四、編譯安裝twemproxy
## 下載 && 解壓並安裝
wget https://github.com/twitter/twemproxy/archive/master.zip
unzip master.zipcd twemproxy-master## 在twemproxy源碼目錄執行autoreconf 生成 configure文件等
aclocal
autoreconf -f -i -Wall,no-obsolete## 而後編譯安裝
./configure --prefix=/usr/local/twemproxy/
make && make install
注意:若是沒有安裝libtool 的話,autoreconf 的時候會報錯,以下:
configure.ac:133: the top level
configure.ac:36: error: possibly undefined macro: AC_PROG_LIBTOOL
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.autoreconf: /usr/local/bin/autoconf failed with exit status: 1
一、建立目錄環境
#### 在192.168.2.104 , 192.168.2.106 建立目錄mkdir -p /data/nosql/{redis_6379,redis_6380,sentinel}
## 在192.168.2.23 建立目錄mkdir -p /data/nosql/sentinelmkdir -p /usr/local/twemproxy/{conf,logs}
192.168.2.104:6379 -> 192.168.2.106:6379 (主->從)
192.168.2.104:6380 -> 192.168.2.106:6380 (主->從)
二、在 192.168.2.104 配置 192.168.2.104:6379 redis master
在192.168.2.104 配置master文件 /data/nosql/redis_6379/redis.conf ,文件內容以下:
daemonize yes ##使用daemon 方式運行程序,默認爲非daemon方式運行
pidfile "/data/nosql/redis_6379/redis.pid" ##pid文件位置
port 6379 ##監聽端口
bind 192.168.2.104 ##綁定ip
timeout 0 ## client 端空閒斷開鏈接的時間
loglevel warning ##日誌記錄級別,默認是notice,我這邊使用warning,是爲了監控日誌方便。
## 使用warning後,只有發生告警纔會產生日誌,這對於經過判斷日誌文件是否爲空來監控報警很是方便。
logfile "/data/nosql/redis_6379/redis.log"
databases 16 ##默認是0,也就是隻用1 個db,我這邊設置成16,方便多個應用使用同一個redis server。
##使用select n 命令能夠確認使用的redis db ,這樣不一樣的應用即便使用相同的key也不會有問題。
##下面是SNAPSHOTTING持久化方式的策略。##爲了保證數據相對安全,在下面的設置中,更改越頻繁,SNAPSHOTTING越頻繁,##也就是說,壓力越大,反而花在持久化上的資源會越多。##因此我選擇了master-slave模式,並在master關掉了SNAPSHOTTING。
save 900 1 #在900秒以內,redis至少發生1次修改則redis抓快照到磁盤
save 300 10 #在300秒以內,redis至少發生100次修改則redis抓快照到磁盤
save 60 10000 #在60秒以內,redis至少發生10000次修改則redis抓快照到磁盤
stop-writes-on-bgsave-error yes
rdbcompression yes ##使用壓縮
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/nosql/redis_6379"
## replication 設置
slave-serve-stale-data yes
slave-read-only yes
slave-priority 100
###LIMIT 設置
maxmemory 256mb ##redis最大可以使用的內存量,若是使用redis SNAPSHOTTING的copy-on-write的持久會寫方式,會額外的使用內存,
##爲了使持久會操做不會使用系統VM,使redis服務器性能降低,建議保留redis最大使用內存的一半來留給持久化使用
maxmemory-policy allkeys-lru ##使用LRU算法刪除設置了過時時間的key,但若是程序寫的時間沒有寫key的過時時間
##建議使用allkeys-lru,這樣至少保證redis不會不可寫入
##append only mode設置
appendonly no
appendfsync everysecno-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
###slow log 設置
slowlog-log-slower-than 10000
slowlog-max-len 128
##advanced config設置,下面的設置主要是用來節省內存的
hash-max-ziplist-entries 1024
hash-max-ziplist-value 2048
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
啓動master 6379 端口:
##
[root@vm16-22 ~]# /usr/local/bin/redis-server /data/nosql/redis_6379/redis.conf
三、在 192.168.2.106 配置 192.168.2.106:6379 redis slave
在 192.168.2.106 配置slave文件 /data/nosql/redis_6379/redis.conf
redis slave 從實例須要多加一個配置參數: slaveof 192.168.2.104 6379 , 指明master 的ip 和端口
文件內容以下:
daemonize yes
pidfile "/data/nosql/redis_6379/redis.pid"
port 6379 ##監聽端口
bind 192.168.16.24 ##綁定ip
timeout 0
loglevel warning
logfile "/data/nosql/redis_6379/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/data/nosql/redis_6379"
slave-serve-stale-data yes
slave-read-only yes
slave-priority 100
maxmemory 256mb ##緩存大小
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysecno-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
hash-max-ziplist-entries 1024
hash-max-ziplist-value 2048
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# Generated by CONFIG REWRITE## slave 實例只須要配置 slaveof 便可
slaveof 192.168.2.104 6379
啓動 slave 實例服務
##
[root@vm16-24 ~]# /usr/local/bin/redis-server /data/nosql/redis_6379/redis.conf
四、192.168.2.104:6380 -> 192.168.2.106:6380 的 master->slave 同理第二、3步驟
五、檢查兩個主從實例信息:
## 查看redis 進程
[root@vm16-22 ~]# ps -ef |grep redis
root 37694 1 0 Mar04 ? 00:10:52 /usr/local/bin/redis-server 192.168.2.104:6380
root 39611 65000 0 22:03 pts/2 00:00:00 grep redis
root 60304 1 0 Mar04 ? 00:10:07 /usr/local/bin/redis-server 192.168.2.104:6379
[root@vm16-24 ~]# ps -ef |grep redis
root 36265 1 0 Mar04 ? 00:10:08 /usr/local/bin/redis-server 192.168.16.24:6380
root 63873 24110 0 22:03 pts/0 00:00:00 grep redis
root 65394 1 0 Mar04 ? 00:10:38 /usr/local/bin/redis-server 192.168.16.24:6379
## 檢查主從信息 info replication### 6379 端口主信息
[root@vm16-22 ~]# redis-cli -h 192.168.2.104 -p 6379 info replication# Replicationrole:masterconnected_slaves:1slave0:ip=192.168.2.106,port=6379,state=online,offset=96330188,lag=0master_repl_offset:96330188repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:95281613repl_backlog_histlen:1048576
### 6379 端口從信息
[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6379 info replication# Replicationrole:slavemaster_host:192.168.2.104master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:96354366slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
### 6380 端口主信息
[root@vm16-22 ~]# redis-cli -h 192.168.2.104 -p 6380 info replication# Replicationrole:masterconnected_slaves:1slave0:ip=192.168.16.24,port=6380,state=online,offset=50410,lag=0master_repl_offset:50553repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:50552
### 6380 端口從信息
[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6380 info replication# Replicationrole:slavemaster_host:192.168.2.104master_port:6380master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:75031slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
六、檢查兩個主從實例同步:
檢查 192.168.2.104:6379 -> 192.168.2.106:6379 (主->從)同步
## 主設置一個key huangdc[root@vm16-22 ~]# redis-cli -h 192.168.2.104 -p 6379 set huangdc "i love you"OK
## 在從獲取[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6379 get huangdc
"i love you"
檢查 192.168.2.104:6380 -> 192.168.2.106:6380 (主->從)同步
## 主設置一個key huangdc6380[root@vm16-22 ~]# redis-cli -h 192.168.2.104 -p 6379 set huangdc6380 "i love you 6380"OK
## 在從獲取[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6379 get huangdc6380
"i love you 6380"
ok , 兩個主從同步沒有問題
在三臺服務器配置 sentinel ,sentinel 默認監聽端口是 26379
一、三臺服務器的sentinel 配置文件 /data/nosql/sentinel/sentinel.conf ,內容以下:
# Global
port 26379 ##監聽端口
daemonize yes ##使用daemon方式運行程序,默認爲非daemon方式運行
dir "/data/nosql/sentinel"
pidfile "/data/nosql/sentinel/sentinel.pid"
loglevel notice
logfile "/data/nosql/sentinel/sentinel.log"#### sentinel monitor <master-group-name> <ip> <port> <quorum> ####行尾的<quorum>是數字####這個數字代表須要最少多少個sentinel互相溝通來確認某個master是否真的死了### sentinel <option_name> <master-group-name> <option_value>#### down-after-milliseconds : sentinel會向master發送心跳PING來確認master是否存活,若是master在「必定時間範圍」內不迴應PONG或者是回覆了一個錯誤消息,那麼這個sentinel會主觀地(單方面地)認爲這個master已經不可用了(subjectively down, 也簡稱爲SDOWN)。而這個down-after-milliseconds就是用來指定這個「必定時間範圍」的,單位是毫秒。#### failover-timeout : 這個選項肯定自動轉移故障超時時間,單位毫秒#### parallel-syncs : 在發生failover主備切換時,這個選項指定了最多能夠有多少個slave同時對新的master進行同步
sentinel monitor redis_14555_g1_6379 192.168.2.104 6379 2
sentinel down-after-milliseconds redis_14555_g1_6379 2500
sentinel failover-timeout redis_14555_g1_6379 10000
sentinel parallel-syncs redis_14555_g1_6379 1
sentinel monitor redis_14555_g2_6380 192.168.2.104 6380 2
sentinel down-after-milliseconds redis_14555_g2_6380 2500
sentinel failover-timeout redis_14555_g2_6380 10000
sentinel parallel-syncs redis_14555_g2_6380 1
上面的配置項配置了兩個名字分別爲redis_14555_g1_6379 和redis_14555_g2_6380 的master,配置文件只須要配置master的信息就好啦,不用配置slave的信息,由於slave可以被自動檢測到(master節點會有關於slave的消息)。須要注意的是,配置文件在sentinel運行期間是會被動態修改的,例如當發生主備切換時候,配置文件中的master會被修改成另一個slave。這樣,以後sentinel若是重啓時,就能夠根據這個配置來恢復其以前所監控的redis集羣的狀態。
你們在這裏記一下我給兩個master的命名爲 redis_14555_g1_6379 和 redis_14555_g2_6380 ,是有目的的,爲了sentinel 後面觸發修改twemproxy 的配置文件和重啓有關係
sentinel 的配置信息也能夠經過動態配置 ,如 SENTINEL SET command動態修改
二、在三臺服務器分別啓動 sentinel 服務
#/usr/local/bin/redis-sentinel /data/nosql/sentinel/sentinel.conf
三、測試sentinel 自動故障轉移(kill掉一個master ,sentinel 會將slave 提高爲master)
在前面redis 配置主從時候,咱們已經檢查過了 主從的信息
## 查看 192.168.16.24:6380 的信息( role:slave )[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6380 info replication
# Replicationrole:slave ## slavemaster_host:192.168.2.104master_port:6380master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:855442slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
## kill 掉 192.168.2.104:6380 master 進程 [root@vm16-22 ~]# ps -ef |grep 6380 root 14455 59263 0 23:16 pts/2 00:00:00 grep 6380root 37694 1 0 Mar04 ? 00:10:58 /usr/local/bin/redis-server 192.168.2.104:6380 [root@vm16-22 ~]# kill 37694[root@vm16-22 ~]# ps -ef |grep 6380 root 14532 59263 0 23:16 pts/2 00:00:00 grep 6380
## 立馬再次查看 192.168.16.24:6380 的信息,角色role 仍是slave ;由於故障轉移須要一點時間[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6380 info replication
# Replicationrole:slave ## slavemaster_host:192.168.2.104master_port:6380master_link_status:downmaster_last_io_seconds_ago:-1master_sync_in_progress:0slave_repl_offset:857887master_link_down_since_seconds:20slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
## 稍等幾秒,再次查看 192.168.16.24:6380 的信息,角色role 仍是master;故障轉移成功,提高slave爲 master了[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6380 info replication
# Replicationrole:master ## masterconnected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0[root@vm16-22 ~]#
四、查看一臺sentinel 的日誌信息
55580:X 09 Mar 23:17:01.856 # +new-epoch 9
55580:X 09 Mar 23:17:01.856 # +try-failover master redis_14555_g2_6380 192.168.2.104 6380
55580:X 09 Mar 23:17:01.900 # +vote-for-leader f88ba4336b43abddc5c9fbffbc564b2bc213560c 9
55580:X 09 Mar 23:17:01.979 # 192.168.16.23:26379 voted for f88ba4336b43abddc5c9fbffbc564b2bc213560c 9
55580:X 09 Mar 23:17:01.986 # 192.168.16.24:26379 voted for f88ba4336b43abddc5c9fbffbc564b2bc213560c 9
55580:X 09 Mar 23:17:02.040 # +elected-leader master redis_14555_g2_6380 192.168.2.104 6380
55580:X 09 Mar 23:17:02.040 # +failover-state-select-slave master redis_14555_g2_6380 192.168.2.104 6380
55580:X 09 Mar 23:17:02.117 # +selected-slave slave 192.168.16.24:6380 192.168.16.24 6380 @ redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.117 * +failover-state-send-slaveof-noone slave 192.168.16.24:6380 192.168.16.24 6380 @ redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.176 * +failover-state-wait-promotion slave 192.168.16.24:6380 192.168.16.24 6380 @ redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.425 # +promoted-slave slave 192.168.16.24:6380 192.168.16.24 6380 @ redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.425 # +failover-state-reconf-slaves master redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.425 # +failover-end master redis_14555_g2_6380 192.168.2.104 638055580:X 09 Mar 23:17:02.425 # +switch-master redis_14555_g2_6380 192.168.2.104 6380 192.168.16.24 638055580:X 09 Mar 23:17:02.426 * +slave slave 192.168.2.104:6380 192.168.2.104 6380 @ redis_14555_g2_6380 192.168.16.24 638055580:X 09 Mar 23:17:04.956 # +sdown slave 192.168.2.104:6380 192.168.2.104 6380 @ redis_14555_g2_6380 192.168.16.24 6380
你們能夠自行查看一下相關說明
由於sentinel 確保了 redis 主從故障轉移,當master 出現故障後,將slave提高爲master 繼續爲客戶端提供緩存服務;可是新的master ip 和端口信息已經發生了改變,因此客戶端須要從新配置文件或者改造程序才能從新鏈接新的master ,這樣有點不方便 。爲了方便客戶端無需改造及redis 達到高可用狀態(故障恢復時間保持在1分鐘內),咱們採用 twemproxy 作redis 前端代理,分片存儲數據,結合sentinel故障轉移時的通知/觸發腳本功能,作一個自動故障轉移且高可用的redis 集羣。也就是本文最開始的架構圖 twemproxy + redis + sentinel + 腳本 實現redis高可用架構(高可用集羣)
redis 主從 和 sentinel 基本都已經配置好了,咱們如今來配置一下 twemproxy
一、在 192.168.16.23 服務器上配置twemproxy ,配置文件爲 /usr/local/twemproxy/conf/redis_14555.yml
內容爲:
redis_14555:
listen: 192.168.16.23:14555
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
redis: true
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 192.168.2.104:6379:1
- 192.168.2.104:6380:1
上面配置了兩個redis master 的分片 192.168.2.104:6379 和 192.168.2.104:6380 。
這裏的參數咱們先不講,咱們看看配置的文件名是 redis_14555.yml ,你們有沒有想起來,跟sentinel monitor 監控的 master-group-name 有關係,對了取的就是master-group-name 的前半段(redis_14555_g1_6379); 你們再記住一下,後面還會用到
二、啓動twemproxy
## 啓動
[root@vm16-23 ~]# /usr/local/twemproxy/sbin/nutcracker -c /usr/local/twemproxy/conf/redis_14555.yml -p /usr/local/twemproxy/conf/redis_14555.pid -o /usr/local/twemproxy/logs/redis_14555.log -v 11 -d
[root@vm16-23 ~]# ps -ef |grep nutcracker
root 9356 1 0 23:56 ? 00:00:00 /usr/local/twemproxy/sbin/nutcracker -c /usr/local/twemproxy/conf/redis_14555.yml -p /usr/local/twemproxy/conf/redis_14555.pid -o /usr/local/twemproxy/logs/redis_14555.log -v 11 -d
啓動相關參數信息說明:
Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]
[-c conf file] [-s stats port] [-a stats addr]
[-i stats interval] [-p pid file] [-m mbuf size]
Options:
-h, --help : this help -V, --version : show version and exit -t, --test-conf : test configuration for syntax errors and exit -d, --daemonize : run as a daemon -D, --describe-stats : print stats description and exit -v, --verbose=N : set logging level (default: 5, min: 0, max: 11) -o, --output=S : set logging file (default: stderr) -c, --conf-file=S : set configuration file (default: conf/nutcracker.yml) -s, --stats-port=N : set stats monitoring port (default: 22222) -a, --stats-addr=S : set stats monitoring ip (default: 0.0.0.0) -i, --stats-interval=N : set stats aggregation interval in msec (default: 30000 msec) -p, --pid-file=S : set pid file (default: off) -m, --mbuf-size=N : set size of mbuf chunk in bytes (default: 16384 bytes)
三、測試 twemproxy set/get ,後端分片查看
## 測試set 和 get
## 測試短key - value[root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 set huang "dc"OK[root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 get huang
"dc"
## 測試長key - value[root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 set huangggggggggggggggggggggggggg "dccccccccccccccccccccccccccccccccccccc"OK[root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 get huangggggggggggggggggggggggggg
"dccccccccccccccccccccccccccccccccccccc"
## 直接經過後端redis 的master get key 查看存儲,會發現已經分片了[root@vm16-23 ~]# redis-cli -h 192.168.2.104 -p 6379 get huang
"dc"[root@vm16-23 ~]# redis-cli -h 192.168.2.104 -p 6380 get huang
(nil)
[root@vm16-23 ~]# redis-cli -h 192.168.2.104 -p 6379 get huangggggggggggggggggggggggggg
(nil)[root@vm16-23 ~]# redis-cli -h 192.168.2.104 -p 6380 get huangggggggggggggggggggggggggg
"dccccccccccccccccccccccccccccccccccccc"
咱們如今將 192.168.2.104:6380 master 直接kill 掉 ,並查看 192.168.2.104:6380 的從服務192.168.16.24:6380是否被提示爲 master
[root@vm16-22 ~]# ps -ef |grep 6380root 18304 1 0 Mar09 ? 00:00:03 /usr/local/bin/redis-server 192.168.2.104:6380 root 41826 59263 0 00:07 pts/2 00:00:00 grep 6380[root@vm16-22 ~]# kill 18304[root@vm16-22 ~]# ps -ef |grep 6380root 41871 59263 0 00:07 pts/2 00:00:00 grep 6380
## 查看從服務是否被提高爲新的 master ,以下所示,很明顯已經被提高爲master了[root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 6380 info replication
# Replicationrole:masterconnected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
好了,咱們再次經過 twemproxy 獲取 剛剛設置的兩個key 「huang」 和 「huangggggggggggggggggggggggggg"
## [root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 get huang
"dc"[root@vm16-23 ~]# redis-cli -h 192.168.16.23 -p 14555 get huangggggggggggggggggggggggggg
(error) ERR Connection refused
## 很明顯,剛剛存儲在 6380 上面的key:huangggggggggggggggggggggggggg 已經獲取不到了
爲了讓redis 達到高可用狀態,咱們還須要在 sentinel 發送故障轉移的時候,將新的master ip和端口告知twemproxy ,並修改twemproxy的配置文件和重啓nutcracker服務,下一步見分曉
四、sentinel 配置 client-reconfig-script 腳本
增長腳本 /data/nosql/sentinel/client-reconfig.sh ; 並添加執行權限 chmod +x /data/nosql/sentinel/client-reconfig.sh ; 腳本內容以下:
#!/bin/sh ### sentinel 觸發執行此腳本時,會默認傳遞幾個參數過來### <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>#
monitor_name="$1" ##monitor master-group-name
master_old_ip="$4"
master_old_port="$5"
master_new_ip="$6"
master_new_port="$7"
twemproxy_name=$(echo $monitor_name |awk -F'_' '{print $1"_"$2}') ##注意 ## 本文前面已經提了2次讓你們記住一個地方 master-group-name ,我這邊的命名規則 redis_14555_g1_6379 , 這裏我就是爲了獲取redis_14555 , 由於twemproxy 的配置文件名用的是 redis_14555.yml ;## 這裏經過獲取 master-group-name 來修改 twemproxy 的配置文件,這裏定的一點規範而已
twemproxy_bin="/usr/local/twemproxy/sbin/nutcracker"
twemproxy_conf="/usr/local/twemproxy/conf/${twemproxy_name}.yml"
twemproxy_pid="/usr/local/twemproxy/conf/${twemproxy_name}.pid"
twemproxy_log="/usr/local/twemproxy/logs/${twemproxy_name}.log"
twemproxy_cmd="${twemproxy_bin} -c ${twemproxy_conf} -p ${twemproxy_pid} -o ${twemproxy_log} -v 11 -d"
## 將新的master 端口和ip 替換掉 twemproxy 配置文件中舊的master 信息
sed -i "s/${master_old_ip}:${master_old_port}/${master_new_ip}:${master_new_port}/" ${twemproxy_conf}
## kill 掉根據redis_14555.yml配置啓動的nutcracker 進程 ,並從新啓動
ps -ef |grep "${twemproxy_cmd}" |grep -v grep |awk '{print $2}'|xargs kill${twemproxy_cmd}
sleep 1
ps -ef |grep "${twemproxy_cmd}" |grep -v grep
動態修改192.168.16.23:26379 sentinel 的配置,添加 client-reconfig-script 項
[root@vm16-23 sentinel]# redis-cli -h 192.168.16.23 -p 26379 sentinel set redis_14555_g1_6379 client-reconfig-script /data/nosql/sentinel/client-reconfig.sh
OK
[root@vm16-23 sentinel]# redis-cli -h 192.168.16.23 -p 26379 sentinel set redis_14555_g2_6380 client-reconfig-script /data/nosql/sentinel/client-reconfig.sh
OK
[root@vm16-23 sentinel]#
五、再次測試 twemproxy
咱們確認一下 twemproxy的配置文件的 servers 信息:(/usr/local/twemproxy/conf/redis_14555.yml)
[root@vm16-23 sentinel]# cat /usr/local/twemproxy/conf/redis_14555.yml redis_14555: listen: 192.168.16.23:14555 hash: fnv1a_64 distribution: ketama auto_eject_hosts: true redis: true server_retry_timeout: 2000 server_failure_limit: 1 servers: - 192.168.2.104:6379:1 - 192.168.2.104:6380:1
### 肯定servers項的信息爲 192.168.2.104:6379:1 和 192.168.2.104:6380:1
好了,在192.168.2.104服務器上,咱們把 192.168.2.104:6380 master 幹掉,直接kill 掉
[root@vm16-22 sentinel]# ps -ef |grep 6380 |grep -v grep
root 61109 1 0 00:41 ? 00:00:00 /usr/local/bin/redis-server 192.168.2.104:6380
[root@vm16-22 sentinel]# kill 61109
[root@vm16-22 sentinel]# ps -ef |grep 6380 |grep -v grep
經過twemproxy 代理192.168.16.23:14555 獲取key 「huang」 和 「huangggggggggggggggggggggggggg"的值
[root@vm16-22 sentinel]# redis-cli -h 192.168.16.23 -p 14555 get huang
"123"[root@vm16-22 sentinel]# redis-cli -h 192.168.16.23 -p 14555 get huangggggggggggggggggggggggggg
"dccccccccccccccccccccccccccccccccccccc"[root@vm16-22 sentinel]#
## oh oh 獲取到了
再次查看twemproxy 的配置文件的 servers 信息:(/usr/local/twemproxy/conf/redis_14555.yml)
[root@vm16-23 sentinel]# cat /usr/local/twemproxy/conf/redis_14555.ymlredis_14555: listen: 192.168.16.23:14555 hash: fnv1a_64 distribution: ketama auto_eject_hosts: true redis: true server_retry_timeout: 2000 server_failure_limit: 1 servers: - 192.168.2.104:6379:1 - 192.168.16.24:6380:1
看到沒有,看到沒有,看到沒有,192.168.2.104:6380 已經被替換爲 192.168.2.106:6380 了。
twemproxy + redis + sentinel + 腳本 實現redis高可用架構(高可用集羣)
twemproxy 有個缺點:若是 Twemproxy 的後端節點數量發生變化,Twemproxy 相同算法的的狀況下,原來的數據必須從新處理分佈,不然會存在找不到key值的狀況
·