Redis超級新手指南-下篇(哪吒篇)

可用高性能分佈式緩存解決方案(Rdeis)前端

1.簡述

    本文將從如下幾個方面詳細講解redis,看過上篇(福祿篇)的能夠直接跳過簡介,這裏只是保證文章的可讀性.linux

(在word上寫完才拷貝過來的(幾天才寫完),因此可能看起來不太舒服)git

redis簡介github

sentinel 功能redis

twemproxy特性算法

twemproxy + redis + sentinel 實現redis集羣高可用架構圖sql

環境部署數據庫

redis 主從配置json

sentinel 配置後端

twemproxy 配置

2.Redis 簡介

Redis 是徹底開源免費的,遵照BSD協議,內存中的數據結構存儲系統,它能夠用做數據庫、緩存和消息中間件,是一個高性能的key-value數據庫。

2.1 Redis 特色:

2.1.1 持久化

Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用。


2.1.2 多種數據結構存儲

Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
2.1.3 master-slave

Redis支持數據的備份,即master-slave模式的數據備份。

2.2 Redis 優點:

2.2.1 性能極高

 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。


2.2.2 豐富的數據類型

 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。


2.2.3 原子性

 – Redis的全部操做都是原子性的,同時Redis還支持對幾個操做全並後的原子性執行。


2.2.4、豐富的特性

 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。

3.redis sentinel 

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 會報告新地址。

4.twemproxy (nutcraker)

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都在同一個分片上。

 

4.1 twemproxy + redis + sentinel 高可用架構

 

· 前端使用twemproxy (主備節點)作代理,將其後端的多臺Redis實例分片進行統一管理與分配

· 每個分片節點的redis slave 都是redis master的副本且只讀

· redis sentinel 持續不斷的監控每一個分片節點的master,當master出現故障且不可用狀態時,sentinel 會通知/啓動自動故障轉移等動做

· sentinel 能夠在發生故障轉移動做後觸發相應腳本(經過 client-reconfig-script 參數配置 ),腳本獲取到最新的master來修改 twemproxy 配置並重啓 twemproxy

 

4.2環境部署

4.2.1環境:

(簡單化用臺主機)

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:6380

192.168.2.104:26379

192.168.2.106

    linux

redis

_

192.168.2.106:6379
192.168.2.106:6380

192.168.2.106:26379

4.2.2 架構圖:

安裝redis

分別在三臺服務器都安裝 redis  192.168.2.104192.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

安裝twemproxy

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

5 redis 主從配置

一、建立目錄環境

#### 在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 , 兩個主從同步沒有問題

6 sentinel 配置

在三臺服務器配置 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

你們能夠自行查看一下相關說明

 

7 twemproxy 配置

由於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值的狀況

 

· 

相關文章
相關標籤/搜索