Redis主从复制

简介: 在分布式系统中,为解决单点故障和提升性能,常采用Redis主从复制架构。通过将数据复制到多个从节点,实现读写分离、负载均衡及高可用性,同时支持多种拓扑结构以适应不同场景需求。

在分布式系统中,为了解决单点问题,通常会把redis服务部署到多个服务器上,满足故障恢复和负载均衡等请求。


所谓的单点问题,就是某个服务器程序,只有一个节点(只有一个物理服务器,来部署这个服务器程序)。


存在的问题:


可用性问题:如果这个机器挂了,那么部署的redis服务就挂了,服务就中断了。


性能/支持的并发量有限:毕竟一台主机的硬件资源(比如CPU,硬盘,网络带宽等等)是有限的,一个请求就要消耗一定量的硬件资源。一旦并发量太高,如果请求超过主机所能提供这些资源,那么可能就会出现异常,甚至主机直接宕机了。


在分布式系统中,往往希望有多个服务器来部署redis服务,从而构成一个redis集群,此时就可以让这个集群给分布式系统中的其他服务,提供更稳定/更高效的数据存储功能 。


主要存在以下几种部署方式:

主从模式

主从+哨兵模式

集群模式

一,主从复制

1,配置主从复制

主从模式,即在若干个redis节点中,有的是主节点,有的是从节点 。


redis主从模式中,从节点上的数据,不允许修改,只允许读取数据。要想修改数据,只能访问主节点。


假设有三个物理服务器(三个节点),都部署了redis服务,此时就可以把其中一个看作是主节点,其余两个看作是从节点。从节点上的数据要跟随主节点的数据而变化,从节点的数据要和主节点保持一致。


本来,在主节点上保存了一堆数据,现在引入从节点,就是要把主节点上的数据复制出来,放到从节点中。后续,主节点这里对数据有任何修改,都会把这样的修改同步给从节点。

总结:主从模式,主要是针对读操作进行可用性和并发量的提高,而对于写操作来说,无论是可用性还是并发量,都很依赖与主节点,但是主节点又不能搞多个。


如何在一个云服务器上部署多个redis服务,按照主从模式,实现类似于分布系统的效果?(ubutun20.04)


我们可以在一个云服务器主机上,运行多个redis-server进程,我们只需保证这几个服务的端口号不同即可。本来redis-server的默认端口号是6379,此时新启动的redis-server端口号就不能是6379了。


在这里我们创建两个从节点,端口号是6380和6381,而主节点就是原先的redis-server,端口号为默认的6379。


可以通过修改配置文件来改变:


1,首先需要将配置文件拷贝两份


cp /etc/redis/redis.conf slave1.conf


cp /etc/redis/redis.conf slave2.conf


2,然后修改拷贝后的两个配置文件中的选项


修改端口号——port 6380 port6381


将该服务设置为后台进程——daemonize yes


只需修改这两个选项即可。


3,启动这两个redis-server(从节点)


redis-server slave1.conf


redis-server slave2.conf


4,现在我们只是有了多个redis-server,还没有构成主从结构。


要想配置成主从结构,就需要使用slaveof。有如下三个方法:


在配置文件中加入slaveof{masterHost} {masterPort},之后随redis启动生效。


在redis-server启动命令中加入--slaveof{masterHost}{masterPort}生效。


直接使用redis命令:slaveof{masterHost}{masterPort}生效。


其中{masterHost}和{masterPort}分别指主节点的ip和端口。


5,在这里我们选择通过修改配置文件的方式来构成主从结构


在slave1.conf和slave2.conf配置文件中加上slaveof 127.0.0.1 6379即可,以6379的redis-server作为主节点。配置文件修改完毕之后,需要我们重新启动redis-server,配置文件才会生效,所以此时需要重启端口号为6380和6381的redis-server。


由于我们启动redis-server服务时,是使用redis-server port这样的方式启动的,所以在重启的时候,需要使用kill -9来杀掉该服务进程,然后再通过redis-server port重启即可。


而如果我们是使用service redis-server start来启动服务器,就需要使用service redis-server stop来终止程序。此时如果使用kill -9来终止服务进程,kill掉之后,这个redis-server进程能自动启动 。相当于有一个进程来专门监控指定服务器的运行状态,如果服务器挂了,会立即重新启动。


因此怎么启动的redis-server,就必须搭配对应的方式进行终止。


6,再次启动redis-server即可实现主从模式

2,断开主从复制

使用命令slaveof no one可以断开主从关系,这只是暂时的,当redis-server重启之后,主从关系就会恢复,所以要想一直断开主从关系,还是需要修改配置文件。


3,拓扑

我们的redis-server服务器可能有很多个节点,如何组织这些节点?


一主一从结构

如果其他客户端想要读取数据,从主节点A或 从节点B读取都可以,两个服务器上的数据是一致的。


如果是写数据请求,那么只能由主节点A来完成。


如果此时写请求太多,也会给主节点造成 一定的压力。我们可以通过关闭主节点的AOF,毕竟写内存比写磁盘快,只打开从节点的AOF。但是这种设定,有一个严重缺陷,主节点一旦挂了,不能立即重启,因为主节点这边没有使用AOF保存数据,如果重启了,那么数据就会丢失,进一步的主从同步,也就使从节点上数据也丢失了。改进办法是,当主节点挂了,先从从节点那里获取AOF文件,再启动,这样就可以保证数据没有问题了。


一主多从结构

同理,如果是读请求,可以访问主节点,也可以访问从节点。

如果是写请求 ,是能访问主节点,主节点上的数据发生变化,就会把改变的数据同步给其他从节点。

这个结构存在的问题:同步操作是需要消耗网络带宽的,如果子节点太多,就会大大消耗主节点主机的硬件资源。

