本文主要描述使用 twemproxy + redis + sentinel + 腳本 實現redis集羣的高可用,篇幅有點長(實戰配置文件/命令) 前端
先貼個本文主要標題列表哈 git
Redis 是徹底開源免費的,遵照BSD協議,內存中的數據結構存儲系統,它能夠用做數據庫、緩存和消息中間件,是一個高性能的key-value數據庫。 github
前面有篇文檔寫到了redis簡介及安裝和壓測數據:http://www.huangdc.com/246 redis
redis sentinel 是redis 官方推薦的redis 高可用(HA)解決方案 算法
sentinel 的功能: sql
Twemproxy,也叫nutcraker。是一個twtter開源的一個redis 和memcache 快速/輕量級代理服務器;Twemproxy是一個快速的單線程代理程序,支持Memcached ASCII協議和更新的Redis協議
Twemproxy 經過引入一個代理層,能夠將其後端的多臺 Redis 或 Memcached 實例進行統一管理與分配,使應用程序只須要在 Twemproxy 上進行操做,而不用關心後面具體有多少個真實的 Redis 或 Memcached 存儲 數據庫
twemproxy 的特性: json
ip | 系統 | 部署軟件 | twemproxy服務 | redis服務 | sentinel服務 |
192.168.16.23 | CentOS 6.7 | redis twemproxy |
192.168.16.23:14500 | _ | 192.168.16.23:26379 |
192.168.16.22 | CentOS 6.7 | redis | _ | 192.168.16.22:4500 192.168.16.22:4501 |
192.168.16.22:26379 |
192.168.16.24 | CentOS 6.7 | redis | _ | 192.168.16.24:4500 192.168.16.24:4501 |
192.168.16.24:26379 |
分別在三臺服務器都安裝 redis (192.168.16.22,192.168.16.23,192.168.16.24 ) 後端
## 下載 && 解壓並安裝 wget http://download.redis.io/releases/redis-3.0.6.tar.gz tar zxf redis-3.0.6.tar.gz cd redis-3.0.6 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.16.23 服務器安裝 twemproxy api
安裝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.zip cd 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.12.22 , 192.168.12.24 建立目錄 mkdir -p /data/nosql/{redis_4500,redis_4501,sentinel} ## 在192.168.12.23 建立目錄 mkdir -p /data/nosql/sentinel mkdir -p /usr/local/twemproxy/{conf,logs}
192.168.12.22:4500 -> 192.168.12.24:4500 (主->從)
192.168.12.22:4501 -> 192.168.12.24:4501 (主->從)
二、在 192.168.12.22 配置 192.168.12.22:4500 redis master
在192.168.12.22 配置master文件 /data/nosql/redis_4500/redis.conf ,文件內容以下:
daemonize yes ##使用daemon 方式運行程序,默認爲非daemon方式運行 pidfile "/data/nosql/redis_4500/redis.pid" ##pid文件位置 port 4500 ##監聽端口 bind 192.168.16.22 ##綁定ip timeout 0 ## client 端空閒斷開鏈接的時間 loglevel warning ##日誌記錄級別,默認是notice,我這邊使用warning,是爲了監控日誌方便。 ## 使用warning後,只有發生告警纔會產生日誌,這對於經過判斷日誌文件是否爲空來監控報警很是方便。 logfile "/data/nosql/redis_4500/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_4500" ## 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 everysec no-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 4500 端口:
## [root@vm16-22 ~]# /usr/local/bin/redis-server /data/nosql/redis_4500/redis.conf
三、在 192.168.12.24 配置 192.168.12.24:4500 redis slave
在 192.168.12.24 配置slave文件 /data/nosql/redis_4500/redis.conf
redis slave 從實例須要多加一個配置參數: slaveof 192.168.16.22 4500 , 指明master 的ip 和端口
文件內容以下:
daemonize yes pidfile "/data/nosql/redis_4500/redis.pid" port 4500 ##監聽端口 bind 192.168.16.24 ##綁定ip timeout 0 loglevel warning logfile "/data/nosql/redis_4500/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_4500" slave-serve-stale-data yes slave-read-only yes slave-priority 100 maxmemory 256mb ##緩存大小 maxmemory-policy allkeys-lru appendonly no appendfsync everysec no-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.16.22 4500
啓動 slave 實例服務
## [root@vm16-24 ~]# /usr/local/bin/redis-server /data/nosql/redis_4500/redis.conf
四、192.168.12.22:4501 -> 192.168.12.24:4501 的 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.16.22:4501 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.16.22:4500 [root@vm16-24 ~]# ps -ef |grep redis root 36265 1 0 Mar04 ? 00:10:08 /usr/local/bin/redis-server 192.168.16.24:4501 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:4500 ## 檢查主從信息 info replication ### 4500 端口主信息 [root@vm16-22 ~]# redis-cli -h 192.168.16.22 -p 4500 info replication # Replication role:master connected_slaves:1 slave0:ip=192.168.16.24,port=4500,state=online,offset=96330188,lag=0 master_repl_offset:96330188 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:95281613 repl_backlog_histlen:1048576 ### 4500 端口從信息 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4500 info replication # Replication role:slave master_host:192.168.16.22 master_port:4500 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:96354366 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 ### 4501 端口主信息 [root@vm16-22 ~]# redis-cli -h 192.168.16.22 -p 4501 info replication # Replication role:master connected_slaves:1 slave0:ip=192.168.16.24,port=4501,state=online,offset=50410,lag=0 master_repl_offset:50553 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:50552 ### 4501 端口從信息 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4501 info replication # Replication role:slave master_host:192.168.16.22 master_port:4501 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:75031 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
六、檢查兩個主從實例同步:
檢查 192.168.12.22:4500 -> 192.168.12.24:4500 (主->從)同步
## 主設置一個key huangdc [root@vm16-22 ~]# redis-cli -h 192.168.16.22 -p 4500 set huangdc "i love you" OK ## 在從獲取 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4500 get huangdc "i love you"
檢查 192.168.12.22:4501 -> 192.168.12.24:4501 (主->從)同步
## 主設置一個key huangdc4501 [root@vm16-22 ~]# redis-cli -h 192.168.16.22 -p 4500 set huangdc4501 "i love you 4501" OK ## 在從獲取 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4500 get huangdc4501 "i love you 4501"
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_4500 192.168.16.22 4500 2 sentinel down-after-milliseconds redis_14555_g1_4500 2500 sentinel failover-timeout redis_14555_g1_4500 10000 sentinel parallel-syncs redis_14555_g1_4500 1 sentinel monitor redis_14555_g2_4501 192.168.16.22 4501 2 sentinel down-after-milliseconds redis_14555_g2_4501 2500 sentinel failover-timeout redis_14555_g2_4501 10000 sentinel parallel-syncs redis_14555_g2_4501 1
上面的配置項配置了兩個名字分別爲redis_14555_g1_4500 和redis_14555_g2_4501 的master,配置文件只須要配置master的信息就好啦,不用配置slave的信息,由於slave可以被自動檢測到(master節點會有關於slave的消息)。須要注意的是,配置文件在sentinel運行期間是會被動態修改的,例如當發生主備切換時候,配置文件中的master會被修改成另一個slave。這樣,以後sentinel若是重啓時,就能夠根據這個配置來恢復其以前所監控的redis集羣的狀態。
你們在這裏記一下我給兩個master的命名爲 redis_14555_g1_4500 和 redis_14555_g2_4501 ,是有目的的,爲了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:4501 的信息( role:slave ) [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4501 info replication # Replication role:slave ## slave master_host:192.168.16.22 master_port:4501 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:855442 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 ## kill 掉 192.168.16.22:4501 master 進程 [root@vm16-22 ~]# ps -ef |grep 4501 root 14455 59263 0 23:16 pts/2 00:00:00 grep 4501 root 37694 1 0 Mar04 ? 00:10:58 /usr/local/bin/redis-server 192.168.16.22:4501 [root@vm16-22 ~]# kill 37694 [root@vm16-22 ~]# ps -ef |grep 4501 root 14532 59263 0 23:16 pts/2 00:00:00 grep 4501 ## 立馬再次查看 192.168.16.24:4501 的信息,角色role 仍是slave ;由於故障轉移須要一點時間 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4501 info replication # Replication role:slave ## slave master_host:192.168.16.22 master_port:4501 master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 slave_repl_offset:857887 master_link_down_since_seconds:20 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 ## 稍等幾秒,再次查看 192.168.16.24:4501 的信息,角色role 仍是master;故障轉移成功,提高slave爲 master了 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4501 info replication # Replication role:master ## master 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 [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_4501 192.168.16.22 4501 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_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.040 # +failover-state-select-slave master redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.117 # +selected-slave slave 192.168.16.24:4501 192.168.16.24 4501 @ redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.117 * +failover-state-send-slaveof-noone slave 192.168.16.24:4501 192.168.16.24 4501 @ redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.176 * +failover-state-wait-promotion slave 192.168.16.24:4501 192.168.16.24 4501 @ redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.425 # +promoted-slave slave 192.168.16.24:4501 192.168.16.24 4501 @ redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.425 # +failover-state-reconf-slaves master redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.425 # +failover-end master redis_14555_g2_4501 192.168.16.22 4501 55580:X 09 Mar 23:17:02.425 # +switch-master redis_14555_g2_4501 192.168.16.22 4501 192.168.16.24 4501 55580:X 09 Mar 23:17:02.426 * +slave slave 192.168.16.22:4501 192.168.16.22 4501 @ redis_14555_g2_4501 192.168.16.24 4501 55580:X 09 Mar 23:17:04.956 # +sdown slave 192.168.16.22:4501 192.168.16.22 4501 @ redis_14555_g2_4501 192.168.16.24 4501
你們能夠自行查看一下相關說明
由於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.16.22:4500:1 - 192.168.16.22:4501:1
上面配置了兩個redis master 的分片 192.168.16.22:4500 和 192.168.16.22:4501 。
這裏的參數咱們先不講,咱們看看配置的文件名是 redis_14555.yml ,你們有沒有想起來,跟sentinel monitor 監控的 master-group-name 有關係,對了取的就是master-group-name 的前半段(redis_14555_g1_4500); 你們再記住一下,後面還會用到
二、啓動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.16.22 -p 4500 get huang "dc" [root@vm16-23 ~]# redis-cli -h 192.168.16.22 -p 4501 get huang (nil) [root@vm16-23 ~]# redis-cli -h 192.168.16.22 -p 4500 get huangggggggggggggggggggggggggg (nil) [root@vm16-23 ~]# redis-cli -h 192.168.16.22 -p 4501 get huangggggggggggggggggggggggggg "dccccccccccccccccccccccccccccccccccccc"
咱們如今將 192.168.16.22:4501 master 直接kill 掉 ,並查看 192.168.16.22:4501 的從服務192.168.16.24:4501是否被提示爲 master
[root@vm16-22 ~]# ps -ef |grep 4501 root 18304 1 0 Mar09 ? 00:00:03 /usr/local/bin/redis-server 192.168.16.22:4501 root 41826 59263 0 00:07 pts/2 00:00:00 grep 4501 [root@vm16-22 ~]# kill 18304 [root@vm16-22 ~]# ps -ef |grep 4501 root 41871 59263 0 00:07 pts/2 00:00:00 grep 4501 ## 查看從服務是否被提高爲新的 master ,以下所示,很明顯已經被提高爲master了 [root@vm16-22 ~]# redis-cli -h 192.168.16.24 -p 4501 info replication # Replication role:master 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
好了,咱們再次經過 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 ## 很明顯,剛剛存儲在 4501 上面的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_4500 , 這裏我就是爲了獲取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_4500 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_4501 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.16.22:4500:1 - 192.168.16.22:4501:1 ### 肯定servers項的信息爲 192.168.16.22:4500:1 和 192.168.16.22:4501:1
好了,在192.168.16.22服務器上,咱們把 192.168.16.22:4501 master 幹掉,直接kill 掉
[root@vm16-22 sentinel]# ps -ef |grep 4501 |grep -v grep root 61109 1 0 00:41 ? 00:00:00 /usr/local/bin/redis-server 192.168.16.22:4501 [root@vm16-22 sentinel]# kill 61109 [root@vm16-22 sentinel]# ps -ef |grep 4501 |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.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.16.22:4500:1 - 192.168.16.24:4501:1
看到沒有,看到沒有,看到沒有,192.168.16.22:4501 已經被替換爲 192.168.16.24:4501 了。
twemproxy + redis + sentinel + 腳本 實現redis高可用架構(高可用集羣)
twemproxy 有個缺點:若是 Twemproxy 的後端節點數量發生變化,Twemproxy 相同算法的的狀況下,原來的數據必須從新處理分佈,不然會存在找不到key值的狀況