Redis(集群-----主从同步,如何缓存python,高可用--哨兵、Cluster,数据迁移,维护,codis集群扩展 )

redis 高可用与集群

虽然 Redis 可以实现单机的数据持久化,但无论是 RDB 也好或者 AOF 也好,都解决不了单点宕机问题,即一旦 redis 服务器本身出现系统故障、硬件故障等问题后,就会直接造成数据的丢失。

一. 配置 reids 主从(手动)

当master出错—>手动的将slave提升为主(没有高可用

主备模式,可以实现 Redis 数据的跨主机备份。程序端连接到高可用负载的 VIP,然后连接到负载服务器设置的 Redis 后端 real server,此模式不需要在程序里面配置 Redis 服务器的真实 IP 地址,当后期 Redis 服务器 IP 地址发生变更只需要更改 redis 相应的后端 real server 即可,可避免更改程序中的 IP 地址设置。
在这里插入图片描述

Slave 主要配置

Redis Slave 也要开启持久化并设置和 master 同样的连接密码,因为后期 slave 会有提升为 master 的可能,Slave 端切换 master 同步后会丢失之前的所有数据(slave)。(手动切换

一旦某个 Slave 成为一个 master 的 slave,Redis Slave 服务会清空当前 redis 服务器上的所有数据并将master 的数据导入到自己的内存,但是断开同步关系后不会删除当前已经同步过的数据。

命令行配置

192.168.245.73:6379> slaveof 192.168.7.103 6379
OK
192.168.245.73:6379> CONFIG SET masterauth 123456
OK

在这里插入图片描述

永久配置到 redis.conf:
在slave中

replicaof 192.168.7.103 6379
masterauth 123456 #master 如果密码需要设置

在这里插入图片描述
slave 状态只读无法写入数据

Master 日志

在这里插入图片描述

主从复制过程

Redis 支持主从复制分为全量同步和增量同步首次同步是全量同步

redis 的主从同步是非阻塞的,其收到从服务器的 sync命令会fork 一个子进程在后台执行 bgsave 命令,并将新写入的数据写入到一个缓冲区里面,
bgsave 执行完成之后并生成的将 RDB 文件发送给客户端,客户端将收到后的 RDB 文件载入自己的内存,然后主 redis将缓冲区的内容在全部发送给从 redis,之后的同步从服务器会发送一个 offset 的位置(等同于 MySQL的 binlog 的位置)给主服务器,主服务器检查后位置没有错误将此位置之后的数据包括写在缓冲区的积压数据发送给 redis 从服务器,从服务器将主服务器发送的挤压数据写入内存,这样一次完整的数据同步,再之后再同步的时候从服务器只要发送当前的 offset 位 置给主服务器,然后主服务器根据响应的位置将之后的数据发送给从服务器保存到其内存即可。

Redis 全量复制一般发生在 Slave 初始化阶段,这时 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:
1)从服务器连接主服务器,发送 SYNC 命令;
2)主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 快照文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
7)后期同步会先发送自己 slave_repl_offset 位置,只同步新增加的数据,不再全量同步。
在这里插入图片描述

主从同步优化

Redis 在 2.8 版本之前没有提供增量部分复制的功能,当网络闪断或者 slave Redis 重启之后会导致主从之间的全量同步,即从 2.8 版本开始增加了部分复制的功能。

repl-diskless-sync yes#yes 为支持 disk,master 将 RDB 文件先保存到磁盘在发送给 slave,
no 为 maste直接将 RDB 文件发送给 slave,默认即为使用 no,Master RDB 文件不需要与磁盘交互。

repl-diskless-sync-delay 5 #Master 准备好 RDB 文件后等等待传输时间
repl-ping-slave-period 10 #slave 端向 server 端发送 ping 的时间区间设置,默认为 10 秒
repl-timeout 60 #设置超时时间
repl-disable-tcp-nodelay no #是否启用 TCP_NODELAY,如设置成 yes,则 redis 会合并小的 TCP 包从而节省带宽,但会增加同步延迟(40ms),造成 master 与 slave 数据不一致,假如设置成 no,则 redis master会立即发送同步数据,没有延迟,前者关注性能,后者关注一致性
repl-backlog-size 1mb #master 的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:b repl-backlog-size = 允许从节点最大中断时长 * 主实例 offset 每秒写入量,比如 master 每秒最大写入 64mb,最大允许 60 秒,那么就要设置为 64mb*60 秒=3840mb(3.8G)=
repl-backlog-ttl 3600 #如果一段时间后没有 slave 连接到master,则 backlog size 的内存将会被释放。如果值为 0 则表示永远不释放这部份内存。
slave-priority 100 #slave 端的优先级设置,值是一个整数,数字越小表示优先级越高。当 master 故障时将会按照优先级来选择 slave 端进行恢复,如果值设置为 0,则表示该 slave 永远不会被选择。
#min-slaves-to-write 0 #
min-slaves-max-lag 10 #设置当一个 master 端的可用 slave 少于 N 个,延迟时间大于 M 秒时,不接收写操作。
Master 的重启会导致 master_replid 发生变化,slave 之前的 master_replid 就和 master 不一致从而会引发所有 slave 的全量同步。

