Redis 集群


本文目录

  • Redis 集群
  • 1. 主从复制
  • 1.1 主从复制简介
  • 1.2 高可用集群方案
  • 1.3 主从复制工作流程
  • 1.3.1 建立连接
  • 1.3.2 数据同步
  • 1.3.3 命令传播阶段
  • 1.4 心跳机制
  • 1.5 主从复制的常见问题
  • 2. 哨兵模式
  • 2.1 哨兵简介
  • 2.2 启用哨兵
  • 2.3 哨兵工作原理
  • 2.3.1 监控阶段
  • 2.3.2 通知阶段
  • 2.3.3 故障转移阶段
  • 3. 集群
  • 3.1 集群结构设计
  • 3.2 集群搭建
  • 3.3 设置与获取数据
  • 3.4 主从下线和主从切换
  • 3.4.1 slave下线
  • 3.4.2 master下线


1. 主从复制

1.1 主从复制简介

单机Redis的问题:

  • 机器故障:可能丢数据。
  • 容量瓶颈:存不下,硬件有瓶颈。

结论:多台服务器互相复制,实现冗余。

需要解决的问题:如何数据同步。

由主服务器往从服务器复制数据,就叫主从同步。

主服务器
               |
               |
 --------------|--------------
|              |              |
|              |              |
slave1       slave2        slave3

master:

  • 只写不读。
  • 写操作后数据自动同步到slave。

slave:

  • 只读不写

1.2 高可用集群方案

  • 如果master故障,推选出一台slave当做master。
  • 如果master压力过大,可在一个slave下继续接slave,把这个slave当做master。
  • 引入哨兵机制,做一个master集群。

好处:

  • 读写分离。提高读写能力。
  • 负载均衡。
  • 故障恢复。
  • 数据冗余。实现数据的热备份,是AOF和RDB之外的一个手段。
  • 高可用的基石。

1.3 主从复制工作流程

  1. 建立连接
  2. 数据同步
  3. 命令传播
1.3.1 建立连接
  1. slave到master的连接。
    slaveof ip port
  • 如果连通,master会回复masterhost和masterport。
  • slave将信息保存下来。
  1. 建立socket。
  • 根据保存的信息连接master的socket。
  1. slave通过定时任务发送ping命令。
  • master回复pong,证明连接没断。
  1. 身份验证。
    auth password
  • Redis不对外提供服务,基本上不需要密码。
  1. 发送slave端口信息。
    replcof listening-port <port-number>
  • slave将自己的端口号发给master,master保存下来。

连接方式:

  • 方式一:客户端发送命令
    slaveof masterIP masterPort
  • 方式二: 启动服务器时加上参数
    redis-server --slaveof masterIP masterPort
  • 方式三: 配置文件中配置master节点信息
    slaveof masterIP masterPort

断开方式:

  • 从客户端发送命令
    slaveof no one

授权访问:

master:

  • master配置文件设置密码
    requirepass 密码
  • master客户端发送命令设置密码
  • config set requirepass 密码 设置密码
  • config get requirepass 获取密码

slave:

  • slave 客户端发送命令设置密码
    auto 密码
  • slave配置文件设置密码
    masterauth 密码
  • 启动客户端时输入密码(访问自己服务端的密码)
    redis-cli -a 密码
1.3.2 数据同步
  1. 请求同步数据
  • 刚建立连接时,slave请求把master的所有数据都复制到本机。

psync2

  1. master创建rdb同步数据
  • master执行 bgsave
  • master创建了一个复制缓冲区,将新来的数据放进缓冲区。
  1. slave恢复RDB同步数据(全量复制)
  • slave接收rdb文件,并清空自己的数据,执行rdb恢复过程。
  • slave发送命令告诉master恢复完成。
  1. 请求并恢复部分同步数据(增量复制)
  • master复制缓冲区信息。
  • slave接收信息,执行bgrewriteaof,恢复数据。

