从零开始学Redis系列(四)| 如何正确的搭建Redis主从架构

这是我参与更文挑战的第4天,活动详情查看:更文挑战

前言

单机的Redis存储能力受单机限制,无法实现读写操作的负载均衡和读写分离功能等,无法保证高可用。所以要搭建Redis的主从架构来避免上述这些问题

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器,主从是哨兵和集群模式能够实施的基础。

image.png

主从复制作用

  • 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余。
  • 故障恢复:当主节点出现问题时,可以切换成从节点提供服务,实现快速的故障恢复。
  • 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
  • 读写分离:主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量;
  • 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础。

既然主从架构的作用那么强大,所以这篇文章就来和大家聊聊关于Redis主从架构的那点破事,总共可以分为以下四个部分:

  • 主从架构搭建过程详解
  • 主从架构数据同步的过程
  • Java代码如何连接远程云服务器上的Redis主从架构
  • 课外小知识-如何查看Redis服务运行信息

下面就开始第一部分的介绍:主从架构搭建过程详解

part 1:主从架构搭建过程

  • 第一步:修改主节点配置文件
# 修改保护模式为 no
protected-mod no

# 绑定本机的网卡地址,阿里云服务器的话就绑定内网IP,加上127.0.0.1是为了让本地能访问,不用redis-cli -h XXX.XXX.XXX 进行指定
bind XXX.XX.XX.XXX 127.0.0.1

# 修改master节点的端口
port 7000

# 把pid进程号写入pidfile配置的文件中
pidfile /var/run/redis_7000.pid

# 日志文件名
logfile "redis_7000.log"

# 指定数据存放目录,注意是绝对路径
dir /xxx/xxx/
复制代码
  • 第二步:启动主节点

image.png

  • 第三步:创建一个文件夹,用来存放从节点配置文件

image.png
image.png

  • 第四步:复制一份redis.conf文件到刚创建的目录下作为slave节点的配置文件,修改配置文件名称便于识别,修改slave节点的配置文件
# 修改保护模式为 no
protected-mod no

# 绑定本机的网卡地址,阿里云服务器的话就绑定内网IP
bind XXX.XX.XX.XXX

# 修改slave节点的端口
port 8888

# 把pid进程号写入pidfile配置的文件中
pidfile /var/run/redis_8888.pid

# 日志文件名
logfile "redis_8888.log"

# 指定数据存放目录,绝对路径
dir /xxx/xxx/slave/01/

# 配置主从复制
# 主节点网卡地址,阿里云服务器的话就绑定内网IP
replicaof 主节点的IP 主节点的端口

# 配置从节点只读
replica-read-only yes
复制代码
  • 第五步:启动从节点

image.png

image.png

测试搭建是否成功

  • 在从节点的客户端使用keys *命令发现主节点上的数据已经全量同步

image.png

  • 进入主节点的客户端设置值,然后在从节点获取,发现数据已经同步

image.png

  • 进入主节点的客户端,输入info replication命令查看连接状态

image.png

  • 进入从节点的客户端,输入info replication命令查看连接状态,以其中一个从节点为例,上面有主节点连接状态:up说明连接成功

image.png

至此,证明Redis主从架构的环境已经搭建成功

主从搭建过程中踩到的坑

  • 确保文件目录存在,像下方的目录,要确保在启动从节点之前就存在,否则从节点会启动不起来

image.png

  • 没有修改绑定的ip,导致数据同步不过去,原因可以看下方这篇文章:Redis的bind的误区,解决方法就是绑定本机网卡ip,或者直接配置成不限制

image.png

part 2:Redis主从同步的过程

Redis从节点和主节点的同步分为两个场景:

  1. 第一个场景:从节点启动的时候从主节点中全量同步
  2. 第二个场景:主节点有增量命令的时候同步给从节点,增量同步

全量同步

流程图

image.png

流程解析

  • 第一步:从节点先和主节点建立socket长链接,保持通信
  • 第二步:从节点发送psync指令,发起同步的请求
  • 第三步:主节点收到psync指令执行bgsave命令,生成rdb快照,并将之后增量的命令存储在缓冲区中
  • 第四步:主节点生成快rdb快照后,将rdb快照的二进制数据发送给从节点
  • 第五步:从节点接受主节点的rdb快照数据,清空老数据后加载到内存中
  • 第六步:等到从节点同步完快照数据,主节点发送增量的命令给从节点
  • 第七步:从节点执行增量命令
  • 第八步:主节点通过socket长连接持续的把命令发送给从节点

注意事项

当主节点收到了多个从节点的并发连接请求,它只会进行一次持久化,并且把这一份持久化的数据发送给多个并发连接的从节点

增量同步

流程图

image.png

流程解析

  • 第一步:从节点先和主节点断开socket长链接
  • 第二步:从节点重新发送socket连接请求,建立通信
  • 第三步:从节点发送psync(offset)指令,发起同步的请求
  • 第四步:主节点判断offset在不在最近命令的缓冲区repl backlog buffer中,如果存在,那么就从offset之后的命令一次性同步给slave,如果不在,说明断开的时间比较久,就会全量同步
  • 第五步:主节点通过socket长连接持续的把命令发送给从节点

主从同步过程中的注意事项

缓冲区设置大小

缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。

为了提高网络中断时部分复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size);

例如如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用部分复制。

image.png

主从复制风暴

如果有很多从节点,为了缓解主从复制风暴(多个从节点同时复制主节点导致主节点压力过大),可以做如下架构,让部分从节点和主节点同步数据的从节点同步数据

image.png

part 3:Java连接远程云服务器上的Redis主从架构

配置防火墙端口

安全组的话需要去ECS界面配置规则,轻量级服务器直接在防火墙中配置端口范围

引入Jedis客户端

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
复制代码

编写连接代码

public class JedisSingleTest {

    public static void main(String[] args) {

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMinIdle(5);
        // timeout:这里既是连接超时又是读写超时,从Jedis 2.8开始区分connectionTimeout和soTimeout的构造函数
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "阿里云服务器公网IP", 7000, 3000, null);
        // 从redis连接池里拿出一个连接来执行命令
        Jedis jedis = jedisPool.getResource();
        // Jedis普通操作命令172.19.43.91
        System.out.println(jedis.set("single2", "aisiaoteman"));
        System.out.println(jedis.get("single2"));
    }

}
复制代码

测试连接代码

运行main方法后,控制台输出正确主节点和从节点都输出正确

image.png

image.png

证明Java连接远程阿里云Redis配置成功

连接远程阿里云Redis踩过的坑

配置防火墙端口/配置ECS的安全组!!!!!

安全组的话需要去ECS界面配置规则,轻量级服务器直接在防火墙中配置端口范围

image.png

一定要用云服务器的公网IP连,不要用内网IP!!!!!

image.png

part 4:课外小知识-查看Redis服务运行信息

还记得上面文章中,检查主从配置信息的info replication命令吗?

其实这个info命令是专门用来查看Redis服务运行信息,Redis服务运行信息总共可以分为九大块:

  • server:服务器运行时的环境参数

image.png

  • clients:客户端相关信息

image.png

  • memory:服务器运行内存统计数据

image.png

  • persistence:持久化信息

image.png

  • stats:通用统计信息

image.png

  • replication:主从复制相关信息

image.png

  • cpu:cpu相关信息

image.png

  • cluster:集群信息

image.png

  • keySpace:键值对统计数量信息

image.png

如果想要看哪个信息直接在info 模块名就可以了,例如:如果想看主从复制相关信息,就输入命令:info replication

image.png

总结

好啦,以上就是这篇文章的全部内容,这篇文章从四个方面给大家一个比较直观的Redis主从架构:

  • 主从架构搭建过程详解
  • 主从架构数据同步的过程
  • Java代码如何连接远程云服务器上的Redis主从架构
  • 课外小知识-如何查看Redis服务运行信息

相信现在大家现在人手一个Redis主从架构了吧,不过这不是终点,我们在下篇文章中为了实现Redis主从的高可用,还要基于主从架构,继续搭建Redis的哨兵集群,实现故障自动恢复,可以期待一下呦!!!!

往期推荐

从零开始学Redis系列(一)| Redis环境搭建

从零开始学Redis系列(二)| Redis常用命令如何在企业中重拳出击

从零开始学Redis系列(三)| 如何正确的操刀Redis的持久化

絮叨

最后,如果感到文章有哪里困惑的,请第一时间留下评论,如果各位看官觉得小沙弥我有点东西的话 求点赞? 求关注❤️ 求分享? ,因为这将是我输出更多优质文章的动力,感谢!!!

如果想获取Redis相关书籍,可以关注微信公众号Java百科全书输入Redis,即可获得

最后感谢各位看官的支持,我们下期再见!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享