slave同步过程
在这里插入图片描述
master 同步日志:

在这里插入图片描述

手动将slave切换为master

当前状态:

192.168.7.101:6379> info Replication
# Replication
role:slave
master_host:192.168.7.103
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0

停止 slave 同步并查看当前状态

192.168.7.101:6379> SLAVEOF no one
OK
192.168.7.101:6379> info Replication
# Replication
role:master
connected_slaves:0
master_replid:ac3475e5e4fae8c5f47711a643e465b9520c4182
master_replid2:8ee6bc1ac452fd4d2ccbaa660a219f78d218399a
master_repl_offset:8840
second_repl_offset:8841
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:8547
repl_backlog_histlen:294

然后在配置文件中注释掉
在这里插入图片描述

测试能否写入数据

192.168.7.101:6379> set key1 value1
OK
192.168.7.101:6379>

Slave 节点再有 Slave

在这里插入图片描述
在有 slave 的”master”查看状态

# Replication
role:slave
master_host:192.168.7.102
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9  #最近一次与 master 通信已经过去多少秒。
master_sync_in_progress:0 #是否正在与 master 通信。
slave_repl_offset:5334 #当前同步的偏移量。
slave_priority:100 #slave 优先级,master 故障后值越小越优先同步。
slave_read_only:1   #只读
connected_slaves:1   #有几个slave
slave0:ip=192.168.7.104,port=6379,state=online,offset=5334,lag=1  #显示slave的地址,端口,等
master_replid:0f0318c25a022add7fd51d4438c470cf608631f9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5334
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:5334

常见问题:

  1. master 密码不对
    配置的 master 密码不对,导致验证不通过而无法建立主从同步关系
    在这里插入图片描述

  2. Redis 版本不一致

不同的 redis 版本之间存在兼容性问题,因此各 master 和 slave 之间必须保持版本一致
在这里插入图片描述

  1. 无法远程连接
    在开启了安全模式情况下,没有设置 bind 地址和密码
[root@redis-s1 ~]# redis-cli -h 192.168.7.104
192.168.7.104:6379> KEYS *
(error) DENIED Redis is running in protected mode because protected mode is enabled, no 

二. 应用程序连接 redis----java,php,python

Redis 官方客户端:https://redis.io/clients

java 客户端连接 redis 是通过 Jedis 来实现的,java 代码用的时候只要创建 Jedis 对象就可以建多个 Jedis 连接池来连接 redis,应用程序再直接调用连接池即可连接 Redis

而 Redis 为了保障高可用,服务一般都是 Sentinel 部署方式,当 Redis 服务中的主服务挂掉之后,会仲裁出另外一台 Slaves 服务充当 Master。这个时候,我们的应用即使使用了 Jedis 连接
池,Master 服务挂了,我们的应用将还是无法连接新的 Master 服务,为了解决这个问题, Jedis 也提供了相应的 Sentinel 实现,能够在 Redis Sentinel 主从切换时候,通知我们的应用,把我们的应用连接到新的 Master 服务

Redis Sentinel 的使用也是十分简单的,只是在 JedisPool 中添加了 Sentinel 和 MasterName 参数,JRedis Sentinel 底层基于 Redis 订阅实现 Redis 主从服务的切换通知,当 Reids 发生主从切换时,Sentinel 会发送通知主动通知 Jedis 进行连接的切换,JedisSentinelPool 在每次从连接池中获取链接对象的时候,都要对连接对象进行检测,如果此链接和 Sentinel 的 Master 服务连接参数不一致,则会关闭此连接,重新获取新的 Jedis 连接对象。
在这里插入图片描述

python 连接 redis