数据同步注意事项

  1. 如果master数据量过大,数据同步阶段应该避开流量高峰期。
  2. 如果复制缓冲区大小设置的不合理,就会导致数据溢出。如果部分复制发生溢出,那么必须进行第二次全量复制。
    repl-backlog-size 1mb 缓冲区默认是1M。
  3. master单机内存占用主机内存的比例不应过大,建议50%-70%,剩下的内存用于执行bgsave和创建复制换冲区。
  4. 为避免slave进行复制时服务器阻塞,建议关闭此时的对外服务。
    slave-serve-stale-data yes|no
  5. 多个slave同时请求数据同步,会占用大量带宽,注意错峰。
  6. 树状节点时,数据一致性比较差,应该谨慎选择。
1.3.3 命令传播阶段

命令传播阶段会部分复制

  • 如果出现了长时间断网:全量复制
  • 短时间网络中断:部分中断

服务器运行ID: 识别每一次服务运行时的身份识别码,40位的16进制字符。用来在服务器间发送命令时校验身份。

复制缓冲区: 每次传播命令,master都会将传播的命令记录下来,存储在缓冲区。

  • 复制缓冲区是用字符来存储的,拆成AOF那种形式。
  • 仅保存影响数据变更的指令,比如set、select等。

偏移量offset: 使用偏移量来确认发送到了哪一个字节。

  • master和slave都会记录offset,用来对比复制差异。
  • master会保存多个offset,每个slave对应一个。
  • slave只保存自己的。

1.4 心跳机制

在命令传播阶段,master与slave间需要进行信息交换,使用心跳机制保持双方在线。

  • master心跳:
  • 指令:PING
  • 周期: 由repl-ping-slave-period决定,默认是10秒。
  • 作用:判断slave是否在线。
  • 查询:INFO replication 获取slave最后一次连接时间间隔。
  • slave心跳:
  • 指令 REPLCONF ACK offset
  • 周期 一秒
  • 向master汇报自己的复制偏移量,并且判断master是否在线。

注意:

  • 当slave多次掉线或者延迟过高,就会被master踢了。
  • min-slaves-to-write 2最少只剩下2个slave了,就停止写了。
  • min-slaves-max-lag 8延迟过高,也不写了。
  • slave数量和延迟由slave发送REPLCONF ACK命令来确认。

1.5 主从复制的常见问题

  1. 频繁的全量复制

一旦master重启,runid发生变化,会导致slave全部全量复制。

Redis内部优化方案:

  • 会生成一个repl-id和offset。
  • 在master关闭时进行RDB持久化,将repl-id和offset保存进RDB文件。
  • 重启后将这两个东西恢复回来,使slave以为还是原来的master。
  1. 断网后slave的offset 越界,触发全量复制。
  • 最优的复制缓冲区空间
  • 测算master到slave的重连平均时长
  • 空间 = 2*second*master每秒钟产生写命令数据总量
  1. slave收到了慢查询,比如keys *这种命令,导致slave无法响应master,master不停地尝试连接slave,占用了大量资源。
  • 合理地设置超时时间,将slave断开。
  • repl-timeout 60
  • 默认60秒
  1. master的ping频率低,超时时间短,ping万一丢包了,master就会踢掉slave。
  • repl-ping-slave-period
  • 超时时间至少是ping频率的5-10倍。
  1. 多个slave数据不同步,网络信息不同步,数据发送有延迟。
  • 优化主从机器的网络环境,尽量放在同一个机房。
  • 如果延迟非常大,建议暂时关闭slave的对外服务。
  • slave-serve-stale-data yes|no
  • 打开后slave仅响应info,slaveof等少数命令。
  • 慎用。

2. 哨兵模式

2.1 哨兵简介

如果master宕机,需要下线master,再选出来一个slave当做master,再通知所有slave。

哨兵是一个分布式系统,用于对主从结构的每台服务器进行监控,当出现问题时通过投票机制来选取新的master。

