• 技术文章 >数据库 >Redis

    聊聊Redis中的主从同步和哨兵模式

    青灯夜游青灯夜游2022-02-16 10:59:57转载322
    本篇文章带大家深入了解一下Redis中的主从同步和哨兵模式,介绍一下开启关闭主从同步、搭建启动Sentinel的方法,希望对大家有所帮助!

    主从同步

    主从同步(主从复制)是 Redis 高可用服务的基石,也是多机运行中最基础的一个。【相关推荐:Redis视频教程

    我们把主要存储数据的节点叫做主节点 (master),把其他通过复制主节点数据的副本节点叫做从节点 (slave),如下图所示:

    1.png

    Redis一个主节点可以拥有多个从节点一个从节点也可以是其他服务器的主节点,如下图所示:

    2.png

    主从同步的优点

    主从同步具有以下三个优点

    开启主从同步

    运行中设置从服务器

    Redis 运行过程中,我们可以使用 replicaof host port 命令,把自己设置为目标 IP 的从服务器。

    如果主服务设置了密码,需要在从服务器输入主服务器的密码,使用 config set masterauth 主服务密码 命令的方式

    在执行完 replicaof 命令之后,从服务器的数据会被清空,主服务会把它的数据副本同步给从服务器。

    启动时设置从服务器

    可以使用命令 redis-server --port 6380 --replicaof 127.0.0.1 6379 将自己设置成目标服务器的从服务器。

    数据同步

    完整数据同步

    当有新的从服务器连接时,为了保障多个数据库的一致性,主服务器会执行一次 bgsave 命令生成一个 RDB 文件,然后再以 Socket 的方式发送给从服务器,从服务器收到 RDB 文件之后再把所有的数据加载到自己的程序中,就完成了一次全量的数据同步

    部分数据同步

    Redis 2.8 之前每次从服务器离线再重新上线之前,主服务器会进行一次完整的数据同步,然后这种情况如果发生在离线时间比较短的情况下,只有少量的数据不同步却要同步所有的数据是非常笨拙和不划算的,在 Redis 2.8 这个功能得到了优化。

    Redis 2.8 的优化方法是当从服务离线之后,主服务器会把离线之后的写入命令,存储在一个特定大小的队列中,队列是可以保证先进先出的执行顺序的,当从服务器重写恢复上线之后,主服务会判断离线这段时间内的命令是否还在队列中,如果在就直接把队列中的数据发送给从服务器,这样就避免了完整同步的资源浪费。

    存储离线命令的队列大小默认是 1MB,使用者可以自行修改队列大小的配置项 repl-backlog-size

    无盘数据同步

    在第一次主从连接的时候,会先产生一个 RDB 文件,再把 RDB 文件发送给从服务器,如果主服务器是非固态硬盘的时候,系统的 I/O 操作是非常高的。

    Redis 2.8.18 新增了无盘复制功能,无盘复制功能不会在本地创建 RDB 文件,而是会派生出一个子进程,然后由子进程通过 Socket 的方式,直接将 RDB 文件写入到从服务器,这样主服务器就可以在不创建 RDB 文件的情况下,完成与从服务器的数据同步。

    要使用无须复制功能,只需把配置项 repl-diskless-sync 的值设置为 yes 即可,它默认配置值为 no

    查询服务器的角色

    使用 role 命令,来查询当前服务器的主从角色信息。

    关闭主从同步

    可以使用 replicaof no one 命令来停止从服务器的复制。

    执行了 replicaof no one 命令之后,自己就从服务器变成主服务器了。

    服务器类型的转换并不会影响数据,这台服务器的数据将会被保留。

    注意事项

    数据一致性问题

    当从服务器已经完成和主服务的数据同步之后,再新增的命令会以异步的方式发送至从服务器,在这个过程中主从同步会有短暂的数据不一致,如在这个异步同步发生之前主服务器宕机了,会造成数据不一致。

    从服务器只读性

    默认情况下,处于复制模式的主服务器既可以执行写操作也可以执行读操作,而从服务器则只能执行读操作。

    可以在从服务器上执行 config set replica-read-only no 命令,使从服务器开启写模式,但需要注意以下几点:

    复制命令的变化

    Redis 5.0 之前使用的复制命令是 slaveof,在 Redis 5.0 之后复制命令才被改为 replicaof,在高版本(Redis 5+)中我们应该尽量使用 replicaof,因为 slaveof 命令可能会被随时废弃掉。

    哨兵模式

    主从复制模式,它是属于 Redis 多机运行的基础,但这种模式本身存在一个致命的问题,当主节点奔溃之后,需要人工干预才能恢复 Redis 的正常使用。

    我们需要一个自动的工具——Redis Sentinel(哨兵模式)来把手动的过程变成自动的,让 Redis 拥有自动容灾恢复(failover)的能力。

    哨兵就相当于对主从服务器做一个监视的任务。一旦发现主服务器宕机了,就迅速启动相应的规则将某一台从服务器升级为主服务器,无需人工干预,更稳定更快

    Redis Sentinel 的最小分配单位是一主一从。

    3.png

    Redis Sentinel 搭建

    使用命令 ./src/redis-sentinel sentinel.conf 来启动 Sentinel,在启动它时必须设置一个 sentinel.conf 文件,这个配置文件中必须包含监听的主节点信息:

    sentinel monitor master-name ip port quorum

    其中:

    如果主节点服务器 Redis 有密码,sentinel.conf 必须包含以下内容:

    sentinel monitor mymaster 127.0.0.1 6379 1
    sentinel auth-pass mymaster pwd654321

    启动 Sentinel 集群

    生产环境我们不会只启动一台 Sentinel,因为如果启动一台 Sentinel 假如它不幸宕机的话,就不能提供自动容灾的服务了,不符合我们高可用的宗旨,所以我们会在不同的物理机上启动多个 Sentinel 来组成 Sentinel 集群,来保证 Redis 服务的高可用。

    启动 Sentinel 集群的方法很简单,和上面启动单台的方式一样,我们只需要把多个 Sentinel 监听到一个主服务器节点,那么多个 Sentinel 就会自动发现彼此,并组成一个 Sentinel 集群。

    4.png

    一般情况下 Sentinel 集群的数量取大于 1 的奇数,quorum 的参数就设置为一半加 1,例如 5 就设置为 3,7 就设置为 4。

    两个概念:主观下线和客观下线。

    Sentinel 集群中,有一个 Sentinel 认为主服务器已经下线时,它会将这个主服务器标记为主观下线(Subjectively DownSDOWN),然后询问集群中的其他 Sentinel,是否也认为该服务器已下线,当同意主服务器已下线的 Sentinel 数量达到 quorum 参数所指定的数量时,Sentinel 就会将相应的主服务器标记为客观下线(Objectively down,ODOWN),然后开始对其进行故障转移。

    主服务竞选规则

    新主节点竞选优先级设置

    redis.conf 中的 replica-priority 选项来设置竞选新主节点的优先级,它的默认值是 100,它的最大值也是 100,这个值越小它的权重就越高。

    新主节点竞选规则

    新主节点的竞选会排除不符合条件的从节点,然后再剩余的从节点按照优先级来挑选。

    存在以下条件的从节点会被排除:

    符合条件的从节点竞选顺序:

    旧主节点恢复上线

    如果之前的旧主节点恢复上线,会作为从节点运行在主从服务器模式中。

    哨兵工作原理

    首先每个 Sentinel 会以每秒钟 1 次的频率,向已知的主服务器、从服务器和以及其他 Sentinel 实例,发送一个 PING 命令。

    如果最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 所配置的值(默认 30s),那么这个实例会被 Sentinel 标记为主观下线。

    如果一个主服务器被标记为主观下线,那么正在监视这个主服务器的所有 Sentinel 节点,要以每秒 1 次的频率确认主服务器的确进入了主观下线状态。

    如果有足够数量(quorum 配置值)的 Sentinel 在指定的时间范围内同意这一判断,那么这个主服务器被标记为客观下线。此时所有的 Sentinel 会按照规则协商自动选出新的主节点。

    注意:一个有效的 PING 回复可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果返回值非以上三种回复,或者在指定时间内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复无效(non-valid)。

    Sentinel 命令操作

    Sentinel 可以监视多台主节点,而不是只能监视一台服务器。想要监视多台主节点只需要在配置文件中设置多个 sentinel monitor master-name ip port quorum 即可,我们通过 master-name 来区分不同的主节点。

    查询所有被监控的主服务器信息

    sentinel masters

    查询某个主节点的信息

    sentinel master master-name

    查看某个主节点的 IP 和端口

    sentinel get-master-addr-by-name master-name

    查询从节点的信息

    sentinel replicas mymastersentinel slaves master-name

    查询 Sentinel 集群中的其他 Sentinel 信息

    sentinel sentinels master-name

    检查可用 Sentinel 的数量

    sentinel ckquorum master-name

    强制故障转移

    sentinel failover master-name

    在线修改配置信息

    Redis 2.8.4 之前如果需要修改 Sentinel 的配置文件,需要重启 Sentinel

    Redis 2.8.4 之后,我们可以在线修改配置文件了。

    增加监视主节点

    sentinel monitor mymaster IP Port Quorum 命令。

    移除主节点的监视

    使用 sentinel remove master-name 命令。

    修改 quorum 参数

    使用 sentinel set master-name quorum n 命令。

    quorum 参数用来表示确认主节点下线的 Sentinel 数量,如果 quorum 设置为 1 表示只要有一台 Sentinel 确认主观下线后,这个主节点就客观(真正地)下线了。

    以上所有对配置文件的修改,都会自动被刷新到物理配置文件 sentinel.conf

    代码实战

    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisSentinelPool;
    import utils.Config;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class SentinelExample {
        // master name
        private static String _MASTER_NAME = "mymaster";
    
        public static void main(String[] args) {
            // Sentinel 配置信息
            Set<String> set = new HashSet<>();
            // 连接信息 ip:port
            set.add("127.0.0.1:26379");
            // 创建 Sentinel 连接池
            JedisSentinelPool jedisSentinel = new JedisSentinelPool(_MASTER_NAME,
                    set, Config.REDIS_AUTH);
            // 获取 Redis 客户端
            Jedis jedis = jedisSentinel.getResource();
            // 设置元素
            String setRes = jedis.set("key", "Hello, redis.");
            System.out.println(setRes);
            // 获取元素
            System.out.println(jedis.get("key"));
        }
    }

    更多编程相关知识,请访问:编程入门!!

    以上就是聊聊Redis中的主从同步和哨兵模式的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    上一篇:Redis学习之深入了解Bitmaps 下一篇:一文聊聊Redis中的过期操作和过期策略
    PHP编程就业班

    相关文章推荐

    • 浅析Redis中的集群主从复制原理• 浅析Redis中的哨兵模式原理• 保证mysql和redis的双写一致性• 浅析Redis6中的单线程和多线程模型• Redis源码解析之深入了解Makefile文件• 什么是可重入锁?详解redis实现分布式重入锁的方法

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网