• Redis 分片集群


    目录

    ​编辑一、搭建分片集群

    1、集群结构

    ​编辑 2、准备实例和配置

    3、启动

    4、创建集群

    二、散列插槽

     三、集群伸缩

    四、故障转移

    1、自动故障转移

    2、手动故障转移

    五、RedisTemplate 访问分片集群


    一、搭建分片集群

    1、集群结构

    主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

    1、海量数据存储问题

    2、高并发写的问题

    使用分片集群可以解决上述问题,分片集群特征:

    1、集群中有多个master,每个master保存不同数据

    2、每个master都可以有多个slave节点

    3、master之间通过ping监测彼此健康状态

    4、客户端请求可以访问集群任意节点,最终都会被转发到正确节点 

    这里我们会在同一台虚拟机中开启6个redis实例,模拟分片集群,信息如下:

     2、准备实例和配置

    先删除之前的 7001、7002、7003 这几个目录,重新创建7001、7002、7003、8001、8002、8003 目录

    1. # 进入/tmp目录
    2. cd /tmp
    3. # 删除旧的,避免配置干扰
    4. rm -rf 7001 7002 7003
    5. # 创建目录
    6. mkdir 7001 7002 7003 8001 8002 8003

    在 /tmp 下准备一个新的 redis.conf 文件,内容如下:

    1. port 6379
    2. # 开启集群功能
    3. cluster-enabled yes
    4. # 集群的配置文件名称,不需要我们创建,由redis自己维护
    5. cluster-config-file /tmp/6379/nodes.conf
    6. # 节点心跳失败的超时时间
    7. cluster-node-timeout 5000
    8. # 持久化文件存放目录
    9. dir /tmp/6379
    10. # 绑定地址
    11. bind 0.0.0.0
    12. # 让redis后台运行
    13. daemonize yes
    14. # 注册的实例ip
    15. replica-announce-ip 111.229.153.16
    16. # 保护模式
    17. protected-mode no
    18. # 数据库数量
    19. databases 1
    20. # 日志
    21. logfile /tmp/6379/run.log

    将这个文件拷贝到每个目录下:

    1. # 进入/tmp目录
    2. cd /tmp
    3. # 执行拷贝
    4. echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf

    修改每个目录下的redis.conf,将其中的6379修改为与所在目录一致:

    1. # 进入/tmp目录
    2. cd /tmp
    3. # 修改配置文件
    4. printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf

    3、启动

    因为已经配置了后台启动模式,所以可以直接启动服务:

    1. # 进入/tmp目录
    2. cd /tmp
    3. # 一键启动所有服务
    4. 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

    4、创建集群

    我使用的是Redis6.2版本,集群管理以及集成到了redis-cli中,格式如下:

    /usr/redis/bin/redis-cli --cluster create --cluster-replicas 1 111.229.153.16:7001 111.229.153.16:7002 111.229.153.16:7003 111.229.153.16:8001 111.229.153.16:8002 111.229.153.16:8003
    

    命令说明:

     输入 yes 之后,集群开始创建


    二、散列插槽

    Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上,查看集群信息时就能看到:

    那么为什么要做这样一个插槽呢?

    假设现在,我们要 set num 123 那么这个 num 应该存储在哪个 master 上呢? ,假设我们将其存储到 7001 上,那么到时候我们找的时候又怎么知道它存储在 7001 上呢?

    插槽就是用来解决这个问题的

    数据key不是与节点绑定,而是与插槽绑定。redis 会根据 key 的有效部分计算插槽值,分两种情况:

    1、key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分

    2、key中不包含“{}”,整个key都是有效部分

    例如:key是num,那么就根据num计算,如果是{itcast}num,则根据itcast计算。计算方式是利用CRC16算法得到一个hash值,然后对16384取余,得到的结果就是slot值。

    为什么我们的 key 要去和插槽绑定,而不是和节点绑定呢?

    这是因为我们 redis 的主节点是可能出现宕机等情况的,如果一个节点删除了或者宕机了,那么上面的数据也就会丢失,而如果数据是和插槽绑定,当节点宕机时,我们可以将这个节点对应的插槽转移到活着的节点,集群扩容时,我们也可以将插槽进行转移,这样数据跟着插槽走,就永远都能找到数据所在的位置了

    key 和插槽绑定的体现:

    总结:

    Redis如何判断某个key应该在哪个实例?

    1、将16384个插槽分配到不同的实例

    2、根据key的有效部分计算哈希值,对16384取余

    3、余数作为插槽,寻找插槽所在实例即可

    如何将同一类数据固定的保存在同一个Redis实例?

    这一类数据使用相同的有效部分,例如 key 都以 {typeId} 为前缀


     三、集群伸缩

    redis-cli --cluster提供了很多操作集群的命令,可以通过下面方式查看:

    redis-cli --cluster help

    比如,添加节点的命令:

    add-node
    

    我们可以看到,添加节点的时候需要几个参数:新节点的端口和 IP,已经存在的主机的端口和 IP

    那么为什么我们添加新节点还要知道旧节点的 IP 和端口呢?

    因为当你向集群中添加节点,需要通知集群中的每个角色,那么就得先连上集群,提供了已经存在的主机的端口和 IP,就能联系上集群,从而把新节点的信息通知给每一个节点


    四、故障转移

    1、自动故障转移

    当集群中有一个 master 宕机会发生什么呢?

    1、首先是该实例与其它实例失去连接

    2、然后是疑似宕机:

    3、最后是确定下线,自动提升一个slave为新的master:

    2、手动故障转移

    利用 cluster failover 命令可以手动让集群中的某个 master 宕机,切换到执行 cluster failover 命令的这个 slave 节点,实现无感知的数据迁移。其流程如下:

    再执行命令的那一刻,slave 会向 master 发送一个消息,告诉它 当前这个 slave 将要替换它,为了避免消息的丢失,master 就会拒绝客户端的一切请求

    此时 master 会返回当前的 offset 给 slave ,如果二者 offset 不一致,就进行同步,同步完成之后,slave 与 master 数据就完全一致了。 

    slave 与 master 数据完全一致之后就可以进行故障转移,slave 标记自己成 master 并广播故障转移的结果,master 受到广播后,就转为 slave

    手动的 failover 支持三种不同模式:

    缺省:默认的流程,如图1~6歩

    force:省略了对offset的一致性校验

    takeover:直接执行第5歩,忽略数据一致性、忽略master状态和其它master的意见


    五、RedisTemplate 访问分片集群

    RedisTemplate 底层同样基于 lettuce 实现了分片集群的支持,而使用的步骤与哨兵模式基本一致:

    1、引入 redis 的 starter 依赖

    2、配置分片集群地址

    3、配置读写分离

    与哨兵模式相比,其中只有分片集群的配置方式略有差异,如下:

  • 相关阅读:
    印度证明离开中国制造,富士康将再没奇迹
    在ios系统上实现更改IP地址
    C语言从入门到精通 第二章(数据的表现形式)
    使用Seata实现分布式事务
    Apache-Atlas-2.2.0 独立编译部署
    结构体字节对齐
    PHP代码审计11—逻辑漏洞
    拼多多API批量获取商品详情信息
    IO模型4-NIO三大核心之Buffer
    无涯教程-JavaScript - COUPNUM函数
  • 原文地址:https://blog.csdn.net/weixin_73616913/article/details/134043257