# yum install python-pip
# pip install redis
[root@redis-s3 ~]# cat test.py 
import redis
pool = redis.ConnectionPool(host="192.168.7.101", port=6379,password="123456")
r = redis.Redis(connection_pool=pool)
for i in range(100):
 	r.set("k%d" % i,"v%d" % i)
	 data=r.get("k%d" % i)
print(data)

三. redis集群 (高可用)

当单台 Redis 服务器性能无法满足业务写入需求的时候

  1. master 和 slave 角色的无缝切换,让业务无感知从而不影响业务使用(高可用
  2. 可以横向动态扩展 Redis 服务器,从而实现多台服务器并行写入以实现更高并发的目的。(添加服务器
    Redis 集群实现方式:客户端分片,代理分片,Redis Cluster

1. Sentinel(哨兵)

Sentinel 进程是用于监控 redis 集群中 Master 主服务器工作的状态,在 Master 主服务器发生故障的时候,可以实现 Master 和 Slave 服务器的切换,保证系统的高可用,一般在生产环境也建议使用 Redis 的 2.8 版本的以后版本。哨兵(Sentinel) 是一个分布式系统可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossip protocols)来接收关于 Master 主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个 Slave 作为新的 Master。每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave 定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机SDOWN,主观是每个成员都具有的独自的而且可能相同也可能不同的意识,有主观宕机,肯定就有客观宕机。当“哨兵群”中的多数 Sentinel 进程在对 Master主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的 Master Server 下线判断,这种方式就是“客观宕机”,客观是不依赖于某种意识而已经实际存在的一切事物,英文名称是:Objectively Down, 简称 ODOWN。通过一定的 vote 算法,从剩下的 slave 从服务器节点中,选一台提升为 Master 服务器节点,然后自动修改相关配置,并开启故障转移(failover)。

Sentinel 机制可以解决 master 和 slave 角色的切换问题。

手动配置 master

需要手动先指定某一台 Redis 服务器为 master,然后将其他 slave 服务器使用命令配置为 master 服务
器的 slave,哨兵的前提是已经手动实现了一个 redis master-slave 的运行环境。
在这里插入图片描述
服务器 A 配置 slave

192.168.7.102:6379> REPLICAOF 192.168.7.101 6379
OK
	192.168.7.102:6379> CONFIG SET masterauth "123456"
OK

服务器 B 配置 slave

192.168.7.103:6379> REPLICAOF 192.168.7.101 6379
OK
192.168.7.103:6379> CONFIG SET masterauth "123456"
OK

如何配置哨兵—26379(高可用)

编辑配置文件 sentinel.conf: 在安装目录中有

cp /usr/local/src/redis-4.0.14/sentinel.conf /usr/local/redis/etc/

哨兵可以不和 Redis 服务器部署在一起

redis集群中的sentinel.conf可以一样(都要配置

[root@redis-s1 etc]# grep "^[a-Z]" /usr/local/redis/etc/sentinel.conf 

#后台运行
daemonize yes
bind 0.0.0.0
port 26379
#redis-master
sentinel myid 43214006ac221d4662198qhweiu89
#禁止修改脚本
sentinel deny-scripts-reconfig yes
#法定人数限制(quorum),即有几个 slave 认为 masterdown 了就进行故障转移
sentinel monitor redis-cluster 10.0.5.151 6379 1
#sentinel向master发送心跳Ping,如果在一定时间不回复(SDOWN)主观下线的时间
sentinel down-after-milliseconds redis-cluster 1000
#所有 slaves 指向新的 master 所需的超时时间(ms)
sentinel failover-timeout redis-cluster 1000

#sentinel auth-pass redis-master Zu5GpNWDOmyredispasswdwlHxgS

logfile "/data/logs/redis/sentinel/sentinel-26379.log"
# Generated by CONFIG REWRITE
dir "/"
#是否开启保护模式,默认开启。
#要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
#要是开启了密码和bind,可以开启。否则最好关闭,设置为no。
protected-mode no
#failover主备切换时最多可以有多少个slave同时对新的master进行 同步
#如果这个数字越大,就意味着越 多的slave因为replication而不可用。
#1 来保证每次只有一个slave 处于不能处理命令请求的状态。
sentinel parallel-syncs redis-cluster 2

#密码
sentinel auth-pass redis-cluster 123456
sentinel config-epoch redis-cluster 8
sentinel leader-epoch redis-cluster 8
#两个slave节点
sentinel known-replica redis-cluster 10.0.5.26 6379
sentinel known-replica redis-cluster 10.0.5.4 6379
#两个Sentinel节点
sentinel known-sentinel redis-cluster 10.0.5.151 26379 9a4b60c2a64080db3d228b03d4128a6dcb2bdef8
sentinel known-sentinel redis-cluster 10.0.5.4 26379 b8f0a28d1229420311393cf38e4ce156c82e54f3

sentinel current-epoch 8
#发生切换之后执行的一个自定义脚本:如发邮件、vip切换等
#sentinel notification-script <master-name> <script-path>
#发生切换之后执行的一个自定义脚本:如发邮件、vip切换等
#sentinel client-reconfig-script T1 /opt/bin/notify.py

启动哨兵
三台哨兵都要启动

/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf
/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf
/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf

验证端口ss -ntl
查看哨兵日志tail /usr/local/redis/logs/sentinel_26379.log
查看当前redis状态

127.0.0.1:6379> auth 123456
127.0.0.1:6379> INFO replication
role:slave
master_host:192.168.245.73
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:1
master_link_down_since_seconds:1617169245
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:67f7a1ace08beecb7b7154e1260233a0ef627295
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

然后测试
关掉master的reids-server
然后在日志中查看具体状态
在这里插入图片描述

2.Redis Cluster(集群)16379

Redis 分布式部署方案

1)客户端分区:由客户端程序决定 key 写分配和写入的 redis node,但是需要客户端自己处理写入分配、高可用管理和故障转移等
2)代理方案:基于三方软件实现 redis proxy,客户端先连接之代理层,由代理层实现 key 的写入分配,对客户端来说是有比较简单,但是对于集群管节点增减相对比较麻烦,而且代理本身也是单点和性能瓶颈。