作用:

  • 监控
  • 通知
  • 自动故障转移

哨兵一般是奇数,3个起。

哨兵也是Redis服务器,只不过不提供数据服务。

2.2 启用哨兵

  • 配置文件
    sentinel.conf
  • port 26379
  • sentinel monitor mymaster 127.0.0.1 6379 2
  • mymaster是给master起的名字。
  • 2的意思是如果有两个哨兵觉得master宕机,那就真的宕机了。一般是所有哨兵的一半+1。
  • sentinel down-after-milliseconds mymaster 30000
  • 主机多少秒没联系就认为宕机
  • sentinel parallel-syncs mymaster 1
  • 挂了之后一次有多少台机器来和新master同步。
  • sentinel failover-timeout mymaster 180000
  • 同步时多久同步完成是有效的。默认180秒同步超时。
  • 启动哨兵
    redis-sentinel sentinel_port.conf
  • 启动顺序
  1. 启动master。
  2. 启动slave。
  3. 启动sentinel。

注意:

  • 哨兵启动后,配置文件内会被追加一些自己id和其他哨兵ID和slave的信息。
  • 每个哨兵启动后都能互相被其他已经启动的哨兵识别到。

2.3 哨兵工作原理

2.3.1 监控阶段

用于同步各个节点的状态信息。

  1. 获取各个sentinel的信息。
  2. 获取master的信息。
  • master属性:
  • runid
  • role
  • 各个slave的信息
  1. 获取所有的slave状态。
  • slave属性
  • runid
  • role
  • port
  • offset等等。
2.3.2 通知阶段
2.3.3 故障转移阶段
  • 如果一个哨兵发现master联不通,就会将其标记为sdown。
  • 其他哨兵收到第一个哨兵的通知后,也会去访问master,如果超过配置文件中那个数量的哨兵都确认master宕机,就会将其标记为odown。
  • 哨兵们会选举出来一个带头人,内部会有一个投票机制,选定一个哨兵去处理故障转移。
  • 选master原则:
  1. slave在线。
  2. 响应慢的淘汰。
  3. 与master断开时间久的踢掉。
  4. 优先级。
  • 优先级
  • 偏移量(偏移量小的说明同步的快)
  • runid(选id小的)
  • 现在就选到了新的master。向新的slave发送slaveof no one。
  • 向其他的slave发送slaveof masterIP masterPort。
  • 如果原来的master恢复上线后,作为slave连接。

3. 集群

将若干台机器连接在一起,统一对外服务。

3.1 集群结构设计

  1. 数据存储设计
    先对Key进行计算CRC16(key),再对16384取余,得到一个数字,然后存到对应的机器。这个数字,官方叫做槽。增删节点,就是移动槽的位置。
  2. 集群内部通讯设计
    内部节点会互相通讯,了解每个节点有哪些槽。一次命中,直接返回。不命中就查表。所以最多两次就能找到槽。

3.2 集群搭建

配置文件里添加cluster相关配置。

  • cluster-enabled yes|on
  • cluster-config-file nodes-端口.conf
  • cluster-node-timeout 超时下线时间

src文件夹有个命令 redis-trib.rb ,是个ruby脚本。

redis-trib.rb create --replicas 1 master1IP:Port master2IP:Port.....

- 1代表一个master拖一个slave。
- 后面的ip和端口,前面是master,后面是slave。

3.3 设置与获取数据

redis-cli -c 这是集群专用的客户端。一定要加上-c命令。

3.4 主从下线和主从切换

3.4.1 slave下线

slave对应的master会将slave标记为下线。同时将slave下线的消息发送给集群其他的节点。

slave再次上线后,会与master建立同步,集群其他节点会清除slave的下线状态。

3.4.2 master下线

slave会重连10次,一秒连接一次。

slave会经历一串转变升级为master。

master再次上线后,就会变成slave,去找刚才升级为master的slave同步信息。