Redis學習筆記八:集群模式


作者: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四個點

image

這種方式的優點在於:增加節點的時候可以分擔其他節點的壓力,不會造成全局洗牌。

缺點在於:新增節點造成一小部分數據不能命中,會使得緩存擊穿,壓到mysql

解決方案:取離我最近的2個物理節點

modula,random和ketama方式都是從客戶端入手,因為每個客戶端都需要與redis實例建立連接,所以,這種情況會導致連接的成本很高。如何解決這個問題呢?

我們可以在客戶端和Redis之間增加一個代理層,通過代理層去實現原先在客戶端要實現的三個方案。

image

此時,代理層就容易成為一個單點故障。所以代理可以做集群,然后最前端通過LVS來做負載均衡,防止LVS掛掉,可以通過KeepAlived來調配LVS,同時,KeepAlived也可以作為代理層健康檢查的工具。整個架構圖如下:

image

這三種模式的弊端都在於:只能讓Redis做緩存,無法做數據庫。(因為數據會丟失)

要解決這個問題,可以通過預分區的方式,增加槽位的概念:http://www.redis.cn/topics/cluster-tutorial.html

可以通過redis-cluster 模式(無主模型)來解決。

image

客戶端隨機地請求任意一個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

image

在/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

predix實戰

Predixy 是一款高性能全特征redis代理,支持redis-sentinel和redis-cluster。

我們配置一套哨兵來監控兩套主從復制集群,並用predix作為代理。

環境准備

第一套主從:
主:6380
從:6379

第二套主從:
主:16380
從:16379

啟動這兩套實例

哨兵26379

配置為:

port 26379
sentinel monitor mymaster1 127.0.0.1 6380 2
sentinel monitor mymaster2 127.0.0.1 16380 2

哨兵26380

配置為

port 26380
sentinel monitor mymaster1 127.0.0.1 6380 2
sentinel monitor mymaster2 127.0.0.1 16380 2

啟動哨兵

[root@redis01 sentinel]# ps -ef|grep redis
root       1456   1443  0 20:34 pts/1    00:00:00 redis-server 127.0.0.1:6380
root       1474   1463  0 20:35 pts/2    00:00:00 redis-server 127.0.0.1:6379
root       1505   1488  0 20:39 pts/3    00:00:00 redis-server 127.0.0.1:16380
root       1525   1512  0 20:39 pts/4    00:00:00 redis-server 127.0.0.1:16379
root       1574   1559  0 20:44 pts/5    00:00:00 redis-server *:26380 [sentinel]
root       1592   1581  0 20:44 pts/6    00:00:00 redis-server *:26379 [sentinel]

配置predixy

cd /usr/local

## 下載predixy的二進制安裝包
wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz

## 解壓
tar xf predixy-1.0.5-bin-amd64-linux.tar.gz

## 重命名
mv predixy-1.0.5 predixy

cp /usr/local/predixy/bin/predixy /usr/bin/

修改配置

vi /usr/local/predixy/conf/predixy.conf

打開如下兩個配置

Bind 0.0.0.0:7617

## 默認try.conf,注釋掉,打開sentinel.conf
# Include cluster.conf
Include sentinel.conf
#Include try.conf

修改sentinel.conf配置文件

vi /usr/local/predixy/conf/sentinel.conf

增加如下配置項

SentinelServerPool {
    Databases 16
    Hash crc16
    HashTag "{}"
    Distribution modula
    MasterReadPriority 60
    StaticSlaveReadPriority 50
    DynamicSlaveReadPriority 50
    RefreshInterval 1
    ServerTimeout 1
    ServerFailureLimit 10
    ServerRetryTimeout 1
    KeepAlive 120
    Sentinels {
        + 127.0.0.1:26379
        + 127.0.0.1:26380
    }
    Group mymaster1 {
    }
    Group mymaster2 {
    }
}

啟動

predixy /usr/local/predixy/conf/predixy.conf

測試

[root@redis01 conf]# redis-cli -p 7617
127.0.0.1:7617> set k1 aaa
OK
127.0.0.1:7617> get k1 
"aaa"

注:predixy的事務只支持單group

redis-cluster實驗

redis自帶的模式,我們可以通過如下方式來搭建一個redis-cluster

# 進入redis源碼目錄
cd /usr/local/src/redis/utils/create-cluster

執行start

```sh
[root@redis01 create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006

執行create

./create-cluster create
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 7be080333e7acc60e207374f27d6f86f15d3c466 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
M: 8e3d9ca761726e57af2c4ca5c092599e6977a8a8 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
M: 71755fb0c3fcb771432467155585b40efafae80b 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
S: 8eb1de8a35bdfced30ef70d6faedae5cf76b8dda 127.0.0.1:30004
   replicates 7be080333e7acc60e207374f27d6f86f15d3c466
S: f4d69a577b0992191517e1fbb71ee7598a0b8527 127.0.0.1:30005
   replicates 8e3d9ca761726e57af2c4ca5c092599e6977a8a8
S: 4138b3e66c71ededf9362327bb5b2562da688155 127.0.0.1:30006
   replicates 71755fb0c3fcb771432467155585b40efafae80b
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: 7be080333e7acc60e207374f27d6f86f15d3c466 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 4138b3e66c71ededf9362327bb5b2562da688155 127.0.0.1:30006
   slots: (0 slots) slave
   replicates 71755fb0c3fcb771432467155585b40efafae80b
M: 71755fb0c3fcb771432467155585b40efafae80b 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 8e3d9ca761726e57af2c4ca5c092599e6977a8a8 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: f4d69a577b0992191517e1fbb71ee7598a0b8527 127.0.0.1:30005
   slots: (0 slots) slave
   replicates 8e3d9ca761726e57af2c4ca5c092599e6977a8a8
S: 8eb1de8a35bdfced30ef70d6faedae5cf76b8dda 127.0.0.1:30004
   slots: (0 slots) slave
   replicates 7be080333e7acc60e207374f27d6f86f15d3c466
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

客戶端連接30001~30004任意一個服務都可以。

Redis 用作分布式鎖

  1. setnx
  2. 過期時間
  3. 多線程(守護線程)用於延長過期時間

redisson


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM