Redis 主从同步

一、Redis 主从同步介绍

Redis 是一个开源的内存数据库,用 C 语言编写,支持多种数据结构,如字符串、哈希表、列表等。Redis 使用异步 IO,在内存中存储数据,非常适用于缓存和实时数据分析等场景。Redis 的主从同步机制是实现高可用架构的重要组成部分。

Redis 主从同步,一般指一主多从的同步模式,其中主节点负责写入数据,从节点负责读取数据并保持和主节点数据的同步。在这种模式下,主节点将写入数据同步到所有从节点,从而实现数据的备份、读取负载均衡和故障切换等功能。

Redis 的主从同步采用异步复制方式,从节点会定期发送同步请求给主节点,主节点在接收到同步请求后会将当前的数据快照和写入操作异步推送到从节点。从节点会先接收到全量同步,之后再接收到增量同步,从而把自己的数据与主节点的数据保持同步。

二、Redis 主从同步配置

在 Redis 中,实现主从同步需要进行一些配置。首先,需要在主节点和从节点之间建立连接,然后在主节点上进行配置,启用主从同步功能,设置从节点的 IP 和端口号。

具体的配置步骤如下:

# 在主节点上配置
slaveof master_ip master_port

# 在从节点上配置
# 如果主节点和从节点不在同一台机器上,需要设置主节点的 IP 和端口号
# 如果主节点和从节点在同一台机器上,则不需要设置
replicaof master_ip master_port

其中,slaveof 命令用于在主节点上配置从节点,replicaof 命令用于在从节点上配置主节点。在配置完成后,从节点会自动连接到主节点,并开始数据同步。

三、Redis 主从同步实现原理

Redis 的主从同步实现依赖于复制和命令传播两个模块。

复制模块

复制模块由同步源和同步目标两个部分组成,同步源即主节点,同步目标即从节点。同步源在接收到同步请求后,会将当前执行的写命令内容和参数进行序列化,并发送给同步目标,从而实现数据的同步。

// 同步请求处理实现
void syncCommand(client *c) {
    // 序列化当前执行的写命令并发送给同步目标
    replicationFeedSlaves(c->db->id, &c->argv, c->argc);
    c->flags |= CLIENT_MASTER_FORCE_REPLY;
    addReply(c, shared.ok);
}

命令传播模块

当主节点执行写入命令时,需要将命令发送给所有从节点进行同步。消息的发送有两种方式:异步复制和主节点判断从节点已经收到的可靠复制。

在异步复制方式中,主节点将命令发送给所有从节点,并返回结果。在写入数据前,主节点会将写操作添加到写命令 AOF(append-only file)文件中,从节点会定期读取 AOF 文件,从而保持和主节点数据的一致性。

// AOF 文件写操作实现
int flushAppendOnlyFile(int force) {
    ...
    if (server.aof_selected_db->dirty == 0) {
        ...
        return C_OK;
    }
    // 将 AOF 文件和复制缓存中的内容发送给所有从节点
    feedSlaves(ALL_SLAVES,server.delCommand,c->db->id,c->argv,c->argc,"del",OBJ_SHARED_INTEGERS[2]->ptr);
    ...
    // 将写操作添加到 AOF 文件中
    addReply(c,shared.ok);
    writeCommandsVectorLenToFile(c->db->id,c->argv,c->argc);
    ...
}

在可靠复制方式中,主节点根据从节点的复制缓冲区中保存的 offset 和 ACK 信息来判断哪些命令已经被从节点接收并执行。主节点会等待从节点的 ACK 信息后,再执行后续操作。

// 可靠复制方式实现
void syncWithMaster(void) {
    while(1) {
        // 读取主节点发送的命令并执行
        if (syncReadLine(reply,buf,PROTO_REPLY_CHUNK_BYTES,maxlen,&rlen) == -1) goto cleanup;
        if (rlen == 0) goto cleanup;
        if (buf[0] == '-') {
            // 命令出错,中止同步
            ...
        } else if (buf[0] == '+') {
            // 命令执行成功,继续同步
            ...
        } else if (buf[0] == '*') {
            // 命令包含多个回复,解析后继续同步
            ...
        } else if (buf[0] == '$') {
            // 命令结果为 BulkString 类型,解析后继续同步
            ...
        } else if (buf[0] == ':') {
            // 命令结果为 Integer 类型,解析后继续同步
            ...
        }
        // 发送 ACK 信息给主节点
        if (write(sfd,"+",1) != 1) goto cleanup;
    }
}

四、Redis 主从同步流程

Redis 主从同步流程可以分为全量同步和增量同步两个阶段。

全量同步

全量同步也叫 initial sync,是主从节点第一次进行同步时使用的同步方式。全量同步会在从节点启动时自动触发,主节点会将当前的数据快照和写命令推送给从节点,从节点会接收到全量同步数据并进行加载,之后再接收增量同步。

具体的全量同步流程如下:

  1. 从节点请求主节点进行全量同步
  2.     # 在从节点上执行
        SLAVEOF master_ip master_port
        
  3. 主节点返回 RDB 快照文件
  4.     # 主节点发送 RDB 快照文件
        $redis-benchmark -t set -n 100000 -r 100000 -D redis-master
        
  5. 从节点加载 RDB 快照文件,并接收增量同步

增量同步

增量同步也叫 partial sync,是在全量同步完成后进行的同步方式。增量同步会在主节点执行写入操作后,将写入操作推送给所有从节点,从节点接收到写入操作后进行同步。

具体的增量同步流程如下:

  1. 从节点连接主节点,并请求进行数据同步
  2.     # 在从节点上执行
        SLAVEOF master_ip master_port
        
  3. 主节点接收到同步请求,并推送写入命令给所有从节点
  4.     # 主节点推送命令给所有从节点
        SET key value
        
  5. 从节点接收到命令并执行

五、Redis 主从同步优化

为了提高 Redis 主从同步的效率和稳定性,我们可以进行一些优化。

优化复制缓冲区

为了避免从节点处理速度低于主节点的写入速度,导致从节点复制缓冲区积压过多,我们可以扩大从节点复制缓冲区的大小。

# 在从节点上配置
repl_backlog_size size

优化 AOF 缓冲区

为了避免从节点读取 AOF 文件时,因为 AOF 缓冲区写满而阻塞,导致数据同步失败,我们可以启用 AOF 重写机制,定期对 AOF 文件进行重写。

# 在主节点上配置
auto-aof-rewrite-percentage percentage
auto-aof-rewrite-min-size size

启用故障转移机制

在主从同步环境下,如果主节点出现故障,则需要从节点接替主节点成为新的主节点。为了实现自动切换,我们可以启用 Redis 的 Sentinel(哨兵)机制。

# 在主节点和从节点上启用 Sentinel
sentinel monitor master_name master_ip master_port num_slaves

六、总结

Redis 主从同步是实现高可用的必要手段,在多节点环境下具有重要意义。掌握 Redis 主从同步的配置、实现原理和优化策略,可以提高系统的稳定性和性能。

原创文章,作者:TJND,如若转载,请注明出处:https://www.506064.com/n/142168.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
TJNDTJND
上一篇 2024-10-10 09:25
下一篇 2024-10-10 09:25

相关推荐

  • 在CentOS上安装Redis

    Redis是一款非关系型数据库,它支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。Redis运行内存内并且支持数据持久化,它还可以应用于缓存、消息队列等场景。本文将介绍…

    编程 2025-04-28
  • 解析spring.redis.cluster.max-redirects参数

    本文将围绕spring.redis.cluster.max-redirects参数进行详细阐述,从多个方面解读它的意义与作用,并给出相应的代码示例。 一、基础概念 在介绍sprin…

    编程 2025-04-27
  • Redis Bitmap用法介绍

    Redis是一款高性能的内存数据库,支持多种数据类型,其中之一便是bitmap。Redis bitmap(位图)是一种用二进制位来表示元素是否在集合中的数据结构。由于使用了二进制位…

    编程 2025-04-27
  • 使用yum安装redis

    一、什么是redis? Redis是一种开源的基于key-value存储的NoSQL数据库,它支持多种数据结构的存储,例如字符串、哈希、列表、集合以及有序集合等。同时,Redis还…

    编程 2025-04-25
  • Linux Redis 重启

    一、概述 Redis 是一款高性能的 NoSQL 数据库,常用于各种应用场景的数据缓存、消息队列、实时数据分析等等。在使用 Redis 过程中,如果出现了某些问题,有时候只需要重启…

    编程 2025-04-25
  • Ubuntu安装Redis指南

    一、安装步骤 1、查看Ubuntu是否已安装Redis,如果已安装,则卸载Redis。 sudo apt-get remove redis-server 2、安装Redis——命令…

    编程 2025-04-25
  • 深入解析Redis内存淘汰策略

    Redis是一个高性能键值数据库,由于其快速、稳定和易于使用,它已经成为很多应用程序中不可或缺的一部分。在使用Redis时,我们需要考虑内存管理问题。Redis内存淘汰策略是如何工…

    编程 2025-04-25
  • Redis MSET完全指南

    一、MSET简介 Redis是一个高性能的开源缓存软件,被称作NoSQL数据库。其中,MSET是Redis中的一种命令,可以同时设置多个Key-Value对。如果KeyValue已…

    编程 2025-04-25
  • Redis乐观锁详解

    一、乐观锁概述 乐观锁是一种并发控制机制,它假定在数据变更时不会有冲突发生,因此不会像悲观锁一样在操作时先加锁。 在Redis中,乐观锁常用于多线程、多用户同时操作同一个数据的场景…

    编程 2025-04-25
  • Redis的作用

    一、缓存 Redis最常见的用途是作为缓存。所谓缓存,就是将频繁读取、但不经常修改的数据存储在内存中,用户请求数据时优先从内存中读取,可大幅提升数据访问效率。Redis的数据结构特…

    编程 2025-04-24

发表回复

登录后才能评论