1、集群介绍
1-1、含义
集群(cluster)就是一组计算机,他们作为一个整体向用户提供一组网络资源,这些单个的计算机系统就是集群的节点(node)。集群提供了以下关键的特性
- 可扩展性
- 高可用性
- 负载均衡
- 错误恢复
1-2、集群分类
- HA:高可用(Hight Availability Cluster)
- LBC:负载均衡集群 / 负载均衡系统(Load Balance Cluster)
- HPC:科学计算集群(Hight Performance Computing Cluster) / 高性能计算(Hight Performance Computing)集群
1-3、优点
- 去中心化
- 可扩展性
- 高可用性
- 自动故障转移
1-4、缺点
- 数据通过异步复制,无法保证数据强一致性
- 集群环境搭建略微复杂
2、集群架构
并发量大 -> 主从复制解决 -> 主从稳定性 -> 哨兵解决 -> 单节点存储能力 -> 集群Cluster解决
Redis Cluster 采用无中心结构,每个节点都可以保存数据和整个集群状态,每个节点都和其他所有节点连接。Cluster至少为6个才能保证组成完整高可用的集群,其中三主三从。主节点分配槽,处理客户端的命令请求,从节点可用在主节点故障,顶替主节点
因为最小的 Redis 集群,需要至少3个主节点,既然有3个主节点,而一个主节点搭配至少一个从节点。该集群中包含6个Redis几点,3主3从,分别是M1、M2、M3、S1、S2、S3。除了主从Redis节点之间进行数据复制外,所有Redis节点之间采用Gossip协议进行通信,交换维护元数据信息
简单粗暴来说就是:读请求分配给 Slave 节点,写请求分配给 Master ,数据同步从 Master 到 Slave 节点
3、数据分区方式
3-1、概述
随着请求量和数据量的增加,一台机器已经无法满足需求,我们就需要把数据和请求分散到多台机器。这时候需要引入分布式存储。分布式存储有以下特征:
- 增强可用性
- 维护方便
- 均衡I / O
- 改善查询性能
分布式存储首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集
3-2、常见分区算法
范围分区
- 优点:同一范围内的范围查询不需要跨节点,提升查询速度
- 应用场景Oracle、MySQL
节点取余分区
hash(object)% N
优点:实现简单
缺点:当扩容或收缩节点时,需要迁移的数据量大
一致性哈希分区
优点:相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其他节点无影响
缺点:当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案
应用场景:Memcached
虚拟槽分区
- 优点:每个 node 均匀的分配了 slot,缩小增减节点影响的范围
- 缺点:需要存储 node 和 slot 的对应信息
- 应用场景:Redis Cluster
4、环境搭建
IP | 节点 |
---|---|
192.168.86.135 | 6379,6380 |
192.168.86.136 | 6381,6382 |
192.168.86.137 | 6383,6384 |
# 关闭防火墙,临时关闭:systemctl stop firewalld
systemctl disable --now firewalld
systemctl disable --now dnsmasq
systemctl disable --now NetworkManager
# 关闭selinux
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
# 关闭分区
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
# 设置hosts
[root@redis-master]#
cat >> /etc/hosts << EOF
192.168.86.135 redis-master
192.168.86.136 redis-node01
192.168.86.137 redis-node02
EOF
# redis 6.x 的版本情况下执行命令
yum install -y centos-release-scl scl-utils-build
yum install -y devtoolset-9-toolchain
scl enable devtoolset-9 bash
yum install cpp binutils glibc-kernheaders glibc-common glibc-devel gcc make -y
ssh-keygen -t rsa
for i in redis-master redis-node01 redis-node02;do ssh-copy-id -i .ssh/id_rsa.pub $i;done
cd /opt
wget https://download.redis.io/releases/redis-6.2.4.tar.gz
tar xvf redis-6.2.4.tar.gz
cd redis-6.2.4 && make
mkdir -p /usr/local/redis
make PREFIX=/usr/local/redis install
mkdir -p /usr/local/redis
cd /usr/local/redis
mkdir -p /usr/local/redis/cluster/conf /usr/local/redis/cluster/data /usr/local/redis/cluster/logs
[root@redis-master cluster]# pwd
/usr/local/redis/cluster
vi conf/redis-6379.conf
# 是否以守护进程的方式启动
daemonize yes
# 默认数据库16个
databases 16
# 绑定IP
# bind 0.0.0.0
# 端口
port 6379
# 配置密码
requirepass 123456
# 从节点访问主节点密码(必须和requirepass一致)
masterauth 123456
# 设置日志路径
logfile "/usr/local/redis/cluster/logs/redis-6379.log"
# 设置存储数据路径
dir /usr/local/redis/cluster/data
# rdb 数据文件名
dbfilename dump-6379.rdb
# aof模式开启和aof数据文件名
appendonly yes
appendfilename "appendonly.aof"
# 开启集群
cluster-enabled yes
# 集群超时时间
cluster-node-timeout 15000
# 节点配置
cluster-config-file nodes-6379.conf
# 集群节点 IP
cluster-announce-ip 192.168.86.135
# 集群映射端口
cluster-announce-port 6379
# 集群节点总线端口
cluster-announce-bus-port 16379
[root@redis-master cluster]# cp conf/redis-6379.conf conf/redis-6380.conf
[root@redis-master cluster]# vi conf/redis-6380.conf
# 修改端口,命令模式 :%s/6379/6380,然后 :wq! 保存退出
[root@redis-master cluster]# scp conf/redis-6379.conf conf/redis-6380.conf redis-node01:/usr/local/redis/cluster/conf/
[root@redis-master cluster]# scp conf/redis-6379.conf conf/redis-6380.conf redis-node02:/usr/local/redis/cluster/conf/
[root@redis-node01 cluster]# mv conf/redis-6379.conf conf/redis-6381.conf
[root@redis-node01 cluster]# mv conf/redis-6380.conf conf/redis-6382.conf
[root@redis-node01 cluster]# vi conf/redis-6381.conf
# 修改端口,命令模式 :%s/6379/6381,:%s/192.168.86.135/192.168.86.136 然后 :wq! 保存退出
[root@redis-node01 cluster]# vi conf/redis-6382.conf
# 修改端口,命令模式 :%s/6380/6382,:%s/192.168.86.135/192.168.86.136 然后 :wq! 保存退出
[root@redis-node02 cluster]# mv conf/redis-6379.conf conf/redis-6383.conf
[root@redis-node02 cluster]# mv conf/redis-6380.conf conf/redis-6384.conf
[root@redis-node02 cluster]# vi conf/redis-6383.conf
# 修改端口,命令模式 :%s/6379/6383,:%s/192.168.86.135/192.168.86.137 然后 :wq! 保存退出
[root@redis-node02 cluster]# vi conf/redis-6384.conf
# 修改端口,命令模式 :%s/6380/6384,:%s/192.168.86.135/192.168.86.137 然后 :wq! 保存退出
[root@redis-master redis]# pwd
/usr/local/redis
[root@redis-master redis]# ./bin/redis-server cluster/conf/redis-6379.conf
[root@redis-master redis]# ./bin/redis-server cluster/conf/redis-6380.conf
[root@redis-node01 redis]# pwd
/usr/local/redis
[root@redis-node01 redis]# ./bin/redis-server cluster/conf/redis-6381.conf
[root@redis-node01 redis]# ./bin/redis-server cluster/conf/redis-6382.conf
[root@redis-node02 redis]# pwd
/usr/local/redis
[root@redis-node02 redis]# ./bin/redis-server cluster/conf/redis-6383.conf
[root@redis-node02 redis]# ./bin/redis-server cluster/conf/redis-6384.conf
# 集群帮助命令
./bin/redis-cli --cluster help
# 随便一个节点:创建集群
./bin/redis-cli -a 123456 --cluster create \
192.168.86.135:6379 192.168.86.135:6380 \
192.168.86.136:6381 192.168.86.136:6382 \
192.168.86.137:6383 192.168.86.137:6384 \
--cluster-replicas 1
...
Can I set the above configuration? (type 'yes' to accept): yes
...
M: a5aa2e356508ee76d1c75739f8f6434f87a903e6 192.168.86.135:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: fe5e55b629c28ac66ff1d2859744cae33c50f586 192.168.86.136:6383
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: b9545b0f83ae0ef7a78bf8d5dab63189cb9172c5 192.168.86.137:6381
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 8ad5630f8183909508e2251487e2d2975e684400 192.168.86.135:6380
slots: (0 slots) slave
replicates fe5e55b629c28ac66ff1d2859744cae33c50f586
S: 6feb528fb01e366d6830dca2715b7cb54121bb08 192.168.86.137:6382
slots: (0 slots) slave
replicates a5aa2e356508ee76d1c75739f8f6434f87a903e6
S: 2cebb091fc9563e602d38d52e2aff7695e9ba5dc 192.168.86.136:6384
slots: (0 slots) slave
replicates b9545b0f83ae0ef7a78bf8d5dab63189cb9172c5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
./bin/redis-cli -a 123456 --cluster check 192.168.86.135:6379
./bin/redis-cli -c -a 123456 -h 192.168.86.135 -p 6379 cluster info
./bin/redis-cli -c -a 123456 -h 192.168.86.135 -p 6379 cluster nodes
./bin/redis-cli -c -a 123456 -h 192.168.86.135 -p 6380 readonly
# 只允许从节点,如果操作在主节点上就会报错
./bin/redis-cli -c -a 123456 -h 192.168.86.137 -p 6384 cluster failover
# 将新的 6385 节点加入了 192.168.86.135:6381 主节点中
[root@redis-master redis]#
./bin/redis-cli -a 123456 \
--cluster add-node 192.168.86.138:6385 192.168.86.136:6381 \
--cluster-master-id b9545b0f83ae0ef7a78bf8d5dab63189cb9172c5
# 分配槽slots:把 6381 的槽分 1024 个槽给 新加入节点 6385 的槽中
# reshard:表示连接IP:host
# --cluster-from:表示slot目前所在的节点的node ID,多个ID用逗号分隔
# --cluster-to:表示需要新分配节点的node ID(貌似每次只能分配一个)
# --cluster-slots:分配的slot数量
[root@redis-master redis]#
./bin/redis-cli -a 123456 \
--cluster reshard 192.168.86.135:6379 \
--cluster-from b9545b0f83ae0ef7a78bf8d5dab63189cb9172c5, ...... \
--cluster-to 31940458ecc5becade331e89faa254197d812c9a \
--cluster-slots 1024 --cluster-yes
把 6386 作为 6385 的slave节点
[root@redis-master redis]#
./bin/redis-cli -a 123456 \
--cluster add-node 192.168.86.139:6386 192.168.86.138:6385 \
--cluster-slave --cluster-master-id 31940458ecc5becade331e89faa254197d812c9a
把 6386 作为 6385 的slave节点
[root@redis-master redis]#
./bin/redis-cli -a 123456 \
--cluster del-node 192.168.86.139:6386 88f148d854b4552e60f96681d902591691178ff6
# 方式1:把要删除的主节点的槽先分配给其他主节点后再删
[root@redis-master redis]#
./bin/redis-cli -a 123456 \
--cluster reshard 192.168.86.135:6379 \
--cluster-from 31940458ecc5becade331e89faa254197d812c9a \
--cluster-to b9545b0f83ae0ef7a78bf8d5dab63189cb9172c5 \
--cluster-slots 1024 --cluster-yes
./bin/redis-cli -a 123456 、
--cluster del-node 192.168.86.138:6385 31940458ecc5becade331e89faa254197d812c9a