在哨兵 sentinel 机制中,可以解决 redis 高可用的问题,即当 master 故障后可以自动将 slave 提升为master 从而可以保证 redis 服务的正常使用,但是无法解决 redis 单机写入的瓶颈问题,即单机的 redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素,因此 redis 官方在 redis 3.0 版本之后推出了无中心架构的 redis cluster 机制,在无中心的 redis 集群汇中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接,
特点如下:
1:所有 Redis 节点使用(PING 机制)互联
2:集群中某个节点的失效,是整个集群中超过半数的节点监测都失效才算真正的失效
3:客户端不需要 proxy 即可直接连接 redis,应用程序需要写全部的 redis 服务器 IP。
4:redis cluster 把所有的 redis node 映射到 0-16383 个槽位(slot)上,读写需要到指定的 redis node 上进行操作,因此有多少个 reids node 相当于 redis 并发扩展了多少倍
5:Redis cluster 预先分配 16384 个(slot)槽位,当需要在 redis 集群中写入一个 key -value 的时候,会使用 CRC16(key) 取模16384 之后的值,决定将 key 写入值哪一个槽位从而决定写入哪一个 Redis 节点上,从而有效解决单机瓶颈

Redis cluster 架构

基本架构
假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配 16384 个 slot 的话,它们三个节点分别承担的 slot 区间是:
节点 A 覆盖 0-5460
节点 B 覆盖 5461-10922
节点 C 覆盖 10923-16383
在这里插入图片描述
Redis cluster 主从架构
Redis cluster 的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个 Redis master 的高可用如何解决

给每个master下面加一个slave(不要把相同master和slave放到相同的服务器)
在这里插入图片描述

部署 redis 集

环境准备:
环境 A:三台服务器,每台服务器启动 6379 和 6380 两个 redis 服务。(交叉式)
192.168.7.101:6379/6380 192.168.7.102:6379/6380
192.168.7.103:6379/6380
另外预留一台服务器做集群添加节点测试。
192.168.7.104:6379/6380

环境 B:生产环境建议直接 6 台服务器。
在这里插入图片描述

创建 redis cluster 集群的前提

1.每个 redis node 节点采用相同的硬件配置、相同的密码
2.每个节点必须开启的参数
cluster-enabled yes #必须开启集群状态,开启后 redis 进程会有 cluster 显示
cluster-config-file nodes-6380.conf #此文件有 redis cluster 集群自动创建和维护,不需要任何手动操作
3.所有 redis 服务器必须没有任何数据
4.先启动为单机 redis 且没有任何 key value