树形结构

主节点将数据同步给从节点B和从节点C,再由从节点B将数据同步给从节点D和从节点E。

此时主节点A就不需要太高的网络带宽,但此时数据同步的延时会更长。

4,原理

同步数据的命令:PSYNC replicationid offset,这个命令是从节点执行的。


其中replicationid是复制id,是主节点生成的,主节点在启动的时候就会生成。


当从节点和主节点建立了复制关系,就会从主节点上 获取到这个id,这个id就表明了当前从节点是从哪个主节点上获取的数据。


在主节点和从节点上一般都有两个replicationid:replicationid和replicationid2。其中replicationid2其备份的作用,比如下面的例子。


现在有一个主节点A和一个从节点B,A在启动的时候会生成一个replicationid,之后B获取到A的replicationid。如果A和B通信过程中出现了一些网络抖动,B可能会认为A挂了,此时从节点B就会晋升为主节点,并给自己生成一个replicationid,此时B的replicationid2就保存了之前获取到的A的replicationid。等到网络稳定,B还可以根据这个replicationid2再次与节点A建立主从关系。(但是主从复制这种方法,当主节点挂了,一般从节点是不会晋升为主节点的)


这个再次建立主从关系的过程,一般是需要手动完成的。当然,在下面的哨兵机制部分,可以自动完成这个过程。


offset表示偏移量


主节点和从节点都会维护这个偏移量(一个整数)。


主节点的偏移量:主节点可能会收到很多的修改操作的命令,每个命令都选哟占据几个字节。主节点会把这些命令的字节数进行累加,这个数字就是主节点的偏移量。


从节点的偏移量:描述了当前数据同步的进度,从节点会每秒上报自身的偏移量给主节点。


如果从节点和主节点的偏移量一致,就表述数据 同步完成了。


综上,replicationid描述了从哪个主节点同步数据,offset表示同步数据的进度。如果两个机器的replicationid和 offset一样,就表示这两个机器上的数据一致。


replicationid和offset就共同描述了一个"数据集合"。


PSYNC工作流程

PSYNC可以从主节点获取全量数据,也可以获取部分数据。


主要看offset的值,如果设为-1,表示全量获取,如果设置为具体的整数,则表示从当前整数位置来进行获取。


当然,从节点想要全量的获取数据,还是增量的获取数据,同时也取决于主节点,主节点会自行判定,看当前是否方便给部分数据,如果不方便,会直接给 全量数据。

全量复制的流程

在一个从节点与主节点第一次建立主从关系的时候,就会涉及到数据的同步,而此时一般就是进行全量复制。

在进行全量复制的时候,主节点要进行生成rdb文件的操作,然后再把该文件通过网络传输发送给从节点,从节点也是先将该rdb文件保存,然后读取该文件来获取数据。


而redis也支持"无硬盘模式"(diskless):主节点生成的rdb的二进制数据,不直接保存到文件中,而是直接通过网络传输发送给从节点 ,省去了读写硬盘的操作,而从节点现在也可以省去这个操作了,直接将收到数据加载到内存中......


但是,即使引入了"无硬盘模式",对全量复制的效率提升不是很大,因为全量复制整个操作是比较重量的,数据规模较大。相比于网络传输,读写硬盘操作算是快的了。所以减少了对硬盘的操作,但网络传输无法省去,意味着对整个操作的效率提升不大。


部分复制流程

在主节点与从节点连接的过程中,可能由于网络抖动等原因,主从节点的连接断开,此时重新建立连接并进行数据同步的时候,使用的就是部分复制。

实时复制

全量复制:主要适用于从节点刚连上主节点进行数据初始化的工作。


部分复制:是全量复制的一种特殊情况,属于全量复制的一种优化。


实时复制:在从节点与主节点建立好连接,并且完成数据同步之后,此时主节点可能会受到源源不断的请求,其中就会包含修改数据的请求,主节点的数据就会发生变化,此时就要把数据也同步给从节点。从节点和主节点之间建立有Tcp连接,当主节点收到修改数据的请求,就会通过该Tcp连接,将这个请求发送给从节点,从节点再根据这些请求修改数据即可。


所以在实时复制的时候,我们需要保证主节点与从节点的Tcp连接处于可用状态。在这里,使用心跳包机制来实现。


心跳包机制:


主节点:默认每隔10s,向从节点发送一个ping命令,从节点收到后会返回一个"pong"。


从节点:默认每隔1s,向主节点发送一个特定的请求,告诉主节点当前的同步进度(offset),之后主节点也会给出一个响应。


如果,达到某个阈值,还没有收到响应,那么就认为这个主节点/从节点存在问题,判断下线了。

5,总结

主从复制解决的问题:单点问题


单点问题:单个redis节点,可用性不高,性能有限。


主从复制的特点:


1,主节点可以用来读写,从节点只能用来读,可以减少主节点的访问压力。


2,主从复制存在多种拓扑结构:可以在适当的场景使用适当的拓扑结构,比如一主多从的结构,同步操作快,但是消耗的网络资源多,因为主节点要通过网络和所有从节点实现同步。而树形结构,主节点消耗的网络资源减少了,但是如果树的层级太高,会造成数据同步的延迟增长加。


3,复制分为全量复制,部分复制和实时复制。


4,通过心跳机制保证主节点和从节点的正常通信和数据一致。


主从复制的缺点:


1,从节点多了,数据复制的延时就会非常明显。


2,如果主节点挂了,从节点不会晋升为主节点,需要通过人工干预的方式恢复。



相关文章
|
6天前
|
人工智能 运维 安全
|
4天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
565 20
|
12天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
923 109
|
5天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。