作者:Grey
原文地址:Redis學習筆記八:叢集模式
前面提到的Redis學習筆記七:主從複製和哨兵只能解決Redis的單點壓力大和單點故障問題,接下來要講的Redis Cluster模式,主要是用來解決Redis的單點容量問題。
如何來解決Redis單點容量問題呢?
如果資料可以拆分,我們可以讓不同業務的客戶端打到不同的Redis例項中。
如果資料不能拆分,我們有如下方式:
方案2-1 modula方式
可以通過Hash加上取模的方式來定位打到哪個Redis例項中。
這種方式的弊端在於:模數值固定,會影響分散式下的擴充套件性。
方案2-2 random方式
即每次請求redis的例項是隨機的,一部分客戶端負責push資料,一部分客戶端負責消費資料,這樣的場景可以適用於訊息佇列。
方案2-3 ketama方式
這種方式是通過一致性Hash演算法(沒有取模),規劃成一個環形,環形上有很多虛擬節點,每次選擇的例項通過hash演算法對應到具體的一個節點。模型如下:
Client1~Client4通過Hash分別找到了環上A~B四個點
這種方式的優點在於:增加節點的時候可以分擔其他節點的壓力,不會造成全域性洗牌。
缺點在於:新增節點造成一小部分資料不能命中,會使得快取擊穿,壓到mysql
解決方案:取離我最近的2個物理節點
modula,random和ketama方式都是從客戶端入手,因為每個客戶端都需要與redis例項建立連線,所以,這種情況會導致連線的成本很高。如何解決這個問題呢?
我們可以在客戶端和Redis之間增加一個代理層,通過代理層去實現原先在客戶端要實現的三個方案。
此時,代理層就容易成為一個單點故障。所以代理可以做叢集,然後最前端通過LVS來做負載均衡,防止LVS掛掉,可以通過KeepAlived來調配LVS,同時,KeepAlived也可以作為代理層健康檢查的工具。整個架構圖如下:
這三種模式的弊端都在於:只能讓Redis做快取,無法做資料庫。(因為資料會丟失)
要解決這個問題,可以通過預分割槽的方式,增加槽位的概念:http://www.redis.cn/topics/cluster-tutorial.html
可以通過redis-cluster 模式(無主模型)來解決。
客戶端隨機地請求任意一個redis例項,然後由Redis將請求轉發給正確的Redis節點。Redis Cluster實現了一種混合形式的查詢路由,但並不是直接將請求從一個redis節點轉發到另一個redis節點,而是在客戶端的幫助下直接redirected到正確的redis節點。
但是資料分治的時候,會帶來一個問題,無法做聚合操作,怎麼解決呢?
我們可以使用hash tag,讓同一組key打到同一個redis例項上面,並且對同一hash tag下的key可以進行聚合操作。
Twemproxy實戰
Twemproxy 也叫 nutcraker。是 Twitter 開源的一個 Redis 和 Memcache 代理伺服器,主要用於管理 Redis 和 Memcached 叢集,減少與Cache 伺服器直接連線的數量。
啟動3個redis服務例項:假設為:
- 6379
- 6381
- 6380
在/usr/local/src目錄下,下載最新的twemproxy的原始碼包
cd /usr/local/src
## 下載原始碼
wget https://github.com/twitter/twemproxy/archive/refs/tags/v0.4.1.tar.gz
## 解壓
tar xf v0.4.1.tar.gz
## 重新命名
mv twemproxy-0.4.1/ twemproxy/
接下來按照官方步驟編譯安裝
yum install automake libtool -y
cd /usr/local/src/twemproxy/
autoreconf -fvi
./configure --enable-debug=full
make
src/nutcracker -h
## 安裝成服務
cp nutcracker.init /etc/init.d/nutcracker
chmod +x /etc/init.d/nutcracker
mkdir /etc/nutcracker
cp /usr/local/src/twemproxy/conf/* /etc/nutcracker/
cp /usr/local/src/twemproxy/src/nutcracker /usr/bin
接下來修改twemproxy的配置檔案
vi /etc/nutcracker/nutcracker.yml
修改為:
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
- 127.0.0.1:6381:1
啟動
service nutcracker start
連線到代理:
redis-cli -p 22121
127.0.0.1:22121> set k1 1
OK
127.0.0.1:22121> get k1
"1"
不支援的一些操作。
127.0.0.1:22121> keys *
Error: Server closed the connection
127.0.0.1:22121> watch k1
Error: Server closed the connection
127.0.0.1:22121> mult
Error: Server closed the connection
127.0.0.1:22121> multi
Error: Server closed the connection