中国建设部官方网站资格证查询,腾讯云域名购买,公司网站建设描述,淘宝联盟+做网站目录
分布式缓存
一、Redis持久化
1.1、RDB持久化
1.1.1、执行时机
1.1.2、RDB原理
1.1.3、小结
1.2、OF持久化
1.2.1、AOF原理
1.2.2、OF配置
1.2.3、AOF文件重写
1.3、RDB与AOF对比
二、Redis主从
2.1、搭建主从架构
2.1.1、集群结构
2.1.2、准备实例和配置
…目录
分布式缓存
一、Redis持久化
1.1、RDB持久化
1.1.1、执行时机
1.1.2、RDB原理
1.1.3、小结
1.2、OF持久化
1.2.1、AOF原理
1.2.2、OF配置
1.2.3、AOF文件重写
1.3、RDB与AOF对比
二、Redis主从
2.1、搭建主从架构
2.1.1、集群结构
2.1.2、准备实例和配置
2.1.3、启动
2.1.4、开启主从关系
2.1.5、测试
2.2、主从数据同步原理
2.2.1、全量同步
2.2.2、增量同步
2.2.3、repl_backlog原理
2.3、主从同步优化
2.4、小结
三、哨兵模式
3.1、哨兵原理
3.1.1、集群结构和作用
3.1.2、集群监控原理
3.1.3、集群故障恢复原理
3.1.4、集群故障恢复原理
3.2、搭建哨兵集群
3.2.1、集群结构
3.2.2、准备实例和配置
3.2.3、启动
3.2.4、测试
四、分片集群
4.1、搭建分片集群
4.1.1、集群结构
4.1.2、准备实例和配置
4.1.3、启动
4.1.4、创建集群
4.1.5、测试
4.2、散列插槽
4.2.1、插槽原理
4.2.2、小结
4.3、集群伸缩
4.3.1、需求分析
4.3.2、创建新的Redis实例
4.3.3、添加新节点到Redis
4.3.4、转移插槽
4.4、故障转移
4.4.1、自动故障转移
4.4.2、手动故障转移 分布式缓存
基于Redis集群解决单机Redis存在的问题。
单机的Redis存在四大问题
1数据丢失问题Redis是内存存储服务重启可能会丢失数据。
2并发能力问题单节点Redis并发能力虽然不错但也无法满足如618这样的高并发场景。
3故障恢复问题如果Redis宕机则服务不可用需要一种自动的故障恢复手段。
4存储能力问题Redis基于内存单节点能存储的数据量难以满足海量数据需求。 一、Redis持久化
Redis有两种持久化方案 RDB持久化 AOF持久化
1.1、RDB持久化
RDB全称Redis Database Backup fileRedis数据备份文件也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后从磁盘读取快照文件恢复数据。快照文件称为RDB文件默认是保存在当前运行目录。
1.1.1、执行时机
RDB持久化在四种情况下会执行 执行save命令 执行bgsave命令 Redis停机时 触发RDB条件时
1save命令
执行下面的命令可以立即执行一次RDB save命令会导致主进程执行RDB这个过程中其它所有命令都会被阻塞。只有在数据迁移时可能用到。
2bgsave命令
下面的命令可以异步执行RDB 这个命令执行后会开启独立进程完成RDB主进程可以持续处理用户请求不受影响。
3停机时
Redis停机时会执行一次save命令实现RDB持久化。
4触发RDB条件
Redis内部有触发RDB的机制可以在redis.conf文件中找到格式如下
# 900秒内如果至少有1个key被修改则执行bgsave 如果是save 则表示禁用RDB
save 900 1
save 300 10
save 60 10000
RDB的其它配置也可以在redis.conf文件中设置
# 是否压缩 ,建议不开启压缩也会消耗cpu磁盘的话不值钱
rdbcompression yes# RDB文件名称
dbfilename dump.rdb # 文件保存的路径目录
dir ./
1.1.2、RDB原理
bgsave开始时会fork主进程得到子进程子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。
fork子进程过程
注意虽然子进程是对主进程没影响的但fork子进程的过程是要主线程来做这个时候是阻塞的所以我们需要加快fork的速度。
如下图所示主进程其实是无法直接操作物理内存的所以应该有个做映射的虚拟内存页表主进程通过页表映射到物理内存里的数据这时就可以访问了。而fork子进程的时候把页面直接拷贝一份给子进程这样子进程就能通过相同的页表映射到物理内存中的数据了。
copy-on-write
那么既然是异步的子进程在写RDB的过程中主进程这时接收用户的请求来修改内存中的数据主进程在写子进程在读那么会出现一些脏数据为了避免此类情况发生。
所以fork采用的是copy-on-write技术 当主进程执行读操作时访问共享内存 当主进程执行写操作时则会拷贝一份数据执行写操作。 如图所示当主进程来了一条写命令先拷贝一份数据以后主进程写和读的操作都作用在拷贝的副本上。
那么有一种情况假如子进程RDB写的过程比较慢在子进程写的过程中主进程不断的有新的请求过来不断的修改共同数据所有的数据都被修改了一遍那么这种情况下意味着所有的数据都要拷贝一份意味着对内存的占用翻倍了这种情况理论上是有可能发生的虽然是极端情况。 1.1.3、小结
RDB方式bgsave的基本流程 fork主进程得到一个子进程共享内存空间 子进程读取内存数据并写入新的RDB文件 用新RDB文件替换旧的RDB文件
RDB会在什么时候执行save 60 1000代表什么含义 默认是服务停止时 代表60秒内至少执行1000次修改则触发RDB
RDB的缺点 RDB执行间隔时间长两次RDB之间写入数据有丢失的风险 fork子进程、压缩、写出RDB文件都比较耗时 1.2、OF持久化
1.2.1、AOF原理
AOF全称为Append Only File追加文件。Redis处理的每一个写命令都会记录在AOF文件可以看做是命令日志文件。 1.2.2、OF配置
AOF默认是关闭的需要修改redis.conf配置文件来开启AOF
# 是否开启AOF功能默认是no
appendonly yes
# AOF文件的名称
appendfilename appendonly.aof
AOF的命令记录的频率也可以通过redis.conf文件来配
# 表示每执行一次写命令立即记录到AOF文件
appendfsync always
# 写命令执行完先放入AOF缓冲区然后表示每隔1秒将缓冲区数据写到AOF文件是默认方案
appendfsync everysec
# 写命令执行完先放入AOF缓冲区由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
三种策略对比 1.2.3、AOF文件重写
因为是记录命令AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作但只有最后一次写操作才有意义。通过执行bgrewriteaof命令可以让AOF文件执行重写功能用最少的命令达到相同效果。 如图AOF原本有三个命令但是set num 123 和 set num 666都是对num的操作第二次会覆盖第一次的值因此第一个命令记录下来没有意义。
所以重写命令后AOF文件内容就是mset name jack num 666
Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置
# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb 1.3、RDB与AOF对比
RDB和AOF各有自己的优缺点如果对数据安全性要求较高在实际开发中往往会结合两者来使用。 二、Redis主从
2.1、搭建主从架构
单节点Redis的并发能力是有上限的要进一步提高Redis的并发能力就需要搭建主从集群实现读写分离。
2.1.1、集群结构
我们搭建的主从集群结构如图 共包含三个节点一个主节点两个从节点。
这里我们会在同一台虚拟机中开启3个redis实例模拟主从集群信息如下 2.1.2、准备实例和配置
要在同一台虚拟机开启3个实例必须准备三份不同的配置文件和目录配置文件所在目录也就是工作目录。
1创建目录
我们创建三个文件夹名字分别叫7001、7002、7003
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003
如图 2恢复原始配置
修改redis-6.2.4/redis.conf文件将其中的持久化模式改为默认的RDB模式AOF保持关闭状态。
# 开启RDB
# save
save 3600 1
save 300 100
save 60 10000# 关闭AOF
appendonly no
3拷贝配置文件到每个实例目录
然后将redis-6.2.4/redis.conf文件拷贝到三个目录中在/tmp目录执行下列命令
# 方式一逐个拷贝
cp redis-6.2.4/redis.conf 7001
cp redis-6.2.4/redis.conf 7002
cp redis-6.2.4/redis.conf 7003# 方式二管道组合命令一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp redis-6.2.4/redis.conf
4修改每个实例的端口、工作目录
修改每个文件夹内的配置文件将端口分别修改为7001、7002、7003将rdb文件保存位置都修改为自己所在目录在/tmp目录执行下列命令
sed -i -e s/6379/7001/g -e s/dir .\//dir \/tmp\/7001\//g 7001/redis.conf
sed -i -e s/6379/7002/g -e s/dir .\//dir \/tmp\/7002\//g 7002/redis.conf
sed -i -e s/6379/7003/g -e s/dir .\//dir \/tmp\/7003\//g 7003/redis.conf
5修改每个实例的声明IP
虚拟机本身有多个IP为了避免将来混乱我们需要在redis.conf文件中指定每一个实例的绑定ip信息格式如下
# redis实例的声明 IP
replica-announce-ip 192.168.150.101
每个目录都要改我们一键完成修改在/tmp目录执行下列命令
# 逐一执行
sed -i 1a replica-announce-ip 192.168.150.101 7001/redis.conf
sed -i 1a replica-announce-ip 192.168.150.101 7002/redis.conf
sed -i 1a replica-announce-ip 192.168.150.101 7003/redis.conf# 或者一键修改
printf %s\n 7001 7002 7003 | xargs -I{} -t sed -i 1a replica-announce-ip 192.168.150.101 {}/redis.conf
2.1.3、启动
为了方便查看日志我们打开3个ssh窗口分别启动3个redis实例启动命令
# 第1个
redis-server 7001/redis.conf
# 第2个
redis-server 7002/redis.conf
# 第3个
redis-server 7003/redis.conf
启动后 如果要一键停止可以运行下面命令
printf %s\n 7001 7002 7003 | xargs -I{} -t redis-cli -p {} shutdown 2.1.4、开启主从关系
现在三个实例还没有任何关系要配置主从可以使用replicaof 或者slaveof5.0以前命令。
有临时和永久两种模式 修改配置文件永久生效 在redis.conf中添加一行配置slaveof masterip masterport 使用redis-cli客户端连接到redis服务执行slaveof命令重启后失效
slaveof masterip masterport
注意在5.0以后新增命令replicaof与salveof效果一致。
这里我们为了演示方便使用方式二。
通过redis-cli命令连接7002执行下面命令
# 连接 7002
redis-cli -p 7002
# 执行slaveof
slaveof 192.168.150.101 7001
通过redis-cli命令连接7003执行下面命令
# 连接 7003
redis-cli -p 7003
# 执行slaveof
slaveof 192.168.150.101 7001
然后连接 7001节点查看集群状态
# 连接 7001
redis-cli -p 7001
# 查看状态
info replication
结果 2.1.5、测试
执行下列操作以测试 利用redis-cli连接7001执行set num 123 利用redis-cli连接7002执行get num再执行set num 666 利用redis-cli连接7003执行get num再执行set num 888
可以发现只有在7001这个master节点上可以执行写操作7002和7003这两个slave节点只能执行读操作。 2.2、主从数据同步原理
2.2.1、全量同步
主从第一次建立连接时会执行全量同步将master节点的所有数据都拷贝给slave节点流程 这里有一个问题master如何得知salve是第一次来连接呢
有几个概念可以作为判断依据 Replication Id简称replid是数据集的标记id一致则说明是同一数据集。每一个master都有唯一的replidslave则会继承master节点的replid offset偏移量随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset说明slave数据落后于master需要更新。
因此slave做数据同步必须向master声明自己的replication id 和offsetmaster才可以判断到底需要同步哪些数据。
因为slave原本也是一个master有自己的replid和offset当第一次变成slave与master建立连接时发送的replid和offset是自己的replid和offset。
master判断发现slave发送来的replid与自己的不一致说明这是一个全新的slave就知道要做全量同步了。
master会将自己的replid和offset都发送给这个slaveslave保存这些信息。以后slave的replid就与master一致了。
因此master判断一个节点是否是第一次同步的依据就是看replid是否一致。
如图 完整流程描述 slave节点请求增量同步 master节点判断replid发现不一致拒绝增量同步 master将完整内存数据生成RDB发送RDB到slave slave清空本地数据加载master的RDB master将RDB期间的命令记录在repl_baklog并持续将log中的命令发送给slave slave执行接收到的命令保持与master之间的同步 2.2.2、增量同步
全量同步需要先做RDB然后将RDB文件通过网络传输个slave成本太高了。因此除了第一次做全量同步其它大多数时候slave与master都是做增量同步。
什么是增量同步就是只更新slave与master存在差异的部分数据。如图 那么master怎么知道slave与自己的数据差异在哪里呢? 2.2.3、repl_backlog原理
master怎么知道slave与自己的数据差异在哪里呢?
这就要说到全量同步时的repl_baklog文件了。
这个文件是一个固定大小的数组只不过数组是环形也就是说角标到达数组末尾后会再次从0开始读写这样数组头部的数据就会被覆盖。
repl_baklog中会记录Redis处理过的命令日志及offset包括master当前的offset和slave已经拷贝到的offset slave与master的offset之间的差异就是salve需要增量拷贝的数据了。
随着不断有数据写入master的offset逐渐变大slave也不断的拷贝追赶master的offset 直到数组被填满 此时如果有新的数据写入就会覆盖数组中的旧数据。不过旧的数据只要是绿色的说明是已经被同步到slave的数据即便被覆盖了也没什么影响。因为未同步的仅仅是红色部分。
但是如果slave出现网络阻塞导致master的offset远远超过了slave的offset 如果master继续写入新数据其offset就会覆盖旧的数据直到将slave现在的offset也覆盖 棕色框中的红色部分就是尚未同步但是却已经被覆盖的数据。此时如果slave恢复需要同步却发现自己的offset都没有了无法完成增量同步了。只能做全量同步。 2.3、主从同步优化
主从同步可以保证主从数据的一致性非常重要。
可以从以下几个方面来优化Redis主从就集群 在master中配置repl-diskless-sync yes启用无磁盘复制避免全量同步时的磁盘IO。 Redis单节点上的内存占用不要太大减少RDB导致的过多磁盘IO 适当提高repl_baklog的大小发现slave宕机时尽快实现故障恢复尽可能避免全量同步 限制一个master上的slave节点数量如果实在是太多slave则可以采用主-从-从链式结构减少master压力
主从从架构图 2.4、小结
简述全量同步和增量同步区别 全量同步master将完整内存数据生成RDB发送RDB到slave。后续命令则记录在repl_baklog逐个发送给slave。 增量同步slave提交自己的offset到mastermaster获取repl_baklog中从offset之后的命令给slave
什么时候执行全量同步 slave节点第一次连接master节点时 slave节点断开时间太久repl_baklog中的offset已经被覆盖时
什么时候执行增量同步 slave节点断开又恢复并且在repl_baklog中能找到offset时 三、哨兵模式
3.1、哨兵原理
3.1.1、集群结构和作用
哨兵的结构如图 哨兵的作用如下 监控Sentinel 会不断检查您的master和slave是否按预期工作。 自动故障恢复如果master故障Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主。 通知Sentinel充当Redis客户端的服务发现来源当集群发生故障转移时会将最新信息推送给Redis的客户端。 3.1.2、集群监控原理
Sentinel基于心跳机制监测服务状态每隔1秒向集群的每个实例发送ping命令
主观下线如果某sentinel节点发现某实例未在规定时间响应则认为该实例主观下线。客观下线若超过指定数量quorum的sentinel都认为该实例主观下线则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。 3.1.3、集群故障恢复原理
一旦发现master故障sentinel需要在salve中选择一个作为新的master选择依据是这样的 首先会判断slave节点与master节点断开时间长短如果超过指定值down-after-milliseconds * 10则会排除该slave节点。 然后判断slave节点的slave-priority值越小优先级越高如果是0则永不参与选举。 如果slave-prority一样则判断slave节点的offset值越大说明数据越新优先级越高。 最后是判断slave节点的运行id大小越小优先级越高。 当选出一个新的master后该如何实现切换呢
流程如下 sentinel给备选的slave1节点发送slaveof no one命令让该节点成为master。 sentinel给所有其它slave发送slaveof 192.168.150.101 7002 命令让这些slave成为新master的从节点开始从新的master上同步数据。 最后sentinel将故障节点标记为slave当故障节点恢复后会自动成为新的master的slave节点。 3.1.4、集群故障恢复原理
Sentinel的三个作用是什么 监控 故障转移 通知
Sentinel如何判断一个redis实例是否健康 每隔1秒发送一次ping命令如果超过一定时间没有相向则认为是主观下线 如果大多数sentinel都认为实例主观下线则判定客观下线
故障转移步骤有哪些 首先选定一个slave作为新的master执行slaveof no one 然后让所有节点都执行slaveof 新master 修改故障节点配置添加slaveof 新master 3.2、搭建哨兵集群
3.2.1、集群结构 三个sentinel实例信息如下 3.2.2、准备实例和配置
要在同一台虚拟机开启3个实例必须准备三份不同的配置文件和目录配置文件所在目录也就是工作目录。
我们创建三个文件夹名字分别叫s1、s2、s3
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir s1 s2 s3
如图 然后我们在s1目录创建一个sentinel.conf文件添加下面的内容
port 27001
sentinel announce-ip 192.168.150.101
sentinel monitor mymaster 192.168.150.101 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir /tmp/s1
解读 port 27001是当前sentinel实例的端口 sentinel monitor mymaster 192.168.150.101 7001 2指定主节点信息 mymaster主节点名称自定义任意写 192.168.150.101 7001主节点的ip和端口 2选举master时的quorum值
然后将s1/sentinel.conf文件拷贝到s2、s3两个目录中在/tmp目录执行下列命令
# 方式一逐个拷贝
cp s1/sentinel.conf s2
cp s1/sentinel.conf s3
# 方式二管道组合命令一键拷贝
echo s2 s3 | xargs -t -n 1 cp s1/sentinel.conf
修改s2、s3两个文件夹内的配置文件将端口分别修改为27002、27003
sed -i -e s/27001/27002/g -e s/s1/s2/g s2/sentinel.conf
sed -i -e s/27001/27003/g -e s/s1/s3/g s3/sentinel.conf 3.2.3、启动
为了方便查看日志我们打开3个ssh窗口分别启动3个redis实例启动命令
# 第1个
redis-sentinel s1/sentinel.conf
# 第2个
redis-sentinel s2/sentinel.conf
# 第3个
redis-sentinel s3/sentinel.conf
启动后 3.2.4、测试
尝试让master节点7001宕机查看sentinel日志 查看7003的日志 查看7002的日志 四、分片集群
4.1、搭建分片集群
主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决 海量数据存储问题 高并发写的问题
使用分片集群可以解决上述问题如图: 分片集群特征 集群中有多个master每个master保存不同数据 每个master都可以有多个slave节点 master之间通过ping监测彼此健康状态 客户端请求可以访问集群任意节点最终都会被转发到正确节点 4.1.1、集群结构
分片集群需要的节点数量较多这里我们搭建一个最小的分片集群包含3个master节点每个master包含一个slave节点结构如下 这里我们会在同一台虚拟机中开启6个redis实例模拟分片集群信息如下 4.1.2、准备实例和配置
删除之前的7001、7002、7003这几个目录重新创建出7001、7002、7003、8001、8002、8003目录
# 进入/tmp目录
cd /tmp
# 删除旧的避免配置干扰
rm -rf 7001 7002 7003
# 创建目录
mkdir 7001 7002 7003 8001 8002 8003
在/tmp下准备一个新的redis.conf文件内容如下
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称不需要我们创建由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log
将这个文件拷贝到每个目录下
# 进入/tmp目录
cd /tmp
# 执行拷贝
echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
修改每个目录下的redis.conf将其中的6379修改为与所在目录一致
# 进入/tmp目录
cd /tmp
# 修改配置文件
printf %s\n 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i s/6379/{}/g {}/redis.conf
4.1.3、启动
因为已经配置了后台启动模式所以可以直接启动服务
# 进入/tmp目录
cd /tmp
# 一键启动所有服务
printf %s\n 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
通过ps查看状态
ps -ef | grep redis
发现服务都已经正常启动 如果要关闭所有进程可以执行命令
ps -ef | grep redis | awk {print $2} | xargs kill
或者推荐这种方式
printf %s\n 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
4.1.4、创建集群
虽然服务启动了但是目前每个服务之间都是独立的没有任何关联。
我们需要执行命令来创建集群在Redis5.0之前创建集群比较麻烦5.0之后集群管理命令都集成到了redis-cli中。
1Redis5.0之前
Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。 # 安装依赖yum -y install zlib ruby rubygemsgem install redis
然后通过命令来管理集群
# 进入redis的src目录
cd /tmp/redis-6.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003 2Redis5.0以后
我们使用的是Redis6.2.4版本集群管理以及集成到了redis-cli中格式如下
命令说明 redis-cli --cluster或者./redis-trib.rb代表集群操作命令 create代表是创建集群 --replicas 1或者--cluster-replicas 1 指定集群中每个master的副本个数为1此时节点总数 ÷ (replicas 1) 得到的就是master的数量。因此节点列表中的前n个就是master其它节点都是slave节点随机分配到不同master 运行后的样子 这里输入yes则集群开始创建 通过命令可以查看集群状态
redis-cli -p 7001 cluster nodes 4.1.5、测试
尝试连接7001节点存储一个数据
# 连接
redis-cli -p 7001
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1
结果悲剧了 集群操作时需要给redis-cli加上-c参数才可以
redis-cli -c -p 7001
这次可以了 4.2、散列插槽
4.2.1、插槽原理
Redis会把每一个master节点映射到0~16383共16384个插槽hash slot上查看集群信息时就能看到 数据key不是与节点绑定而是与插槽绑定。redis会根据key的有效部分计算插槽值分两种情况 key中包含{}且“{}”中至少包含1个字符“{}”中的部分是有效部分 key中不包含“{}”整个key都是有效部分
例如key是num那么就根据num计算如果是{itcast}num则根据itcast计算。计算方式是利用CRC16算法得到一个hash值然后对16384取余得到的结果就是slot值。 如图在7001这个节点执行set a 1时对a做hash运算对16384取余得到的结果是15495因此要存储到103节点。
到了7003后执行get num时对num做hash运算对16384取余得到的结果是2765因此需要切换到7001节点。 4.2.2、小结
Redis如何判断某个key应该在哪个实例 将16384个插槽分配到不同的实例 根据key的有效部分计算哈希值对16384取余 余数作为插槽寻找插槽所在实例即可
如何将同一类数据固定的保存在同一个Redis实例 这一类数据使用相同的有效部分例如key都以{typeId}为前缀 4.3、集群伸缩
其实就是能动态的添加节点删除节点。
redis-cli --cluster提供了很多操作集群的命令可以通过下面方式查看 比如添加节点的命令 4.3.1、需求分析
需求向集群中添加一个新的master节点并向其中存储 num 10 启动一个新的redis实例端口为7004 添加7004到之前的集群并作为一个master节点 给7004节点分配插槽使得num这个key可以存储到7004实例
这里需要两个新的功能 添加一个节点到集群中 将部分插槽分配到新插槽 4.3.2、创建新的Redis实例
创建一个文件夹
mkdir 7004 拷贝配置文件
cp redis.conf /7004
修改配置文件
sed /s/6379/7004/g 7004/redis.conf
启动
redis-server 7004/redis.conf 4.3.3、添加新节点到Redis
添加节点的语法如下 执行命令
redis-cli --cluster add-node 192.168.150.101:7004 192.168.150.101:7001
通过命令查看集群状态
redis-cli -p 7001 cluster nodes
如图7004加入了集群并且默认是一个master节点 但是可以看到7004节点的插槽数量为0因此没有任何数据可以存储到7004上。 4.3.4、转移插槽
我们要将num存储到7004节点因此需要先看看num的插槽是多少 如上图所示num的插槽为2765。
我们可以将0~3000的插槽从7001转移到7004命令格式如下 具体命令如下
建立连接 得到下面的反馈 询问要移动多少个插槽我们计划是3000个
新的问题来了 哪个node来接收这些插槽
显然是7004那么7004节点的id是多少呢 复制这个id然后拷贝到刚才的控制台后 这里询问你的插槽是从哪里移动过来的 all代表全部也就是三个节点各转移一部分 具体的id目标节点的id done没有了
这里我们要从7001获取因此填写7001的id 填完后点击done这样插槽转移就准备好了 确认要转移吗输入yes
然后通过命令查看结果 可以看到 目的达成。 4.4、故障转移
集群初识状态是这样的 其中7001、7002、7003都是master我们计划让7002宕机。 4.4.1、自动故障转移
当集群中有一个master宕机会发生什么呢
直接停止一个redis实例例如7002
redis-cli -p 7002 shutdown
1首先是该实例与其它实例失去连接
2然后是疑似宕机 3最后是确定下线自动提升一个slave为新的master 4当7002再次启动就会变为一个slave节点了 4.4.2、手动故障转移
利用cluster failover命令可以手动让集群中的某个master宕机切换到执行cluster failover命令的这个slave节点实现无感知的数据迁移。其流程如下 这种failover命令可以指定三种模式 缺省默认的流程如图1~6歩 force省略了对offset的一致性校验 takeover直接执行第5歩忽略数据一致性、忽略master状态和其它master的意见
案例需求在7002这个slave节点执行手动故障转移重新夺回master地位
步骤如下
1利用redis-cli连接7002这个节点
2执行cluster failover命令
如图 效果