第十一章、redis集群(cluster)

第十一章、redis集群(cluster)

1、是什么?

1、由于数据量过大,单个Master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点间共享数据的程序集。

2、看图秒懂

  • image-20240405134102033

3、总之

  • redis是一个提供在多个redis节点间共享数据的程序集
  • redis集群可以支持多个master

2、能干嘛?

1、redis集群支持多个master,每个master可以挂多个slave

  • 读写分离
  • 支持数据的高可用
  • 支持海量数据的读写操作

2、Cluster自带sentinel的故障转移机制,内置高可用的支持(自带哨兵)

3、槽位slot负责分配到各个物理服务节点,有对应的集群来负责维护结点、插槽和数据之间的关系

3、集群算法—分片—槽位slot

1、redis集群的槽位slot

1、这里redis集群引入的哈希槽的概念

2、就是说redis集群有16384个槽位,通过keyCRC16取模来计算,我这个key值要放在哪个槽位

3、可以理解为,学校里面的每个宿舍,一个宿舍住一个key,算一个槽位。学校总共有16384个宿舍,槽位

2、redis集群的分片

1、redis集群会将存储的数据分配到多台redis机器上。每个redis实例就被认为是整个数据的分片

2、如何找到给定key的分片

  • 也是通过key进行CRC16(key)算法处理并通过对总分片数量取模,然后使用确定性哈希函数

3、可以理解为,数据要放到槽位里面(宿舍),然后有多台redis机器,我们把每台机器所存的槽位范围设置成分片。如,立德苑1栋分配了多少个宿舍(槽位),有几栋这样的宿舍楼,就是有几个分片

3、优势

1、方便扩所容量和数据分派查找。

2、就像二分查找法算法一样,方便

4、slot槽位映射,三种方法

1、就是如何来找到槽位和数据之间的映射,哪个数据放哪个槽位?

1、哈希取余分区

1、就是有几台服务器,就有几个分区,几个分母

2、公式:hash(key)/xx。其中xx是分区

3、缺点

  • 扩容和缩容会比较麻烦
  • 如果分母变了,根据计算出来的槽位所对应的数据位置就会不可控
  • 会导致hash取余全部数据重新洗牌

2、一致性哈希算法分区

1、是什么?

1、为了解决这个问题:分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不OK了。

2、能干嘛?

1、提出一致性hash解决方法

2、就是为了解决哈希取余分区中,分母改变影响客户端到服务器的映射关系

3、目的:如果分母变了,也尽可能减少影响客户端到服务器的映射

3、三大步骤

1、算法构建一致性哈希环

  • 就是用哈希函数按照算法,产生哈希值。然后构成一个集合。
  • 这个集合有0~2^32-1的大小
  • 然后用逻辑控制,将这个集合头尾相连,成为一个环
  • 如图
  • image-20240405135725707

2、redis服务器IP节点映射

  • 将各个服务器使用hash进行一个哈希,具体通过ip或则主机名作为关键字,来创建一个哈希。
  • 每个机器就能在哈希环上确定一个位置。
  • 如图所示
  • image-20240405135915698

3、key落到服务器的落键规则

  • 我现在要存储一个key值,我们要计算key 的哈希值。使用相同的哈希函数计算出hash值就可以确定数据在环上的位置。
  • 然后沿着这个环,顺时针走遇到第一台服务器,这个key值就在这个服务器上(节点)
  • 如图
  • image-20240405140107503
4、优点

1、一致性哈希算法的容错性

  • 就是如上图,NodeC挂了,ObjectC数据要顺时针走,发现C坏了,就去找Node D 数据从而能保存
  • 如图
  • image-20240405140325703

2、一致性哈希算法的扩展性

  • 我要加入一台服务器还是挺简单的,我可以通过redis对服务器ip的映射,然后就可以在hash环上新增一个节点(服务器)
5、缺点

1、hash环的数据倾斜问题

  • 如果只有2个节点,就会发现数据倾斜的问题严重。
  • 就是一个节点卖死卖活,另一个节点非常清闲
  • 如图
  • image-20240405140621667
6、总结

image-20240405140705556

3、哈希槽分区

1、是什么?

1、实质就是一个数组,数组大小为[0,2^14-1] =16384

2、能干嘛?

1、解决均匀分配的问题

2、就是在数据和服务器之间又加了一层。称为哈希槽(slot)

3、主要目的是:把粒度变大,从而达到机器整体均匀分布数据

3、要用多少个hash槽

1、一般是16384。但没强制要求

2、公式

HASH_SLOT = CRC16(key)mod 16384

3、通过上面公式得到,就是数据位置

4、如图(解释)

image-20240405141220772

5、面试题:为什么redis最大槽是16384个

1、解释一

1、CRC16算法产生的hash是2^16

2、因为心跳包如果用2^16次方/1024 = 8KB

3、心跳包如果用2^14/1024 = 2KB

4、这样对网络传输的压力减小,每秒要发一定数量的ping心跳包,浪费带宽

2、解释二

1、redis集群主节点的数量不会太大,基本不会超过1000个

3、解释三

1、槽位越小,节点少的情况下,压缩比越高,越容易传输

4、实验案例

1、三主三从集群配置

1、配置三台虚拟机

1、各自新建

mkdir -p /myredis/cluster

2、其中-p是建立多级文件夹

2、新建6个独立redis实例服务

1、IP:192.168.171.129 6381和6382

  • 6381

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6381
    logfile "/myredis/cluster/cluster6381.log"
    pidfile /myredis/cluster6381.pid
    dir /myredis/cluster
    dbfilename dump6381.rdb
    appendonly yes
    appendfilename "appendonly6381.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6381.conf
    cluster-node-timeout 5000     
  • 6382

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6382
    logfile "/myredis/cluster/cluster6382.log"
    pidfile /myredis/cluster6382.pid
    dir /myredis/cluster
    dbfilename dump6382.rdb
    appendonly yes
    appendfilename "appendonly6382.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6382.conf
    cluster-node-timeout 5000
    

2、IP:192.168.171.132 6383和6384端口

  • 6383

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6383
    logfile "/myredis/cluster/cluster6383.log"
    pidfile /myredis/cluster6383.pid
    dir /myredis/cluster
    dbfilename dump6383.rdb
    appendonly yes
    appendfilename "appendonly6383.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6383.conf
    cluster-node-timeout 5000
  • 6384

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6384
    logfile "/myredis/cluster/cluster6384.log"
    pidfile /myredis/cluster6384.pid
    dir /myredis/cluster
    dbfilename dump6384.rdb
    appendonly yes
    appendfilename "appendonly6384.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6384.conf
    cluster-node-timeout 5000

3、IP:192.168.171.133 6385和6386端口

  • 6385

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6385
    logfile "/myredis/cluster/cluster6385.log"
    pidfile /myredis/cluster6385.pid
    dir /myredis/cluster
    dbfilename dump6385.rdb
    appendonly yes
    appendfilename "appendonly6385.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6385.conf
    cluster-node-timeout 5000
  • 6386

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6386
    logfile "/myredis/cluster/cluster6386.log"
    pidfile /myredis/cluster6386.pid
    dir /myredis/cluster
    dbfilename dump6386.rdb
    appendonly yes
    appendfilename "appendonly6386.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6386.conf
    cluster-node-timeout 5000

4、启动这6台redis服务器

redis-server /myredis/cluster/redisCluster638x.conf
  • x是端口号

5、通过redis-cli命令为6台机器构建集群关系

redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.171.129:6381 192.168.171.129:6382 192.168.171.132:6383 192.168.171.132:6384 192.168.171.133:6385 192.168.171.133:6386
  • 成功如图
  • image-20240405150419448

6、连接诶6381作为切入点,查看集群状态

  • info replication
  • cluster info
  • cluster nodes

3、梳理逻辑

1、master主机:6381

  • slave从机:6384

2、master主机:6383

  • slave从机:6386

3、master主机:6385

  • slave从机:6382

4、看下图可知以上的逻辑

image-20240405151425159

2、3主3从redis集群读写

1、对链接成功的6381进行新增key

1、出现问题

ERR wrong number of arguments for 'set' command

2、如图

image-20240405151557903

3、这个问题的出现,是因为槽位的范围有问题。要路由到位

4、就是我现在加入的key,要分给一个槽位。但是16384个槽位,要进行分区,就是宿舍和宿舍楼的关系。我刚刚加入这个k1,槽位的范围不对,就无法加入才会报错

2、解决以上问题

1、我们只要加入防止路由失效假如一个参数-c就行

2、先退出

quit

3、加入-c参数

redis-cli -a 111111 -p 6381 -c

4、如图

image-20240405152255790

3、查看某个key对应的槽位

1、命令

cluster keyslot xxx(key)

3、主从容错切换迁移案例

1、容错切换迁移

1、主6381和从机切换

1、我们直接把6381shutdown掉

2、看看6384会不会顶替6381的master角色

  • 结果
  • image-20240405152749850

3、我们把6381从新启动,看看原来的master还能上位吗

  • image-20240405152934218
  • 答案是否定的,6381和6384的角色互换了

2、集群不包住数据一致性100%

1、就是说,再怎么样,也会有数据丢失

2、就如果6381死了,在其他slave上位期间,是不存数据的,会丢失一点点

3、手动故障转移or 角色互相调整

1、我容错迁移的时候,发现了6381和6384的角色互相调换了。

2、不符合我们的原始设计图。我们现在要换回来,怎么办

1、操作

1、我们重新登录要还原上位的那台机器

2、这里就是6381端口的主机

3、我们登入6381

  • redis-cli -a 111111 -p 6381 -c

4、然后使用命令

  • cluster failover

5、结果如图

image-20240405153554192

4、主从扩容案例

1、新建6387和6388两个服务器的配置文件

1、IP:192.168.171.133 6387和6388端口的服务器配置文件

  • 6387

    bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6387
    logfile "/myredis/cluster/cluster6387.log"
    pidfile /myredis/cluster6387.pid
    dir /myredis/cluster
    dbfilename dump6387.rdb
    appendonly yes
    appendfilename "appendonly6387.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6387.conf
    cluster-node-timeout 5000
  • 6388

  • bind 0.0.0.0
    daemonize yes
    protected-mode no
    port 6388
    logfile "/myredis/cluster/cluster6388.log"
    pidfile /myredis/cluster6388.pid
    dir /myredis/cluster
    dbfilename dump6388.rdb
    appendonly yes
    appendfilename "appendonly6388.aof"
    requirepass 111111
    masterauth 111111
    
    cluster-enabled yes
    cluster-config-file nodes-6388.conf
    cluster-node-timeout 5000

2、启动87/88实例

redis-server /myredis/cluster/redisCluster6387.conf 
redis-server /myredis/cluster/redisCluster6388.conf 

3、将87/88节点加入原集群

1、把6387和6388作为master加入集群

2、这里要注意,我们需要一个领路人(就是原本集群中有的端口机器)来帮助我们加入集群

2、命令

redis-cli -a 密码 --cluster add-node 自己实际IP地址:6387 自己实际IP地址:原有集群的端口号

3、这里我们以6381作为领路人,将6387加入原有集群

redis-cli -a 111111  --cluster add-node 192.168.171.133:6387 192.168.171.129:6381
  • 如图算成功
  • image-20240405154526644

4、检查集群的情况

  • 命令

  • redis-cli -a 密码 --cluster check 真实ip地址:6381
  • 这里以6381为例

  • redis-cli -a 111111 --cluster check 192.168.171.129:6381
  • 如图算是真正加入成功

  • image-20240405154726613

5、重新分配槽号(reshard)

1、就是说我们现在加入的这个6387并没有分到slot槽号,就是没办法加入和查询数据。所以我们要分配槽号资源

2、命令

redis-cli -a 密码 --cluster reshard IP地址:端口号

