本章重点
-
集群
一、Redis集群
1.1 背景
前面我们学习了Redis高可用的两种架构模式:主从模式、哨兵模式。
-
主从复制:单点故障、读写分离(主负责写,从负责读)、负载均衡(客户端请求,并发)
-
问题:不能自动故障转移(哨兵)、主从数据是完全一致(集群)
-
-
哨兵机制:故障转移(解决主从复制的问题,主机出现故障,从切换为主)
RedisCluster是redis的分布式解决方案,当主备复制场景,无法满足主机的单点故障时,需要引入集群配置,当一个服务挂了可以快速的切换到另外一个服务,当遇到单机内存、并发等瓶颈时,可使用此方案来解决这些问题。
1.2 什么是集群
由于数据量过大,单个Master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点间共享数据的程序集。
Redis集群是一种通过将多个Redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。它允许Redis在不同节点上同时提供服务,提高整体性能和可靠性。
Redis集群主要有三种模式:主从复制模式(Master-Slave)、哨兵模式(Sentinel)、Cluster模式。
-
广义的集群:只要是多台机器,构成一个分布式系统,就可以称为一个“集群”。主从结构,哨兵模式都是“广义的集群”
-
狭义的集群:redis提供的集群模式,这个集群模式主要解决存储空间不足的问题
1.3 Redis Cluster功能
-
数据自动分片
集群中每个节点都会负责一定数量的slot,每个key会映射到一个具体的slot,通过这种方式就可能找到key具体保存在哪个节点上了。
-
提供hash tags功能
通过hash tag功能可以将多个不同key映射到同一个slot上,这样就能够提供multi-key操作,hash tag的使用的方式是在key中包含“{}”,这样只有在“{...}”中字串被用于hash计算。
-
自动失效转移和手动失效转移
-
减少硬件成本和运维成本
1.4 Cluster 实现原理
分布式数据库
就把整个数据按分区规则映射到多个数据库节点,即把数据划分到多个节点上,每个节点负责整体数据的一个子集。比如我们库有900条用户数据,有3个redis节点,将900条分成3份,分别存入到3个redis节点
900-->一个数据库
900-->多个数据库
分区规则
常见的分区规则哈希分区和顺序分区,redis集群使用了哈希分区的“虚拟槽分区”方式。
虚拟槽分区(槽:slot)
数据:key-value
数据库:key值关联
RedisCluster采用此分区,所有的键根据哈希函数映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据。
槽与节点的关系如下:
redis用虚拟槽分区使解耦数据与Redis数据库节点关系,节点自身维护槽映射关系,分布式存储。
redisCluster的缺陷
执行数据库操作时,一次操作,只能连接一个数据库
1) 键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了
2) 键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务
3) 键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
4) 不支持多数据库
5) 复制结构只支持单层结构,不支持树型结构。
二、集群环境搭建
2.1 创建集群节点
创建目录redisCluster
模拟6个节点服务
2.2 复制并修改节点主配置文件
复制的配置文件做以下修改,以下以6379为例:
1 | port 6379 | 端口号 |
---|---|---|
2 | daemonize yes | 让redis服务在后台启动 |
3 | pidfile /var/run/redis_6379.pid | Pidfile 文件中的端口号修改为本节点端口号 |
4 | cluster-enabled yes | 把#注释去掉, 开启集群 |
5 | cluster-config-file nodes_6379.conf | 把#注释去掉,集群的配置,配置文件首次启动自动生成 |
6 | cluster-node-timeout 15000 | 把#注释去掉,请求的超时时间,默认15秒,可自行设置 |
7 | appendonly yes | 开启aof日志aof 和rdb是redis同步内存中的数据到硬盘的两种方式 |
8 | Appendfilename "appendonly_6379.aof" | |
9 | protected-mode no | 关闭保护模式 |
注意::%s/6379/6380/g可以进行全局替换
2.3 启动服务
启动各个节点的服务
./redis-server redisCluster/6379.conf ./redis-server redisCluster/6389.conf ./redis-server redisCluster/6380.conf ./redis-server redisCluster/6390.conf ./redis-server redisCluster/6381.conf ./redis-server redisCluster/6391.conf
启动好之后,执行ps -ef |grep redis检查各节点启动状态:
2.4 创建集群常用命令
三主三从
-
192.168.190.128:6370(主)192.168.190.128:6371(从)
-
192.168.190.128:6380(主)192.168.190.128:6381(从)
-
192.168.190.128:6390(主)192.168.190.128:6391(从)
2.4.1 创建主节点
先创建主节点,不创建从节点,从节点之后使用命令添加(可以自己声明主从关系)
./redis-cli --cluster create 192.168.190.129:6379 192.168.190.129:6371 192.168.190.129:6372 # 带密码 ./redis-cli -a 密码 --cluster create 192.168.190.130:6380 192.168.190.130:6381 192.168.190.130:6382 192.168.190.130:6484
创建主节点和从节点,自动分配主从关系
# --cluster-replicas:从节点个数 ./redis-cli --cluster create --cluster-replicas 1 -a 123 192.168.190.128:6460 192.168.190.128:6470 192.168.190.128:6480 192.168.190.128:6461 192.168.190.128:6471 192.168.190.128:6481
2.4.2 添加主节点
./redis-cli --cluster add-node 192.168.190.128:6385(新的主节点) 192.168.190.130:6380(集群中的任意一个主节点) ./redis-cli --cluster add-node 192.168.190.128:6490 192.168.190.128:6380
2.4.3 添加从节点
./redis-cli --cluster add-node 从节点 主节点 --cluster-slave --cluster-master-id 主节点id ./redis-cli --cluster add-node 192.168.190.128:6491 192.168.190.128:6460 --cluster-slave --cluster-master-id 2cb8cd707d8bdd643bf4da7091cb576c9f81a51c
2.5 测试
2.5.1 创建集群
执行命令,创建主从节点:
./redis-cli --cluster create -a 密码 192.168.31.128:6379 192.168.31.128:6380 192.168.31.128:6381 192.168.31.128:6382 192.168.31.128:6373 192.168.31.128:6383 --cluster-replicas 1
2.5.2 查看节点信息
主从分配,6379是6389的主节点,6380是6390的主节点,6381是6391的主节点
cluster nodes
-
连入redis集群并设置值
./redis-cli -h 192.168.153.133 -p 6379 -c
可以看到设置name以后,重定向到了6380的这个redis,这时因为键name经过CRC16[k]&16284虚拟槽分区算法以后落到了6380这个节点,所以数据就存到了6380这个redis节点
切回6379获取name的值也会通过同样的算法重定向到6380
2.5.3 设置密码
在每个redis.conf里加上
masterauth "123" requirepass "123"
当主节点下线时,从节点会变成主节点,用户和密码是很有必要的,设置成一致
2.6 集群操作
2.6.1 查看集群
客户端连接redis,查看集群节点信息
# 查看集群内所有节点的相关信息 cluster nodes # 查看集群信息 cluster info
不连接,直接查看
redis-cli --cluster check 192.168.153.128:6390
key值操作
# 计算键 key 应该被放置在哪个槽上。 CLUSTER KEYSLOT <key> # 返回槽 slot 目前包含的键值对数量。 CLUSTER COUNTKEYSINSLOT <slot>
2.6.2 改变从节点的master
# 新master的node id cluster replicate 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052
2.6.3 查看集群key、slot、slave分布信息
redis-cli --cluster info 192.168.153.128:6390 或者 redis-cli --cluster check 192.168.153.128:6390
2.6.4 在线迁移槽
自动迁移,根据提示信息做槽点迁移
redis-cli --cluster reshard 192.168.190.128:6393(集群中的节点)
命令参数手动迁移
./redis-cli --cluster reshard 192.168.190.128:6470 --cluster-from 2cb8cd707d8bdd643bf4da7091cb576c9f81a51c --cluster-to 4ca484733192cd371e6b731643ea713bfa5f7b7e --cluster-slots 4096 --cluster-yes
2.6.5 平衡各节点槽数量
redis-cli --cluster rebalance --cluster-threshold 1 192.168.190.128:6480
平衡前
平衡槽点数
2.6.6 删除集群节点
redis-cli --cluster del-node 192.168.153.128:6390 (pid)
删除之后节点会自动shutdown,无法再次直接添加到集群中
启动之后,先连接到当前节点,执行
cluster reset
这里必须是没有槽的节点,所以必须先移除槽,否则报如下错误
通过reshard迁移走槽后,删除成功,并且关闭了该节点
被删除的node重启后,依然记得集群中的其它节点,这是需要执行cluster forget nodeid
来忘记其它节点。
2.6.7 删除集群配置
删除所有的nodes-*文件,appendonly**.aof文件
rm -f ./*/nodes-*.conf ./*/appendonly*.aof ./*/dump.rdb