Redis 集群的实现方法一般有客户端分片、代理分片和服务器端分片三种解决方案
目录
2:修改配置文件(每个节点都要配置,只有IP地址不同,其他都相同)
一:Redis 集群方式
Redis 有三种模式:分别是主从复制、哨兵式、Cluster
主从复制
- 主从复制是高可用 edis 的基础,哨兵和群集都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单故障恢复
- 缺陷:故障恢复无法自动化,写操作无法负载均衡,存储能力受到单机的限制
优点 | 缺点 |
1、解决数据备份问题 2、做到读写分离,提高服务器性能 | 1、master 故障,无法自动故障转移需人工介入 2、master 无法实现动态扩容 |
哨兵模式
- 在主从复制的基础上,哨兵实现了自动化的故障恢复
- 缺陷:写操作无法负载均衡,存储能力受到单机的限制,哨兵无法对从节点进行自动故障转移;在读写分离场景下,从节点故障会导致读服务不可用,需要对从节点做额外的监控、切换操作
优点 | 缺点 |
1、Master 状态监测 2、master 节点故障,自动切换主从,故障自愈 3、所有 slave 从节点,随之更改新的master 节点 | 1、slave 节点下线,sentinel 不会对一进行故障转移,连接从节点的客户端因为无法获取到新的可用从节点 2、master 无法实行动态扩容 |
集群模式(Redis-Cluster)
- 通过集群,Redis 解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案
- 支持 Redis 分布式集群部署模式,采用无中心分布式架构。所有的 Redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽。节点的 fai1 是通过集群中超过半数的节点检测失败时才生效。客户端与 Redis 节点直连,不需要中间代理层。客户端也不需要连接集群所有节点,连接集群中任何一个可用节点即可,这样即减少了代理层,也大大提高了 Redis 集群性能
优点 | 缺点 |
1、有效的解决了 redis 在分布式方面的需求 2、遇到单机内存,并发和流量瓶颈等问题时,可采用cluster方案达到负载均衡的目的 3、可实现动态扩容 4、P2P 模式,无中心化 5、通过 Gossip 协议同步节点信息 6、自动故障转移、slot 迁移中数据可用 7、自动分割数据到不同的节点上 8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令 | 1、架构比较新,最佳实践较少 2、为了性能提升,客户端需要缓存路由表信息 3、节点发现、reshard 操作不够自动T 4、不支持处理多个 keys 的命令,因为这需要在不同的节点间移动数据 5、Redis 集群不像单机 Redis 那样支持多数据库功能,集群只使用默认的0号数据库,并且不能使用SELECT index 命令 |
二、数据分片方式
Redis cluster 通过哈希算法将数据分散到多个节点上,实现数据的分片。每个节点负责管理一部分数据,并提供相应的读写操作。分片机制可以将数据均匀地分布在多个节点上,提高系统的并发处理能力
分片方式有客户端分片、代理分片和Twemproxy 代理分片机制
客户端分片
- 客户端分片方案是将分片工作放在业务程序端。程序代码根据预先设置的路由规则,直接对多个Redis 实例进行分布式访问
- 这种分片机制的性能比代理式更好(少了一个中间分发环节),但缺点是升级麻烦,对研发人员的个人依赖性强,需要有较强的程序开发能力做后盾
代理分片
- 代理分片方案是将分片工作交给专门的代理程序来做。代理程序接收到来自业务程序的数据请求,根据路由规则,将这些请求分发给正确的 Redis 实例并返回给业务程序
- Twemproxy 是一种代理分片机制,由 Twitter 开源。Twemproxy 作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个 Redis 服务器,再原路返回
- 当然 Twemproxy 本身也是单点,需要用 Keepalived 做高可用方案
- Codis 由豌豆英于 2014 年 11 月开源,基于 Go 语言和 c 语言开发,从各种压力测试来看,codis 的稳定性符合高效运维的要求
- Codis 引入了 Group 的概念,每个 Group 包括1个 Redis Master 及至少1个 Redisslave,这是和 Twemproxy 的区别之一
服务器分片
- 服务器端分片是 Redis 官方的集群分片技术。Redis-cluster 将所有 Key 映射到 16384个 slot中,集群中每个 Redis 实例负责一部分,业务程序是通过集成的 Redis-cluster 客户端进行操作
- 负载均衡的实现
- 客户端路由:在 Redis cluster中,客户端需要根据数据的键名选择正确的节点进行读写操作。RedisCluster 使用哈希槽(hash slot)来划分数据,并将每个哈希槽映射到相应的节点上
- 自动迁移: Rediscluster 具有自动迁移功能,当节点加入或离开集群时,系统会自动重新分配数据,保持各个节点上哈希槽的均衡,当节点加入集群时,系统会将一部分哈希槽从其他节点迁移到新节点上;当节点离开集群时,系统会将该节点上的哈希槽重新分配给其他节点
- 故障检测与恢复: Redis cluster 具有故障检测和自动恢复的机制。集群中的节点会相互监控,检测节点的健康状态;当某个节点被检测到不可用时,系统会自动将该节点标记为下线,并将该节点上的哈希槽重新分配给其他节点。当节点恢复正常时,系统会将其重新加入集群,并进行数据迁移,保持数据的-致性
三、故障处理
故障转移
- 当从节点发现自己的主节点变为已下线(FAIL)状态时,便尝试进 Failover,以期成为新的主
- 从下线主节点的所有从节点中选中一个从节点
- 被选中的从节点执行SLAVEOF NO NOE 命令,成为新的主节点
- 新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己(4)新的主节点对集群进行广播 PONG 消息,告知其他节点已经成为新的主节点
- 新的主节点开始接收和处理槽相关的请求
- 集群slots 是否必须完整才能对外提供服务
多slave选举
- 在多个 slave 情况下如果一个master 宕机,需要基于 Raft 协议选举方式来实现的新主的选举
- CLUSTERMSG_TYPE_FAILOVER_AUTH_REOUEST 消息,要求所有收到这条消息,并且具有投票权的主节点向这个从节点投票
- 如果一个主节点具有投票权,并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条,CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 消息,表示这个主节点支持从节点成为新的主节点
- 每个参与选举的从节点都会接收 CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持
- 如果集群里有N个具有投票权的主节点,那么当一个从节点收集到大于等于集群 N/2+1 张支持票时,这个从节点就成为新的主节点
- 如果在一个选举周期没有从能够收集到足够的支持票数,那么集群进入一个新的选举周期,并再次进行选主,直到选出新的主节点为止
四、Redis群集部署
1:安装redis(每个节点都要安装)
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# yum -y install gcc* zlib-devel
[root@localhost ~]# tar xvzf redis-5.0.14.tar.gz
[root@localhost ~]# cd redis-5.0.14/
[root@localhost redis-5.0.14]# make
[root@localhost redis-5.0.14]# make PREFIX=/usr/local/redis install
[root@localhost ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/
[root@localhost redis-5.0.14]# cd /root/redis-5.0.14/utils/
[root@localhost utils]# ./install_server.sh
2:修改配置文件(每个节点都要配置,只有IP地址不同,其他都相同)
[root@localhost ~]# vim /etc/redis/6379.conf
bind 0.0.0.0 ##62行
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis_6379.log
appendonly yes ##开启 aof 持久化
......
cluster-enabled yes ##去掉注释符,表示启用群集;开启Cluster
cluster-config-file nodes-6379.conf ##去掉注释
cluster-node-timeout 15000 ##去掉注释;集群超时时间:cluster-node-timeout 15000。结点超时多久则认为它宕机了
cluster-require-full-coverage no ##去掉注释,将yes改为no;槽是否全覆盖:cluster-require-full-coverage no。默认是yes,只要有结点宕机导致16384个槽没全被覆盖,整个集群就全部停止服务,所以一定要改为no
[root@localhost ~]# /etc/init.d/redis_6379 restart
[root@localhost ~]# netstat -anpt | grep 6379
3:创建redis群集
redis-cli --cluster create --cluster-replicas 1 192.168.10.101:6379 192.168.10.102:6379 192.168.10.103:6379 192.168.10.104:6379
192.168.10.105:6379 192.168.10.106:6379
##replicas:副本数(1);创建好后可以记住ID
4:测试群集
[root@localhost ~]# redis-cli -h 192.168.10.106 -p 6379 -c
192.168.10.106:6379> set centos 7.3
192.168.10.106:6379> get centos
192.168.10.106:6379> quit
[root@localhost ~]# redis-cli -h 192.168.10.105 -p 6379 -c
192.168.10.105:6379> get centos
192.168.10.105:6379> quit
192.168.10.102:6379> cluster nodes ##可以查看集群状态
9e138e60469a83232bc217423f75aabd7297ae8a 192.168.10.102:6379@16379 master - 0 1723447674457 2 connected 5461-10922
02abd42ae37aa416b5bf876b4d24bc42ab900b8e 192.168.10.101:6379@16379 myself,master - 0 1723447672000 1 connected 0-5460
ea675c88d9646cfaed538dcd9df9ad04f1a558e4 192.168.10.104:6379@16379 slave 61a0460bbc43b55c45e7aaa5897405490b3d37ce 0 1723447673000 4 connected
f42459c093e42063abe20c810527d79e4703b3de 192.168.10.106:6379@16379 slave 9e138e60469a83232bc217423f75aabd7297ae8a 0 1723447673451 6 connected
8e5db37e0cf6eab979aaa36d034abce7f18da18f 192.168.10.105:6379@16379 slave 02abd42ae37aa416b5bf876b4d24bc42ab900b8e 0 1723447672438 5 connected
61a0460bbc43b55c45e7aaa5897405490b3d37ce 192.168.10.103:6379@16379 master - 0 1723447671000 3 connected 10923-16383
5:为现有的群集添加节点(master)
[root@localhost ~]# redis-cli -c -p 6379 cluster meet 192.168.10.107 6379 ##为集群添加节点
[root@localhost ~]# redis-cli --cluster add-node 192.168.10.108:6379 192.168.10.107:6379 ##另一种方法,需要一个节点同意
//改造一个master节点
[root@localhost ~]# redis-cli -h 192.168.10.108 -p 6379
192.168.10.108:6379> cluster nodes ##找到107的ID
192.168.10.108:6379> cluster replicate 107的ID
[root@localhost ~]# redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 192.168.10.101:6379 ##分发槽位
6:为现有的群集删除节点
[root@localhost ~]# redis-cli -h 192.168.10.107 -p 6379 ##需要把被占用的节点槽清除
192.168.10.107:6379> flushall
192.168.10.107:6379> cluster reset
[root@localhost ~]# redis-cli --cluster del-node 192.168.10.101:6379 107的ID ##删除后这个主节点的从节点就成其他主节点的从
标签:NoSQL,redis,Redis,192.168,6379,集群,分片,节点
From: https://blog.csdn.net/minly12/article/details/141137616