一,實現Redis集羣方案
Redis在3.0版本前只支持單實例模式,雖然Redis的開發者Antirez早在博客上就提出在Redis 3.0版本中加入集羣的功能,但3.0版本等到2015年才發佈正式版。各大企業等不急了,在3.0版本還沒發佈前爲了解決Redis的存儲瓶頸,紛紛推出了各自的Redis集羣方案。這些方案的核心思想是把數據分片(sharding)存儲在多個Redis實例中,每一片就是一個Redis實例。
爲了實現集羣的功能,從服務端、客戶端分片的角度來看,可以分爲以下三類:
客戶端分片: 典型的是支持一致性哈希的客戶端
代理層分片: 典型代表twemproxy、codis
redis服務端分片: redis cluster
客戶端分片是把分片的邏輯放在Redis客戶端實現,(比如:jedis已支持Redis Sharding功能,即ShardedJedis),通過Redis客戶端預先定義好的路由規則(使用一致性哈希),把對Key的訪問轉發到不同的Redis實例中,查詢數據時把返回結果彙集。
客戶端分片的優缺點:
優點:
客戶端sharding技術使用hash一致性算法分片的好處是所有的邏輯都是可控的,不依賴於第三方分佈式中間件。服務端的Redis實例彼此獨立,相互無關聯,每個Redis實例像單服務器一樣運行,非常容易線性擴展,系統的靈活性很強。開發人員清楚怎麼實現分片、路由的規則,不用擔心踩坑。
缺點:
這是一種靜態的分片方案,需要增加或者減少Redis實例的數量,需要手工調整分片的程序。
運維成本比較高,集羣的數據出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。
在不同的客戶端程序中,維護相同的路由分片邏輯成本巨大。比如:java項目、PHP項目裏共用一套Redis集羣,路由分片邏輯分別需要寫兩套一樣的邏輯,以後維護也是兩套。
客戶端分片有一個最大的問題就是,服務端Redis實例羣拓撲結構有變化時,每個客戶端都需要更新調整。如果能把客戶端分片模塊單獨拎出來,形成一個單獨的模塊(中間件),作爲客戶端 和 服務端連接的橋樑就能解決這個問題了,此時代理分片就出現了。
代理基本原理是:通過中間件的形式,Redis客戶端把請求發送到代理,代理根據路由規則發送到正確的Redis實例,最後代理把結果彙集返回給客戶端。
在redis 3.0推出redis cluster之前,代理層實現redis集羣是首選方案,twemproxy和codis是最常見的兩個代理。
然而twemproxy不支持的redis功能太多,像列表的阻塞命令、事物、發佈訂閱等都不支持,而且也沒有直接支持redis的高可用。
twemproxy github地址:https://github.com/twitter/twemproxy
基於上述原因,2017年推出了一款全新的redis代理:predixy。
predixy完美的實現了對redis單例模式及集羣模式的支持,幾乎完整的實現了redis原生的所有用於客戶端的命令。多key命令、列表阻塞操作、發佈訂閱、腳本、掃描等高級功能全支持,在使用redis單例模式下也支持事物。
predixy github地址:https://github.com/joyieldInc/predixy
Redis Cluster是一種服務器Sharding技術(分片和路由都是在服務端實現),採用多主多從,每一個分區都是由一個Redis主機和多個從機組成,片區和片區之間是相互平行的。Redis Cluster集羣採用了P2P的模式,完全去中心化。
redis cluster原理上和codis差不多,同樣是引入了slot的概念,不過redis cluster有16384個slot。redis cluster自身集成了高可用的功能,可擴展也是通過遷移slot來實現的。但是對客戶端來說,redis cluster和單個redis實例相比它在請求響應上帶來了MOVE/ASK語義,也就意味着之前的redis客戶端無法直接獲得全部集羣功能,需要增加對MOVE/ASK響應的支持纔可以訪問整個集羣。
爲了讓客戶端透明的訪問redis cluster,可以在中間加一層代理,predixy是一個不錯的選擇
基於客戶端的方案任何時候都要慎重考慮,在此我們不予推薦。
基於twemproxy的方案雖然看起來功能挺全面,但是實際使用中存在的問題同樣很多,具體見上述,目前也不推薦再用twemproxy的方案。
redis cluster自redis 3.0推出以來,目前已經在很多生產環境上得到了應用,目前來講,構建redis集羣,推薦採用redis cluster搭配一款支持redis cluster的代理方案。
github地址:https://github.com/twitter/twemproxy
git clone https://github.com/twitter/twemproxy.git
1
autoreconf -fvi
1
./configure
1
make
1
執行完之後我們進src目錄會發現生成一個nutcracker可執行程序
cd ..
cd /scripts
sudo cp nutcracker.init /etc/init.d/twemproxy
1
2
3
cd /etc/init.d
sudo chmod +x twemproxy
1
2
mkdir /etc/nutcracker
1
去源碼目錄
cd /soft/twemproxy/conf
1
拷貝當前目錄下所有文件到/etc/nutcracker目錄
sudo cp ./* /etc/nutcracker/
1
1.8,拷貝make生成的nutcracker可執行程序到/usr/bin目錄下
cd /soft/twemproxy/src
sudo cp nutcracker /usr/bin/
1
2
然後我們就可以在操作系統的任何位置來使用nutcracker命令
參照https://github.com/twitter/twemproxy的configuration
cd /etc/nutcracker/
sudo gedit nutcracker.yml
1
2
配置twemproxy端口爲22121,監聽6379,6380兩個redis實例
alpha:
listen: 127.0.0.1:22121
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
redis: true
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
1
2
3
4
5
6
7
8
9
10
11
1.10,啓動6379,6380兩個redis實例,啓動twemproxy代理
#啓動兩個redis實例
redis-server --port 6379
redis-server --port 6380
redis-cli -p 6379
redis-cli -p 6380
#啓動twemproxy代理
nutcracker -d -c /etc/nutcracker/nutcracker.yml
#連接twemproxy代理
redis-cli -p 22121
1
2
3
4
5
6
7
8
9
10
在twemproxy代理也就是22121端口,設置k1 bo
然後我們發現,可以在6380讀取出來,而6379讀取不到,證明代理把k1存儲到6380實例上面了。
twemproxy不支持的redis功能太多,像列表的阻塞命令、事物、發佈訂閱等都不支持,而且也沒有直接支持redis的高可用。
我們打開predixy github地址:https://github.com/joyieldInc/predixy
你可以直接下載編譯好的包,也可以下載代碼自己make
直接下載包地址:https://github.com/joyieldInc/predixy/releases
或下載代碼:
git clone https://github.com/joyieldInc/predixy.git
#下載完成後
cd /predixy
make
1
2
3
4
make完成後會在src目錄下生成predixy可執行文件
1.2,把predixy可執行文件拷貝到/user/bin目錄下,這樣就可以全局使用了
cd /predixy/src
sudo sudo cp predixy /usr/bin/
1
2
1.3,把predixy/conf中的配置文件拷貝到/etc/predixy目錄下
cd /etc
mkdir predixy
cd /soft/predixy/conf
sudo cp ./* /etc/predixy
1
2
3
4
cd /etc
sudo chmod +x -R predixy
1
2
prefixy詳細使用方式可以參考官網:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md
predixy的配置類似redis, 具體配置項的含義在配置文件裏有詳細解釋,請參考下列配置文件:
predixy.conf,整體配置文件,會引用下面的配置文件
cluster.conf,用於Redis Cluster時,配置後端redis信息
sentinel.conf,用於Redis Sentinel時,配置後端redis信息
auth.conf,訪問權限控制配置,可以定義多個驗證密碼,可每個密碼指定讀、寫、管理權限,以及定義可訪問的健空間
dc.conf,多數據中心支持,可以定義讀寫分離規則,讀流量權重分配
latency.conf, 延遲監控規則定義,可以指定需要監控的命令以及延時時間間隔
提供這麼多配置文件實際上是按功能分開了,所有配置都可以寫到一個文件裏,也可以寫到多個文件裏然後在主配置文件裏引用進來。
# 此代理綁定本機端口:7617
Bind 127.0.0.1:7617
# 包含集羣配置文件
Include cluster.conf
1
2
3
4
注意:這裏有一個點,配置文件中每一塊只能開啓一個配置,比如:
################################### SERVERS ####################################
Include cluster.conf
# Include sentinel.conf
#Include try.conf
1
2
3
4
在SERVERS中你如果開啓了cluster,那麼就必須把sentinel和try給註釋掉!!!
配置7000,7001,7002三個主節點,配置8000,8001,8002三個從節點。
ClusterServerPool {
MasterReadPriority 60
StaticSlaveReadPriority 50
DynamicSlaveReadPriority 50
RefreshInterval 1
ServerTimeout 1
ServerFailureLimit 10
ServerRetryTimeout 1
KeepAlive 120
Servers {
+ 127.0.0.1:7000
+ 127.0.0.1:7001
+ 127.0.0.1:7002
+ 127.0.0.1:8000
+ 127.0.0.1:8001
+ 127.0.0.1:8002
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1>,啓動上述6個節點
redis-server /etc/redis/redis_7000.conf
redis-server /etc/redis/redis_7001.conf
redis-server /etc/redis/redis_7002.conf
redis-server /etc/redis/redis_8000.conf
redis-server /etc/redis/redis_8001.conf
redis-server /etc/redis/redis_8002.conf
1
2
3
4
5
6
2>,節點握手
把上述節點加入到同一個集羣中,在7000節點中使用cluster meet命令,可以將所有節點加入到集羣,完成節點握手:
cluster meet 127.0.0.1 7002
cluster meet 127.0.0.1 7003
cluster meet 127.0.0.1 8000
cluster meet 127.0.0.1 8001
cluster meet 127.0.0.1 8002
1
2
3
4
5
3>,分配槽
給三個主節點7001,7002,7003分配槽
redis-cli -p 7000 cluster addslots {0..5461}
redis-cli -p 7001 cluster addslots {5462..10922}
redis-cli -p 7002 cluster addslots {10923..16383}
1
2
3
4>,設置主從關係
至此,集羣搭建成功!
predixy /etc/predixy/predixy.conf
1
出現如下打印則證明啓動成功!
可以看到,k1被分配到了7002主節點,那麼7002的從節點8002應該也能查詢到:
可以看到在從節點8002也可以查詢到!
驗證發佈/訂閱
驗證多key命令支持: mset/msetnx/mget/del/unlink/touch/exists
高性能並輕量級
支持多線程
多平臺支持:Linux、OSX、BSD、Windows(Cygwin)
支持Redis Sentinel,可配置一組或者多組redis
支持Redis Cluster
支持redis阻塞型命令,包括blpop、brpop、brpoplpush
支持scan命令,無論是單個redis還是多個redis實例都支持
多key命令支持: mset/msetnx/mget/del/unlink/touch/exists
支持redis的多數據庫,即可以使用select命令
支持事務,當前僅限於Redis Sentinel下單一redis組可用
支持腳本,包括命令:script load、eval、evalsha
支持發佈訂閱機制,也即Pub/Sub系列命令
多數據中心支持,讀寫分離支持
擴展的AUTH命令,強大的讀、寫、管理權限控制機制,健空間限制機制
日誌可按級別採樣輸出,異步日誌記錄避免線程被io阻塞
日誌文件可以按時間、大小自動切分
豐富的統計信息,包括CPU、內存、請求、響應等信息
延遲監控信息,可以看到整體延遲,分後端redis實例延遲