Redis集群原理及搭建(Twemproxy、Predixy代理搭建、Redis Cluster集群)


LVS+KeepAlived高可用部署架构》)。接下来我们讲解下Redis集群的具体搭建,proxy和Redis Cluster。

GItHub

# 下载安装包
wget https://github.com/twitter/twemproxy/releases/download/0.5.0/twemproxy-0.5.0.tar.gz

tar xf twemproxy-0.5.0.tar.gz 

# twemproxy运行需要automake和 libtool
yum install automake libtool -y
cd twemproxy
autoreconf -fvi
./configure
make

# 复制配置文件及加入系统命令
cp scripts/nutcracker.init /etc/init.d/twemproxy
chmod +x /etc/init.d/twemproxy
mkdir /etc/nutcracker
cp conf/* /etc/nutcracker/
cp src/nutcracker /usr/bin/
cd /etc/nutcracker/

# 修改配置文件
cp nutcracker.yml nutcracker.yml.bak

修改后配置,按需修改,这里使用的是本机2台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

GItHub

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 

3.2.2 配置

修改predixy.conf

vi predixy-1.0.5/conf/predixy.conf 

打开绑定端口

打开sentinel配置

修改sentinel配置

vi predixy-1.0.5/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
	# 哨兵IP就端口
    Sentinels {
        + 127.0.0.1:8001
        + 127.0.0.1:8002
        + 127.0.0.1:8003
    }
	# 分组
    Group beijin {
    }
    Group shanghai {
    }
}

3.2.3 启动sentinel集群

集群拓扑图

说明:通过sentinel集群端口为:8001、8002、8003 监控2套Redis主从beijin和shanghai。
Redis主从一:beijin Master端口为6001,Slave 6002;
Redis主从一: shanghai Master端口为7001,Slave端口7002;
sentinel配置
beijin和shanghai为Redis主从分组,对应predixy.conf中的Grpoup
8001:

port 8001
sentinel monitor beijin 127.0.0.1 6001 2
sentinel monitor shanghai 127.0.0.1 7001 2

8002:

port 8002
sentinel monitor beijin 127.0.0.1 6001 2
sentinel monitor shanghai 127.0.0.1 7001 2

8003:

port 8003
sentinel monitor beijin 127.0.0.1 6001 2
sentinel monitor shanghai 127.0.0.1 7001 2

配置文件列表

启动3台sentinel

redis-server 8001.conf --sentinel
redis-server 8002.conf --sentinel
redis-server 8003.conf --sentinel

查看启动状态

3.2.4 启动2套Redis主从

mkdir 6001
mkdir 6002
mkdir 7001
mkdir 7002

分别进入4个文件夹启动对应Redis

# 6001文件夹
redis-server --port 6001
# 6002文件夹
redis-server --port 6002 --replicaof 127.0.0.1 6001
# 7001文件夹
redis-server --port 7001
# 7002文件夹
redis-server --port 7002 --replicaof 127.0.0.1 7001

查看启动进程

启动predixy

cd predixy-1.0.5/bin/
./predixy ../conf/predixy.conf 

启动日志

3.2.5 验证

  1. 验证数据存取
    客户端通过7617端口连接predixy代理,进而操作集群。
redis-cli -p 7617

通过代理服务器set k1和k2 数据,分别在2套Redis集群中查看数据分布
代理服务器

Redis主从一:beijin

Redis主从二:shanghai

  1. 验证通过代理服务器将数据存储到指定的Redis集群
    代理服务器指定将k3和k4存储到代号beijin的Redis主从,将k5和k6存储到代号shanghai主从中

beijin主从

shanghai主从

  1. 验证集群事务

发现当存在2套Redis组集群时predixy依旧不支持事务,predixy只支持单组集群下的事务。
停止predixy修改predixy.conf

vi predixy-1.0.5/conf/sentinel.conf 

修改后配置

重新启动predixy并验证

通过测试发现单组集群predixy是可以支持事务的,接下来演示Redis Cluster集群模式

3.3 Redis Cluster集群搭建

3.3.1 使用官方提供的脚本搭建Redis Cluster集群

  1. 修改配置
# 进入Redis源码目录
cd redis-6.2.6/utils/create-cluster
vi  create-cluster

修改nodes节点数量和replicas副本数量,我这使用3组 每组1主1从测试,修改后的结果

2. 启动集群

# 启动集群
./create-cluster start
# 分哈希槽
./create-cluster create

如下截图,已经将16384个slots分给3台master,并且反馈了每台master对应分得的slots编号及数量

3.3.2 手动创建集群并分配哈希槽

目前是Redis cluster 自动帮我们设置的集群信息以及分配的哈希槽,也可以手动创建和设置
手动创建集群并分配哈希槽

# 停止集群
./create-cluster stop
# 清理已分配的哈希槽信息
./create-cluster clean
# 创建集群 --cluster-replicas 1 即 1主1从
redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1


手动设置的集群哈希槽分配情况

节点 哈希槽 数量
30001 0-5460 5461
30002 5461-10922 5462
30003 10923-16383 5461

假设我们需要将30001节点的槽移动1000个到30003

# 连接Redis集群  随便集群中的哪个节点都可以
[root@q110 create-cluster]# redis-cli --cluster reshard 127.0.0.1:30001
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: 8c7f5c199ebe53e12a639ab2e8920f99f9259b78 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 2f340a56e79d2a437a54a41460c73e6f05349431 127.0.0.1:30005
   slots: (0 slots) slave
   replicates 8c7f5c199ebe53e12a639ab2e8920f99f9259b78
M: a708bb61eac6f71c3e55557fe818fa9a96045a02 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: a2dd0cd2673facab097910d99bb12ca78c4e7e31 127.0.0.1:30006
   slots: (0 slots) slave
   replicates a708bb61eac6f71c3e55557fe818fa9a96045a02
S: 0868622a962e035646be41403fcabbab6d3af022 127.0.0.1:30004
   slots: (0 slots) slave
   replicates 8c16df7dbaf6d1c70eb63f369d048744c03ae3fc
M: 8c16df7dbaf6d1c70eb63f369d048744c03ae3fc 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# 需要移动的槽数量1000
How many slots do you want to move (from 1 to 16384)? 1000
# 分配给谁节点ID?
What is the receiving node ID? 8c16df7dbaf6d1c70eb63f369d048744c03ae3fc
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
# 从哪个节点取出
Source node #1: 8c7f5c199ebe53e12a639ab2e8920f99f9259b78
# 结束
Source node #2: done

查看节点信息

redis-cli --cluster info 127.0.0.1:30001 
redis-cli --cluster check 127.0.0.1:30001 


截图中可以看出30001节点0-999共1000个槽已经移动到了30003

3.3.3 测试集群

测试数据存取
如下图,我们使用Redis-cli -p 30001连接后set k1 xxx会报错,提示set k1 需要到30003节点操作。通过redis-cli -c -p 30001连接Redis Cluster集群后 set k1 xxx会自动跳转到30003节点。

上面的截图具体原因是Redis Cluster moved重定向问题:

客户端向Redis Cluster的任意节点发送命令,接收命令的节点会根据CRC16规则进行hash运算与16384取余,计算自己的槽和对应节点;如果保存数据的槽被分配给当前节点,则去槽中执行命令,并把命令执行结果返回给客户端;如果保存数据的槽不在当前节点的管理范围内,则向客户端返回moved重定向异常;客户端接收到节点返回的结果,如果是moved异常,则从moved异常中获取目标节点的信息;客户端向目标节点发送命令,获取命令执行结果。
测试事务

127.0.0.1:30003> set k2 kkd
-> Redirected to slot [449] located at 127.0.0.1:30001
OK
127.0.0.1:30001> WATCH k1
-> Redirected to slot [12706] located at 127.0.0.1:30003
OK
127.0.0.1:30003> MULTI
OK
127.0.0.1:30003(TX)> set k2 asd
-> Redirected to slot [449] located at 127.0.0.1:30001
OK
127.0.0.1:30001> exec
(error) ERR EXEC without MULTI

报错了,原因是事务在30003节点开启,事务中我们set k2 跳转到了30001 然后提交事务在30001提交。这种情况Redis cluster 自身是不支持的,可以通过认为处理,类似的处理方式,在key前面加上固定的字符,比如下面的测试

127.0.0.1:30002> set {beijin}k2 jjjjd
OK
127.0.0.1:30002> set {beijin}k1 jjjjd
OK
127.0.0.1:30002> MULTI
OK
127.0.0.1:30002(TX)> set {beijin}k2 lajdjddda
QUEUED
127.0.0.1:30002(TX)> exec
1) OK
127.0.0.1:30002> 

至此Redis集群模式已经结束,但是实际工作中很多时候都是通过docker创建和管理集群,下一篇讲解Docker搭建Redis集群及扩容收容