Redis集群
集群概述
- 所谓集群,就是通过添加服务器的数量,提供相同的服务,从而让服务器达到一个稳定、高效的状态
- 单个redis存在不稳定性。当redis服务宕机了,就没有可用的服务了
- 单个redis的读写能力是有限的
- Redis集群是为了强化redis的读写能力
- redis集群中,每一个redis称之为一个节点
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽
- 节点的fail是通过集群中超过半数的节点检测失效时才生效
- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
- redis集群中,有两种类型的节点:主节点(master)、从节点(slave)
- redis集群,是基于redis主从复制实现
- 主从复制模型中,有多个redis节点
- 其中,有且仅有一个为主节点Master。从节点Slave可以有多个
- 只要网络连接正常,Master会一直将自己的数据更新同步给Slaves,保持主从同步
- 主节点Master可读、可写
- 从节点Slave只读
部署Redis集群
基本原理
-
集群中至少应该有奇数个节点,所以至少有三个节点,每个节点至少有一个备份节点
-
架构图
graph LR
c(Client:192.168.1.10)--访问-->redis1
m(Manager:192.168.1.20)--管理-->redis2
subgraph Cluster
redis1(redis1:192.168.1.11)
redis2(redis2:192.168.1.12)
redis3(redis3:192.168.1.13)
redis4(redis4:192.168.1.14)
redis5(redis5:192.168.1.15)
redis6(redis6:192.168.1.16)
end
style m fill:lightgreen
style c fill:lightblue
- 存储结构