也就是关掉所有的slaveof配置
开启所有的cluster功能
cluster-enabled yes
cluster-config-file nodes-6380.conf
清空所有数据FLUSHALL

rm /usr/local/redis/data/*
rm /usr/local/redis/run/*
rm /usr/local/redis/logs /*

在这里插入图片描述

创建集群
4 版本:
需要使用到集群管理工具 redis-trib.rb,这个工具是 redis 官方推出的管理 redis 集群的工具,集成在redis 的源码 src 目录下,是基于 redis 提供的集群命令封装成简单、便捷、实用的操作工具,redis-trib.rb是 redis 作者用 ruby 开发完成的,centos 系统 yum 安装的 ruby 存在版本较低问题,如下:

在集群的任意一台配置就可以
不建议ruby版本较低:会出错

[root@s1 ~]# yum install ruby rubygems -y
[root@s1 ~]# find / -name redis-trib.rb 
/usr/local/src/redis-4.0.14/src/redis-trib.rb
[root@s1 ~]# cp /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin/
[root@s1 src]# gem install redis
	Fetching: redis-4.1.2.gem (100%)
	ERROR: Error installing redis:
	redis requires Ruby version >= 2.3.0.

redis 3/4版本:需要装ruby

解决 ruby 版本较低问题建议
只需要在redis集群中任意一台装就可以

源码:https://cache.ruby-lang.org/pub/ruby/

[root@s1 src]# yum remove ruby rubygems -y
[root@s1 src]# wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz
[root@s1 src]# tar xf ruby-2.5.5.tar.gz
[root@s1 src]# cd ruby-2.5.5
[root@s1 ruby-2.5.5]# ./configure
[root@s1 ruby-2.5.5]# make -j 2
[root@s1 ruby-2.5.5]# make install
[root@s1 ruby-2.5.5]# cp /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin/
[root@s1 ruby-2.5.5]# gem install redis  #安装模块

可以在ruby网关中下载redis的rpm包
https://rubygems.org/gems/redis

rpm 
gem install -l redis-3.3.0.gem

验证 redis-trib.rb 命令是否可执行:

[root@s1 ruby-2.5.4]# redis-trib.rb 

Usage: redis-trib <command> <options> <arguments ...>
 
 create host1:port1 ... hostN:portN #创建集群
 		--replicas <arg> #指定 master 的副本数量
 check host:port #检查集群信息
 info host:port #查看集群主机信息
 fix host:port #修复集群
 		--timeout <arg>
 reshard host:port #在线热迁移集群指定主机的 slots 数据
		 --from <arg>
		 --to <arg>
		 --slots <arg>
		 --yes
		 --timeout <arg>
		 --pipeline <arg>
 rebalance host:port #平衡集群中各主机的 slot 数量
		 --weight <arg>
		 --auto-weights
		 --use-empty-masters
		 --timeout <arg>
		 --simulate
		 --pipeline <arg>
		 --threshold <arg>
 add-node new_host:new_port existing_host:existing_port #添加主机到集群
		 --slave
		 --master-id <arg>
 del-node	 host:port node_id #删除主机
 set-timeout 	host:port milliseconds #设置节点的超时时间
 call	 host:port command arg arg .. arg #在集群上的所有节点上执行命令
 import 	host:port #导入外部 redis 服务器的数据到当前集群
		 --from <arg>
		 --copy
		 --replace
 help (show this help)

[root@s1 ruby-2.5.4]# vim /usr/local/lib/ruby/gems/2.5.0/gems/redis-4.1.2/lib/redis/client.rb 
#修改密码为
password 123456

在这里插入图片描述

创建 redis cluster 集群
Redis 3/4 版本:

默认前面3个master,后面三个slave

[root@s1 ~]# redis-trib.rb create --replicas 1 172.18.200.101:6379 172.18.200.102:6379 
172.18.200.103:6379 172.18.200.104:6379 172.18.200.105:6379 172.18.200.106:6379

Redis 5 版本:不需要装ruby

创建集群

[root@redis-s1 ~]# redis-cli -a 123456 --cluster create 192.168.7.101:6379 192.168.7.101:6380 192.168.7.102:6379 192.168.7.102:6380 1
92.168.7.103:6379 192.168.7.103:6380 --cluster-replicas 1

redis-cli --cluster info 10.69.56.156:6379 -a eS^ybKmk

检查状态

由于未设置 masterauth 认证密码,所以主从未建立起来,但是集群已经运行,所以需要在每个 slave控制台使用 config set 设置 masterauth 密码,或者写在每个 redis 配置文件中,最好是在控制点设置密码之后再写入配置文件当中。

集群状态监控

redis-trib.rb  check   192.168.245.129:6379
或者
redis-trib.rb  info   192.168.245.129:6379

分别设置 masterauth 密码:初始化没有配置密码

192.168.245.129:6380> CONFIG SET masterauth 123456

查看集群状态

#redis-cli
cluster  info 

查看集群 node 对应关系

#redis-cli
cluster nodes

验证集群写入 key
就不一定在当前的redis中
因为有对应的槽位

192.168.7.101:6379> SET key1 value1 
 #经过算法计算,当前 key 的槽位需要写入指定的 node 
(error) MOVED 9189 192.168.7.102:6379 
#槽位不在当前 node 所以无法写入
192.168.7.103:6379> SET key1 value1 
(error) MOVED 9189 192.168.7.102:6379 
192.168.7.102:6379> SET key1 value1 
#指定的 node 就可以写入
OK
192.168.7.102:6379> KEYS *
1) "key1"

验证 master 状态

redis-cli -h 192.168.7.101 -p 6379 -a 123456

#重启/查看进程
supervisorctl reload !!!!!千万不要用这个命令加载配置文件,会重启所有进程
重新加载配置
supervisorctl update

查看所有进程状态
supervisorctl status

3. Redis cluster 集群节点维护

集群运行时间长久之后,难免由于硬件故障、网络规划、业务增长等原因对已有集群进行相应的调整
比如增加 Redis node 节点、减少节点、节点迁移、更换服务器等。
增加节点和删除节点会涉及到已有的槽位重新分配及数据迁移

动态添加节点

增加 Redis node 节点,需要与之前的 Redis node 版本相同、配置一致,然后分别启动两台 Redis node,因为一主一从

注意:这里的端口号,6380的conf文件

scp redis.conf 192.168.7.104:/usr/local/redis/etc/
scp redis_6380.conf 192.168.7.104:/usr/local/redis/etc/

分别启动 redis 服务:

systemctl daemon-reload
systemctl restart redis
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis_6380.conf

重启服务
/usr/local/redis/bin/Redis-server /usr/local/redis/etc/redis_6380. conf

添加节点到集群:一般是成对的master,slave

redis-trib.rb add-node new_host:new_port existing_host:existing_port
                       新的                集群中任意一个    

要添加的新 redis 节点 IP 和端口 添加到的集群中的 master IP:端口,加到集群之后默认是 master 节点但是没有slots 数据,需要重新分配。

Redis 4 添加方式:

redis-trib.rb add-node 172.18.200.107:6379 172.18.200.101:6379
redis-trib.rb add-node 172.18.200.108:6379 172.18.200.101:6379

Redis 5 添加方式:

redis-cli -a 123456 --cluster add-node 192.168.7.107:6379 192.168.7.101:6379
redis-cli -a 123456 --cluster add-node 192.168.7.108:6379 192.168.7.101:6379

分配槽位
添加主机之后需要对添加至集群种的新主机重新分片否则其没有分片

验证当前状态:
Redis 3/4

#  重新分配槽位
[root@s1 ~]# redis-trib.rb reshard 172.18.200.107:6379

[root@s1 ~]# redis-trib.rb check 172.18.200.101:6379

注意这里:指定分配多少个槽位

How many slots do you want to move (from 1 to 16384)? 4096 #分配多少个槽位
What is the receiving node ID? 886338acd50c3015be68a760502b239f4509881c #接收 slot 的服务器 ID-----新添加的


#记住这里不能有数据
Source node #1: all #将哪些源主机的槽位分配

Redis 5:

[root@s1 ~]# redis-cli -a 123456 --cluster check 172.18.200.107:6379

在这里插入图片描述

最后检测

redis-cli -a 123456 --cluster check 192.168.7.103:6379 

在这里插入图片描述
为新的 master 添加 slave 节点

为6379 添加的事新redis的6380端口

redis-cli -a 123456 --cluster add-node 192.168.7.104:6380 192.168.7.104:6379

更改新节点更改状态为 slave

192.168.7.104:6380> CLUSTER NODES #查看当前集群节点,找到目标 master 的 ID

192.168.7.104:6380> CLUSTER REPLICATE 886338acd50c3015be68a760502b239f4509881c #将其设置 slave,命令格式为 cluster replicate MASTERID
OK

192.168.7.104:6380> CLUSTER NODES #再次查看集群节点状态,验证节点是否已经更改为指定 master 的 slave

在这里插入图片描述

动态删除节点

删除节点的操作与添加节点的操作正好相反,是先将被删除的 Redis node 上的槽位迁移到集群中的其他 Redis node 节点上,然后再将其删除。如果一个 Redis node 节点上的槽位没有被完全迁移,删除该 node 的时候会提示有数据且无法删除。

迁移 master 的槽位之其他 master
被迁移 Redis 服务器必须保证没有数据

[root@s1 ~]# redis-trib.rb reshard 172.18.200.101:6379
#迁移失败需要修复集群
[root@s1 ~]# redis-trib.rb fix 172.18.200.101:6379 
[root@redis-s1 ~]# redis-cli -a 123456 --cluster reshard 192.168.7.102:6379
#迁移 master 上的多少个槽位
How many slots do you want to move (from 1 to 16384)? 4096 
#接收槽位的服务器 ID
What is the receiving node ID? 886338acd50c3015be68a760502b239f4509881c 
#从哪个服务器迁移 4096 个槽位
Source node #1: f4cfc5cf821c0d855016488d6fbfb62c03a14fda 
#写 done,表示没有其他 master 了
Source node #2: done 

从集群删除服务器
虽然槽位已经迁移完成,但是服务器 IP 信息还在集群当中,因此还需要将 IP 信息从集群删除
命令格式:

Redis 4:

#要删除的ip  和id
redis-trib.rb del-node 172.18.200.102:6379 
3ed26459bcdf4bbd3004c9a7506ba1f6e87dd55a

Redis 5:

redis-cli -a 123456 --cluster del-node 192.168.7.101:6379  f4cfc5cf821c0d855016488d6fbfb62c03a14fda

验证 node 是否删除

redis-trib.rb check 172.16..200.101:6379

在这里插入图片描述
重新分配 slave: 将 192.168.7.104:6380 转移为 192.168.7.103 的 slave

192.168.7.104:6380> CLUSTER REPLICATE 70de3821dde4701c647bd6c23b9dd3c5c9f24a62

数据迁移 --需求两边无密码(可暂时取消密码)

导入数据需要 redis cluster 不能与被导入的数据有重复的 key 名称,否则导入不成功或中断。
案例:
公司将 redis cluster 部署完成之后,需要将之前的数据导入之 Redis cluster 集群,但是由于 Redis cluster使用的分片保存 key 的机制,因此使用传统的 AOF 文件或 RDB 快照无法满足需求,因此需要使用集群数据导入命令完成

基础环境准备
导入数据之前需要关闭各 redis 服务器的密码,包括集群中的各 node 和源 Redis server,避免认证带 来的环境不一致从而无法导入,可以加参数–cluster-replace 强制替换 Redis cluster 已有的 key

关闭所有redis的密码两边无密码
设置/取消密码
config set requirepass 123456
config get requirepass “”

[root@redis-s1 ~]# redis-cli -h 192.168.7.102 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.7.102:6379> CONFIG SET requirepass ""
OK
192.168.7.104:6379> exit

执行数据导入
Redis 3/4

									外部redis								集群
[root@s1 ~]# redis-trib.rb import --from 172.18.200.107:6382 --replace 172.18.200.107:6379

Redis 5

 redis-cli -h 集群ip -p 端口--cluster import 集群服务器IP:PORT --cluster-from 外部Redis node-IP:PORT --cluster-copy --cluster-replace
[root@redis-s2 redis]# redis-cli --cluster import 192.168.7.103:6379 --cluster-from 192.168.7.101:6379 --cluster-copy --cluster-replace

四. codis集群扩展

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的Redis Server 没有显著区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。

codis-proxy 相当于 redis,即连接 codis-proxy 和连接 redis 是没有任何区别的,codis-proxy 无状态,不负责记录是否在哪保存,数据在 zookeeper 记录,即 codis proxy 向 zookeeper 查询 key 的记录位置,proxy 将请求转发到一个组进行处理,一个组里面有一个 master 和一个或者多个 slave 组成,默认有1024 个槽位,redis cluster 默认有 16384 个槽位,其把不同的槽位的内容放在不同的 group。
Github 地址:https://github.com/CodisLabs/codis/blob/release3.2/doc/tutorial_zh.md
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值