3、这里以6381进行

redis-cli -a 111111 --cluster reshard 192.168.171.129:6381

4、如图

image-20240405155545360

6、检查集群情况

1、和第4步骤一样的命令

  • 命令

  • redis-cli -a 密码 --cluster check 真实ip地址:6381
  • 这里以6381为例

  • redis-cli -a 111111 --cluster check 192.168.171.129:6381
  • 如图算是真正加入成功

  • image-20240405155747430

7、为主节点6387分配从节点6388

1、命令

redis-cli -a 密码 --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID

2、这里以6388为例

redis-cli -a 111111 --cluster add-node 192.168.171.133:6388 192.168.171.133:6387 --cluster-slave --cluster-master-id b1c59455049af0e2b81cc6d961c10585159546b3

3、如图

image-20240405160141879

8、检查集群情况

  • 命令

  • redis-cli -a 密码 --cluster check 真实ip地址:6381
  • 这里以6381为例

  • redis-cli -a 111111 --cluster check 192.168.171.129:6381
  • 如图算是真正加入成功

  • image-20240405160302758

5、主从缩容案例

1、这里我们要将6387和6388这两个机器下线,达到缩容的效果

1、获取节点6388节点ID

1、检查集群情况

redis-cli -a 111111 --cluster check 192.168.171.133:6388

2、6388结点的ID

5019119607f445e7e075979ba345c97394872293

2、从集群中将4号从节点6388删除

1、命令

redis-cli -a 密码 --cluster del-node ip:从机端口 从机6388节点ID

2、这里以6388为例

redis-cli -a 111111 --cluster del-node 192.168.171.133:6388 5019119607f445e7e075979ba345c97394872293
  • 如图算是成功

image-20240405160829204

3、将6387分配到的槽号清空

1、我们这里将6387之前分配到的槽号清空

2、然后重新分配:命令和reshare一样

3、我们这里把6387的槽号,全部给6381。也可以各个机器分一点,看个人

redis-cli -a 111111 --cluster reshard 192.168.171.129:6381

4、如图算是成功

image-20240405161732642

4、检查集群情况

1、这里检查6381。看看有没有分到6387的槽位

redis-cli -a 111111 --cluster check 192.168.171.129:6381

2、如图确实分到了

image-20240405161909623

5、删除6387节点

1、槽位也回归了,现在可以正式放心的删除6387了

2、命令

redis-cli -a 密码 --cluster del-node ip:端口 6387节点ID

3、例子

redis-cli -a 111111 --cluster del-node 192.168.171.133:6387 b1c59455049af0e2b81cc6d961c10585159546b3

4、删除成功如图

  • image-20240405162055792

6、检查集群情况

1、这里检查6381。看看有没有分到6387的槽位

redis-cli -a 111111 --cluster check 192.168.171.129:6381

2、如图确实6387/6388都被删除了

image-20240405162141889

5、集群常用操作命令和CRC16算法分析

1、注意

1、在不同的slot槽位下多键操作不太好,提示符占位符

2、如图下操作

  • image-20240405165201642

3、我们发现设置了3个key,在不同的分片里面,我们要全部获取,就发现,不同的slot槽位,值无法获取

4、所以我们引用了占位符:{}

5、操作

mset k1{a} 11 k2{a} 22 k3{a} 33
mget k1{a} k2{a} k3{a}

6、结果如图

image-20240405165502485

2、常用命令

1、集群是否要完整才能对外服务

1、现在有3个master,如果一个master挂了,每个master负责的slot就会有变化。2/3个slot。redis默认就不对外服务,因为不完整了

2、我们可以设置一个配置,强行对外服务

cluster-require-full-coverage yes #默认是no

2、获取槽位数字编号

1、命令

CLUSTER COUNTKEYSINSLOT xxxx槽号

2、如图

image-20240405165934590

3、1表示槽号被占用了

4、0表示槽号没被占用

3、键名称指令

CLUSTER KEYSLOT key(key的名称)

image-20240405170059053

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