images
- redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value
- Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。
配置管理主机
- 在管理主机manager1(192.168.1.20)上配置脚本运行环境
[root@manager1 ~]# yum install -y rubygems
# 把教学环境提供的redis-3.2.1.gem文件拷贝到manager1上,并安装
[root@manager1 ~]# gem install redis-3.2.1.gem
- 部署集群管理脚本
[root@manager1 ~]# tar xf redis-4.0.8.tar.gz
[root@manager1 ~]# cp redis-4.0.8/src/redis-trib.rb /usr/local/bin/
[root@manager1 ~]# chmod +x /usr/local/bin/redis-trib.rb
# 查看帮助
[root@manager1 ~]# redis-trib.rb help
创建集群
- 启动redis1的集群功能
# 停止服务
[root@redis1 ~]# service redis_6379 stop
Stopping ...
Redis stopped
# 修改配置文件
[root@redis1 ~]# vim /etc/redis/6379.conf
protected-mode no # 关闭保护模式,以允许不使用密码、不指定绑定地址提供服务
# bind 127.0.0.1 # 注释掉,以监听在全部地址
# requirepass tedu.cn # 不使用密码
cluster-enabled yes # 启用集群功能
cluster-config-file nodes-6379.conf # 集群配置文件位置
cluster-node-timeout 5000 # 心跳时间
# 清空原有数据
[root@redis1 ~]# rm -rf /var/lib/redis/6379/*
# 修改服务启动文件
[root@redis1 ~]# vim +43 /etc/init.d/redis_6379
... ...
$CLIEXEC -p $REDISPORT shutdown
... ...
# 启动服务
[root@redis1 ~]# service redis_6379 start
Starting Redis server...
# 查看端口,集群服务运行在16379端口上
[root@redis1 ~]# ss -tlnp | grep redis
LISTEN 0 128 *:16379 *:* users:(("redis-server",pid=18952,fd=10))
LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=18952,fd=7))
LISTEN 0 128 [::]:16379 [::]:* users:(("redis-server",pid=18952,fd=9))
LISTEN 0 128 [::]:6379 [::]:* users:(("redis-server",pid=18952,fd=6))
- 配置redis2、redis3、redis4、redis5、redis6的集群功能
# 为了操作方便,可以配置redis1到其他节点的免密登陆
[root@redis1 ~]# ssh-keygen
[root@redis1 ~]# for i in {12..16}
> do
> ssh-copy-id 192.168.1.$i
> done
# 将redis1上编译好的redis拷贝到其他主机
[root@redis1 ~]# for i in 1{2..6}
> do
> scp -r /usr/local/redis 192.168.1.$i:/usr/local/
> done
# 在redis2、redis3、redis4、redis5、redis6上,将redis命令目录添加至PATH环境变量
[root@redis1 ~]# for i in 1{2..6}; do ssh 192.168.1.$i "echo 'export PATH=$PATH:/usr/local/redis/bin' >> /etc/bashrc"; done
# 将redis1上源码目录拷贝到其他主机
[root@redis1 ~]# for i in 1{2..6}; do scp -r redis-4.0.8/ 192.168.1.$i:/root/; done
# 分别在redis2、redis3、redis4、redis5、redis6上执行初始化服务器脚本
[root@nodeX ~]# cd redis-4.0.8/
[root@nodeX redis-4.0.8]# utils/install_server.sh
# 停止redis2、redis3、redis4、redis5、redis6上的redis服务
[root@redis1 ~]# for i in 1{2..6}; do ssh 192.168.1.$i service redis_6379 stop; done
# 拷贝redis1的配置文件到redis2、redis3、redis4、redis5、redis6
[root@redis1 ~]# for i in 1{2..6}; do scp /etc/redis/6379.conf 192.168.1.$i:/etc/redis/; done
# 清除各主机上的数据
[root@redis1 ~]# for i in 1{2..6}; do ssh 192.168.1.$i rm -rf /var/lib/redis/6379/*; done
# 启动redis2、redis3、redis4、redis5、redis6上的redis服务
[root@redis1 ~]# for i in 1{2..6}; do ssh 192.168.1.$i service redis_6379 start; done
- 在管理主机manager1上创建集群
[root@manager1 ~]# redis-trib.rb create --replicas 1 \
> 192.168.1.11:6379 192.168.1.12:6379 192.168.1.13:6379 \
> 192.168.1.14:6379 192.168.1.15:6379 192.168.1.16:6379
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.1.11:6379
192.168.1.12:6379
192.168.1.13:6379
Adding replica 192.168.1.15:6379 to 192.168.1.11:6379
Adding replica 192.168.1.16:6379 to 192.168.1.12:6379
Adding replica 192.168.1.14:6379 to 192.168.1.13:6379
M: b1b8e906ea2c7b71e567485f02d0007ad902a5c5 192.168.1.11:6379
slots:0-5460 (5461 slots) master
M: 7cd1b4dc246c4c11780be1186f118ce79794d182 192.168.1.12:6379
slots:5461-10922 (5462 slots) master
M: 3dd1687f4c9d37a4bc095705a2ab0a35b27b59cc 192.168.1.13:6379
slots:10923-16383 (5461 slots) master
S: c85a2a1474dea3fbf4ac4073c437b8eada04b806 192.168.1.14:6379
replicates 3dd1687f4c9d37a4bc095705a2ab0a35b27b59cc
S: a49746ee742866f0db4cebbc2de17733c0ace5b8 192.168.1.15:6379
replicates b1b8e906ea2c7b71e567485f02d0007ad902a5c5
S: 3c0b9fe153392132003c9707d5132647b59031d4 192.168.1.16:6379
replicates 7cd1b4dc246c4c11780be1186f118ce79794d182
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 192.168.1.11:6379)
M: b1b8e906ea2c7b71e567485f02d0007ad902a5c5 192.168.1.11:6379
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 3dd1687f4c9d37a4bc095705a2ab0a35b27b59cc 192.168.1.13:6379
slots:10923-16383 (5461 slots) master
1 additional replica(s)
M: 7cd1b4dc246c4c11780be1186f118ce79794d182 192.168.1.12:6379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: a49746ee742866f0db4cebbc2de17733c0ace5b8 192.168.1.15:6379
slots: (0 slots) slave
replicates b1b8e906ea2c7b71e567485f02d0007ad902a5c5
S: c85a2a1474dea3fbf4ac4073c437b8eada04b806 192.168.1.14:6379
slots: (