Redis 单节点 ➤ Redis Sentinel 高可用 ➤ Redis Cluster 集群

Posted 木兮同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 单节点 ➤ Redis Sentinel 高可用 ➤ Redis Cluster 集群相关的知识,希望对你有一定的参考价值。


一、Redis 单节点

  • Redis 安装之后,src 目录下多了几个以 redis 开头可执行文件,我们称之为 Redis Shell,下表列出了这些可执行文件的说明:
可执行文件作用
redis-server启动 Redis
redis-cliRedis 命令行客户端
redis-benchmarkRedis 基准测试工具
redis-check-aofRedis AOF 持久化文件监测和修复工具
redis-check-dumpRedis RDB 持久化文件监测和修复工具
redis-sentinel启动 Redis Sentinel
  • 注意要在任意目录下执行这些 Redis Shell 需要将这些运行文件放到 /usr/local/bin 目录下,要不然会报如下命令不识别的错误:
[root@mvxl50258 redis]# redis-cli -h 10.18.26.202 -p 16401
-bash: redis-cli: command not found

启动 Redis

有三种方式启动 Redis:默认配置、运行配置启动、配置文件启动

  • 默认配置
    • 直接在控制台输入 redis-server,之后会使用 Redis 的默认配置来启动。如下演示
  • 运行配置启动
    • redis-server 加上要修改的配置名和值,没有设置的配置将使用默认配置,演示如下
    # redis-server  --configkey1 --configvalue1 --configkey2 --configvalue2
    # 例如:使用 6381 作为端口启动 Redis,那么可以执行:
    $ redis-server --port 6381
    
    • 虽然运行配置可以自定义配置,但如果需要修改的配置较多或者希望将配置保存到文件中,不建议使用这种方式。
  • 配置文件启动
    • 将配置写到指定文件里,例如我们将配置写到了 /apps/redis/sit/redis-16401.conf 中,那么只需要执行如下命令即可启动 Redis
    [root@mvxl50258 sit]# redis-server redis-16401.conf
    
    • 显然通过配置文件启动的方式提供了更大的灵活性,所以大部分生产环境会使用这种方式启动 Redis。

Redis 命令行客户端

现在我们已经启动了 Redis 服务,下面将介绍如何使用 redis-cli 连接、操作 Redis 服务。redis-cli 可以使用如下两种方式连接 Redis 服务器

  • 第一种是交互式方式:通过 redis-cli -h {host} -p {port} 的方式连接到 Redis 服务,之后所有的操作都是通过交互的方式实现,不需要在执行 redis-cli 了,例如:
[root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401
10.18.26.202:16401> set hello world
OK
10.18.26.202:16401> get hello
"world"
  • 第二种是命令方式:用 redis-cli -h {host} -p {port} {command} 就可以直接得到命令的返回结果,例如:
[root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401 get hello
"world"

停止 Redis 服务

  • Redis 提供了 shutdown 命令来停止 Redis 服务,例如要停掉 10.18.26.202 上 16401 端口上的服务,可以执行:
[root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401 shutdown
  • 当使用 redis-cli 再次连接该 Redis 服务时,看到 Redis 已经“失联”。也可以通过查看进程的方式看看是否已经停止,例如使用指令:ps aux|grep redis
[root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401
Could not connect to Redis at 10.18.26.202:16401: Connection refused
Could not connect to Redis at 10.18.26.202:16401: Connection refused
not connected> 
  • 这里有三点要注意:
    • 1)Redis 关闭的过程:断开与客户端的连接、持久化文件生成,是一种相对优雅的关闭方式。
    • 2)除了可以通过 shutdown 命令关闭 Redis 服务以外,还可以通过 kill 进程号的方式关闭掉 Redis,但是不要粗暴地使用 kill -9 强制杀死 Redis 服务,不但不会做持久化操作,还会造成缓冲区等资源不能被优雅关闭,极端情况会造成 AOF 和复制丢失数据的情况。
    • 3)shutdown 还有一个参数 redis-cli shutdown nosave|save,代表是否在关闭 Redis 前生成持久化文件。

二、复制

复制功能是高可用 Redis 的基础,后面介绍的哨兵和集群都是在复制的基础上实现高可用的。所以我们先来看看复制的一些配置,其他复制的相关知识详情请参考:【Redis 开发与运维】复制

建立复制

  • 参与复制的 Redis 实例划分为主节点(master)和从节点(slave)。默认情况下,Redis 都是主节点。每个从节点只能有一个主节点,而主节点可以同时具有多个从节点。复制的数据是单向的,只能由主节点复制到从节点。配置复制的方式有以下三种:
    • 1)在配置文件中加入 slaveof {masterHost} {masterPort} 随 Redis 启动生效。
    • 2)在 redis-server 启动命令后加入 --slaveof {masterHost} {masterPort} 生效。
    • 3)直接使用命令:slaveof {masterHost} {masterPort} 生效。
  • 综上所述,slaveof 命令在使用时,可以运行期动态配置,也可以提前写到配置文件中。
  • slaveof 本身是异步命令,执行 slaveof 命令时,节点只保存主节点信息后返回,后续复制流程在节点内部异步执行。
  • 主从节点复制成功建立后,可以使用 info replication 命令查看复制相关状态。

断开复制

  • slaveof 命令不但可以建立复制,还可以在从节点执行 slaveof no one 来断开与主节点复制关系。断开复制的主要流程:
    • 断开与主节点复制关系
    • 从节点晋升为主节点

三、Redis Sentinel 高可用

在 Redis 主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用方是无法接受的。于是 Redis 提供了 Redis Sentinel(哨兵)架构来解决这个问题,做到真正的不用人工参与的高可用故障转移。本篇只讲如何配置,关于客户端连接以及其他详细知识请参考:【Redis 开发与运维】Redis Sentinel 哨兵

部署拓扑结构图

  • 接下来将以 3 个 Sentinel 节点、1 个主节点、2 个从节点 组成一个 Redis Sentinel 进行说明。具体的物理部署结构如下表:
项目ipport配置文件名称
master10.18.26.20216401redis-16401.conf
slave-110.18.26.20216402redis-16402.conf
slave-210.18.26.20216403redis-16403.conf
sentinel-110.18.26.20226401redis-sentinel-26401.conf
sentinel-210.18.26.20226402redis-sentinel-26402.conf
sentinel-310.18.26.20226403redis-sentinel-26403.conf

部署 Redis 数据节点

  • 启动主节点

    • Redis Sentinel 中 Redis 数据节点没有做任何特殊配置,主节点配置名称:redis-16401.conf
    # 节点端口
    port 16401
    # 是否以守护线程的方式启动,后台运行
    daemonize yes
    # 日志文件
    logfile "logs/16401.log"
    # db文件
    dbfilename "dump-16401.rdb"
    # 存储文件(比如db文件)的目录
    dir "data"
    # 关闭 protected-mode 模式,开启时,需要配置 bind IP,表示只接收来自于该 IP 地址列表的请求,关闭后可以接受所有 IP 请求
    protected-mode no
    # 当在900秒改变了1条数据,将触发 bgsave 操作
    save 900 1
    # 当在300秒改变了10条数据,将触发 bgsave 操作
    save 300 10
    # 当在60秒改变了10000条数据,将触发 bgsave 操作
    save 60 10000 
    
    • 启动主节点:
    [root@mvxl50258 sit]# redis-server redis-16401.conf
    
    • 确认是否启动。一般来说只需要 ping 命令检测一下就可以,确认 Redis 数据节点是否已经启动。
    [root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401 ping
    PONG
    
    • 也可以使用 ps 命令查看进程,看看是否启动成功:
    [root@mvxl50258 sit]# ps aux|grep redis
    ...
    root      5918  0.0  0.0 143912  7572 ?        Ssl  14:42   0:00 redis-server *:16401
    ...
    
  • 启动两个从节点

    • 两个从节点配置一样,和主节点不同的是多了 slaveof 配置,配置名称:redis-16402.conf、redis-16403.conf
    # 节点端口
    port 16402
    # 是否以守护线程的方式启动,后台运行
    daemonize yes
    # 日志文件
    logfile "logs/16402.log"
    # db文件
    dbfilename "dump-16402.rdb"
    # 存储文件(比如db文件)的目录
    dir "data"
    # 关闭 protected-mode 模式,开启时,需要配置 bind IP,表示只接收来自于该 IP 地址列表的请求,关闭后可以接受所有 IP 请求
    protected-mode no
    # 当在900秒改变了1条数据,将触发 bgsave 操作
    save 900 1
    # 当在300秒改变了10条数据,将触发 bgsave 操作
    save 300 10
    # 当在60秒改变了10000条数据,将触发 bgsave 操作
    save 60 10000 
    # 表示当前从节点所指向的主节点
    slaveof 10.18.26.202 16401
    
    • 两个从节点都启动后,ps aux|grep redis 查看启动状态
    [root@mvxl50258 sit]# ps aux|grep redis
    ...
    root      5918  0.0  0.0 145960  9704 ?        Ssl  14:42   0:00 redis-server *:16401         
    root      6570  0.0  0.0 145960  9640 ?        Ssl  14:48   0:00 redis-server *:16402         
    root      6688  0.0  0.0 145960  9644 ?        Ssl  14:49   0:00 redis-server *:16403 
    ...
    
  • 确认主从关系

    • 在主节点和从节点分别使用 info replication 命令查看启动情况
    • 主节点视角,它有两个从节点,分别是 10.18.26.202:1640210.18.26.202:16403
    [root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16401 info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=10.18.26.202,port=16402,state=online,offset=392,lag=0
    slave1:ip=10.18.26.202,port=16403,state=online,offset=392,lag=1
    master_replid:d6a1579d2c29dd2355baee3dd7151b0a7266f15b
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:392
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:392
    
    • 从节点视角,它的主节点是 10.18.26.202:16401
    [root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 16402 info replication
    # Replication
    role:slave
    master_host:10.18.26.202
    master_port:16401
    master_link_status:up
    master_last_io_seconds_ago:3
    master_sync_in_progress:0
    slave_repl_offset:728
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:d6a1579d2c29dd2355baee3dd7151b0a7266f15b
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:728
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:728
    

部署 Sentinel 节点

三个 Sentinel 节点的部署方法是完全一致的(端口不同),下面以 sentinel-1 节点的部署为例子进行说明。

  • 配置 Sentinel 节点
    • 配置文件名称:redis-sentinel-26401.conf,配置的默认端口是 26401。
    • 配置文件中 sentinel monitor mymaster 10.18.26.202 16401 2 这个配置表示,当前 sentinel 节点需要监控 10.18.26.202:16401 这个主节点,2 代表判断主节点失败至少需要 2 个 Sentinel 节点同意,mymaster 是主节点的别名。
    port 26401
    daemonize yes
    logfile "logs/26401.log"
    dir "data"
    protected-mode no
    sentinel monitor mymaster 10.18.26.202 16401 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000
    
  • 启动 Sentinel 节点
    • 方式一:使用 redis-sentinel 命令
    [root@mvxl50258 sit]# redis-sentinel redis-sentinel-26401.conf
    
    • 方式二:使用 redis-server 命令加 --sentinel
    [root@mvxl50258 sit]# redis-server redis-sentinel-26401.conf --sentinel
    
  • 确认已启动
    • ps aux|grep redis 查看启动状态:
    [root@mvxl50258 sit]# ps aux|grep redis
    ...
    root      5918  0.0  0.0 145960  9720 ?        Ssl  14:42   0:01 redis-server *:16401         
    root      6570  0.0  0.0 145960  9704 ?        Ssl  14:48   0:01 redis-server *:16402         
    root      6688  0.0  0.0 145960  9708 ?        Ssl  14:49   0:01 redis-server *:16403         
    root      8436  0.1  0.0 143912  7708 ?        Ssl  15:05   0:01 redis-sentinel *:26401 [sentinel]       
    root      9934  0.0  0.0 143912  7704 ?        Ssl  15:19   0:00 redis-sentinel *:26402 [sentinel]       
    root      9939  0.0  0.0 143912  7704 ?        Ssl  15:19   0:00 redis-sentinel *:26403 [sentinel]       
    ...
    
    • Sentinel 节点本质上是一个特殊的 Redis 节点,所以也可以用 info 命令查询节点的相关信息,全部启动之后,Sentinel 节点能够彼此感知到对方,也能够感知到 Redis 数据节点
    [root@mvxl50258 sit]# redis-cli -h 10.18.26.202 -p 26401 info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=10.18.26.202:16401,slaves=2,sentinels=3
    
    • 可以看到最后一行,主节点别名为 mymaster,地址是 10.18.26.202:16401,有 2 个从节点,3 个哨兵节点

部署技巧

  • Sentinel 节点不应该部署在一台物理机器上,防止机器挂了导致哨兵全不可用。
  • 部署至少三个且奇数个的 Sentinel 节点,这里要注意并非每个数据节点都需要一个哨兵节点,其实只使用一个哨兵节点也是可以的,使用多个哨兵节点是为了 Sentinel 也达到高可用。
  • Sentinel 节点集合可以只监控一个主节点,也可以监控多个主节点,所以多个主节点的情况下,可以选择一套 Sentinel 或者多套 Sentinel ,如何选择?
    • 一套 Sentinel:这种方案降低了维护成本,因为只需要维护固定个数的 Sentinel 节点,但如果这套 Sentinel 节点集合出现异常,可能会对多个 Redis 数据节点造成影响。如果监控的 Redis 数据节点较多,会造成 Sentinel 节点产生过多的网络连接。
    • 多套 Sentinel:优缺点和上面相反,每个 Redis 主节点都有自己的 Sentinel 节点集合,会造成资源浪费。优点也明显,每套 Redis Sentinel 都是彼此隔离的。
    • 如果 Sentinel 节点集合监控的是同一个业务的多个主节点集合,那么使用方案一,否则一般建议采用方案二。
  • 在生产环境一般我们会配置密码
    • 设置 Redis 登录密码,需要在配置文件中加上 requirepass 配置,例如:requirepass 123456,登录密码为 123456
    • 如果设置了登录密码,而且使用了主从的话,还需要配置主从认证密码,否则主从不能同步,配置项是 masterauth,例如:masterauth:123456
    • 如果设置了登录密码,而且使用了哨兵的话,需要在哨兵节点配置 sentinel auth-pass mymaster 123456

四、Redis Cluster 集群

Redis Sentinel 完美的解决了自动故障转移问题,但是当遇到单机内存、并发、流量等瓶颈时,我们就需要考虑采用 Cluster 架构方案达到负载均衡的目的。本小节也是只涉及集群部署相关,关于客户端如何连接集群以及因为集群出现的诸如集群倾斜等问题请参考:【Redis 开发与运维】Redis Cluster 集群

准备节点

  • Redis 集群节点数量至少为 6 个才能保证组成完整高可用的集群。每个节点需要开启配置 cluster-enabled yes,让 Redis 运行在集群模式下。建议为集群内所有节点统一目录,一般划分为三个目录:conf、data、log,分别存放配置、数据和日志相关文件。
  • 我们这里即将部署 3 个集群主节点,以及对应的 3 个从节点,具体 6 个节点配置结构如下:
项目ipport配置文件名称
master-110.18.26.2028379redis-8379.conf
master-210.18.26.2028380redis-8380.conf
master-310.18.26.2028381redis-8381.conf
slave-110.18.26.2028382redis-8382.conf
slave-210.18.26.2028383redis-8383.conf
slave-310.18.26.2028384redis-8384.conf
  • 6 个节点配置文件都一致,只是端口号各自不一,例如 8379 节点的配置:
# 节点端口
port 8379
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位毫秒
cluster-node-timeout 15000
# 集群内部配置文件
cluster-config-file "node-8379.conf"
# 是否以守护线程的方式启动,后台运行
daemonize yes
# 日志文件
logfile "../logs/8379.log"
# db文件
dbfilename "dump-8379.rdb"
# 存储文件(比如db文件、集群配置文件)的目录
dir "../data"
# 关闭 protected-mode 模式,开启时,需要配置 bind IP,表示只接收来自于该 IP 地址列表的请求,关闭后可以接受所有 IP 请求
protected-mode no
# 登录密码
requirepass 123456
# 主从认证密码
masterauth 123456
# 当在900秒改变了1条数据,将触发 bgsave 操作
save 900 1
# 当在300秒改变了10条数据,将触发 bgsave 操作
save 300 10
# 当在60秒改变了10000条数据,将触发 bgsave 操作
save 60 10000 
  • 启动所有节点,第一次启动时如果没有集群配置文件,它会自动创建一份,文件名称采用 cluster-config-file 参数项控制,建议采用 node-{port}.conf 格式定义。
    • 当集群内节点信息发生变化,如添加节点、节点下线,故障转移等,节点会自动保存集群状态到配置文件中。
    • Redis 自动维护集群配置文件,不要手动修改,防止节点重启时产生集群信息错乱。
  • 集群配置文件记录了集群初始状态,这里最重要的是节点 ID,一个 40 位 16 进制字符串,用于唯一标识集群内一个节点。它不同于运行 ID,节点 ID 在集群初始化时只创建一次,节点重启时会加载集群配置文件进行重用。在节点 8380 执行 cluster nodes 命令获取集群节点状态:
10.18.26.202:8379> cluster nodes
e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950 :8379@18379 myself,master - 0 0 0 connected
  • 每个节点目前只能识别出自己的节点信息。我们启动 6 个节点,但每个节点彼此并不知道对方的存在,下面通过节点握手让 6 个节点彼此建立联系从而组成一个集群。

节点握手

  • 节点握手是指一批运行在集群模式下的节点通过 Gossip 协议彼此通信,达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命令:cluster meet {ip} {port}
  • 我们只需要在集群内任意节点上执行 cluster meet 命令加入新节点,握手状态会通过消息在集群内传播,这样其他节点会自动发现新节点并发起握手流程。可以执行 cluster nodes 命令确认 6 个节点都彼此感知并组成集群。
  • 例如可以在 8379 执行 cluster meet 10.18.26.202 8380,然后 8379 和 8380 就进行了握手通信,形成了一个集群,要让其他节点也加入的话,一样的在集群任意一个节点使用该命令执行即可。可以使用 cluster nodes 查看集群状态:
10.18.26.202:8379> cluster nodes
bbabd05ed24d32097b10b67097b6fecea45ab157 10.18.26.202:8380@18380 master - 0 1625729870380 1 connected
799d45193d2facef602e4020d1af5abaa84db555 10.18.26.202:8382@18382 master - 0 1625729872385 3 connected
77bff4b6fdd55b140b9c7cd2a1febad20a3225fe 10.18.26.202:8384@18384 master - 0 1625729870000 4 connected
e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950 10.18.26.202:8379@18379 myself,master - 0 1625729871000 0 connected
a9925fe051bad21e9a00acb5818b03b4d0728660 10.18.26.202:8381@18381 master - 0 1625729869000 2 connected
1e9b5fe30097a5afbae884a9512de1f933610eb5 10.18.26.202:8383@18383 master - 0 1625729871383 5 connected
  • 节点建立握手之后集群还不能正常工作,这时集群处于下线状态,所有的数据读写都被禁止。使用 cluster info 命令(如下)获取集群当前状态,输出内容看被分配的槽是 0,是因为目前所有的槽没有分配到节点,因此集群无法完成槽到节点的映射。
10.18.26.202:8379> cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:0
cluster_stats_messages_ping_sent:61
cluster_stats_messages_pong_sent:70
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:136
cluster_stats_messages_ping_received:70
cluster_stats_messages_pong_received:66
cluster_stats_messages_received:136

分配槽

  • 通过 cluster addslots 命令为节点分配槽。将 16384 个slot 平均分配给 6379、6380、6381 三个节点(如果有登录密码的话需要加上 -a 参数)。命令如下:
redis-cli -h 10.18.26.202 -p 8379 cluster addslots {0..5461}
redis-cli -h 10.18.26.202 -p 8380 cluster addslots {5462..10922}
redis-cli -h 10.18.26.202 -p 8381 cluster addslots {10923..16383}
  • 使用 cluster info 命令再次查看当前集群状态,当前集群状态是 OK,集群进入在线状态:
10.18.26.202:8379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:0
cluster_stats_messages_ping_sent:294
cluster_stats_messages_pong_sent:306
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:605
cluster_stats_messages_ping_received:306
cluster_stats_messages_pong_received:299
cluster_stats_messages_received:605
  • 执行 cluster nodes 命令可以看到节点和槽的分配关系:
10.18.26.202:8379> cluster nodes
bbabd05ed24d32097b10b67097b6fecea45ab157 10.18.26.202:8380@18380 master - 0 1625730189000 1 connected 5462-10922
799d45193d2facef602e4020d1af5abaa84db555 10.18.26.202:8382@18382 master - 0 1625730188949 3 connected
77bff4b6fdd55b140b9c7cd2a1febad20a3225fe 10.18.26.202:8384@18384 master - 0 1625730189951 4 connected
e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950 10.18.26.202:8379@18379 myself,master - 0 1625730187000 0 connected 0-5461
a9925fe051bad21e9a00acb5818b03b4d0728660 10.18.26.202:8381@18381 master - 0 1625730187947 2 connected 10923-16383
1e9b5fe30097a5afbae884a9512de1f933610eb5 10.18.26.202:8383@18383 master - 0 1625730189000 5 connected
  • 目前还有三个节点没有使用,作为一个完整的集群,每个负责处理槽的节点应该具有从节点,保证当它出现故障时可以自动进行故障转移
  • 集群模式下,Redis 节点分为主节点和从节点。首次启动的节点和被分配槽的节点都是主节点,从节点负责复制主节点槽信息和相关的数据
  • 使用 cluster replicate {nodeId} 命令让一个节点成为从节点。其中命令执行必须在对应的从节点上执行,nodeId 是要复制主节点的节点 ID。命令如下:
10.18.26.202:8382> cluster replicate e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950
10.18.26.202:8383> cluster replicate bbabd05ed24d32097b10b67097b6fecea45ab157
10.18.26.202:8384> cluster replicate a9925fe051bad21e9a00acb5818b03b4d0728660
  • 通过 cluster nodes 查看集群状态和复制关系:
10.18.26.202:8379> cluster nodes
bbabd05ed24d32097b10b67097b6fecea45ab157 10.18.26.202:8380@18380 master - 0 1625731527344 1 connected 5462-10922
799d45193d2facef602e4020d1af5abaa84db555 10.18.26.202:8382@18382 slave e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950 0 1625731528346 3 connected
77bff4b6fdd55b140b9c7cd2a1febad20a3225fe 10.18.26.202:8384@18384 slave a9925fe051bad21e9a00acb5818b03b4d0728660 0 1625731526343 4 connected
e7348a6257bc72e0fadba13f0ef0a6ecf9ea1950 10.18.26.202:8379@18379 myself,master - 0 1625731525000 0 connected 0-5461
a9925fe051bad21e9a00acb5818b03b4d0728660 10.18.26.202:8381@18381 master - 0 1625731526000 2 connected 10923-16383
1e9b5fe30097a5afbae884a9512de1f933610eb5 10.18.26.202:8383@18383 slave bbabd05ed24d32097b10b67097b6fecea45ab157 0 1625731526000 5 connected
  • 目前为止,我们依照 Redis 协议手动建立了一个集群。它由 6 个节点构成,3 个主节点负责处理槽和相关数据,3 个从节点负责故障转移。手动搭建集群便于理解集群建立的流程和细节,不过会从中发现搭建集群需要很多步骤,当集群节点众多时,必然会加大搭建集群的复杂度和运维成本。因此 Redis 官方提供了 redis-trib.rb 工具方便我们快速搭建集群。

redis-trib.rb 搭建集群

  • redis-trib.rb 介绍

    • 它采用 Ruby 实现的 Redis 集群管理工具。内部通过 Cluster 相关命令帮我们简化集群创建、检查、槽迁移和均衡等常见运维操作,使用之前需要安装 Ruby 依赖环境。
  • 准备节点

    • 和上面配置内容一样,然后还需要启动所有节点
  • 创建集群

    • 启动好 6 个节点之后,使用 redis-trib.rb create 命令完成节点握手和槽分配过程,--replicas 表示每个主节点配备几个从节点,这里设置为 1,节点列表顺序用于确定主从角色,先主节点之后是从节点,命令如下:
    redis-trib.rb create --replicas 1 10.18.26.202:8379 10.18.26.202:8382 10.18.26.202:8380 10.18.26.202:8383 10.18.26.202:8381 10.18.26.202:8384
    
    • 命令执行后,会打印主从节点角色分配计划,同意这份计划之后输入 yes,它会开始节点握手和槽分配操作。这里要注意节点地址必须是不包含任何槽和数据的节点,否则会拒绝创建集群。
  • 集群完整性检查

    • 集群完整性指所有的槽都分配到存活的主节点上,只要 16384 个槽中有一个没有分配给节点则表示集群不完整。可以使用 redis-trib.rb check 命令检测之前创建的两个集群是否成功,check 命令只需要给出集群中任意一个节点地址就可以完成整个集群的检查工作。
  • 数据迁移

    • 应用 Redis 集群时,常需要把单机 Redis 数据迁移到集群环境。redis-trib.rb 工具提供了导入功能,用于数据从单机向集群环境迁移的场景,命令如下:
    $ redis-trib.rb import host:port --from <arg> --copy --replace
    
    • redis-trib.rb import 命令内部采用批量 scan 和 migrate 的方式迁移数据。这种迁移方式存在以下缺点:
      • 1)迁移只能从单机节点向集群环境导入数据。
      • 2)不支持在线迁移数据,迁移数据时应用方必须停写,无法平滑迁移数据。
      • 3)迁移过程中途如果出现超时等错误,不支持断点续传只能重新全量导入。
      • 4)使用单线程进行数据迁移,大数据量迁移速度过慢。
    • 正因为这些问题,社区开源了很多迁移工具,这里推荐一款唯品会开发的 redis-migrate-tool,该工具可满足大多数 Redis迁移需求,特点如下:
      • 支持单机、Twemproxy、Redis Cluster、RDB/AOF 等多种类型的数据迁移。
      • 工具模拟成从节点基于复制流迁移数据,从而支持在线迁移数据,业务方不需要停写。
      • 采用多线程加速数据迁移过程且提供数据校验和查看迁移状态等功能。

以上是关于Redis 单节点 ➤ Redis Sentinel 高可用 ➤ Redis Cluster 集群的主要内容,如果未能解决你的问题,请参考以下文章

Redis 单节点 ➤ Redis Sentinel 高可用 ➤ Redis Cluster 集群

Redis 单节点 ➤ Redis Sentinel 高可用 ➤ Redis Cluster 集群

Redis_12_Redis集群实现Sentinel哨兵应对高可用

Redis02——Redis单节点安装

Redis单节点部署

redis单节点及集群搭建