MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

拥有备库的主-主复制结构在MySQL中的应用

2022-02-226.8k 阅读

一、MySQL 主 - 主复制基础概念

MySQL 的主 - 主复制是一种特殊的复制拓扑结构,在这种结构中,两个 MySQL 数据库实例都被配置为既是主库(可以接受写入操作并将更改传播给其他副本)又是从库(可以接收并应用来自其他主库的更改)。这与传统的主 - 从复制不同,主 - 从复制中主库负责写入,从库仅用于读取和备份等操作。

在主 - 主复制中,每个节点都可以独立地进行数据写入,并且这些更改会自动同步到另一个节点。这为系统提供了更高的可用性和负载均衡能力。例如,在一个高流量的 Web 应用中,如果使用主 - 主复制结构,两个数据库节点可以分别处理不同的写入请求,从而分担负载。

要实现主 - 主复制,需要在两个 MySQL 实例上进行一系列的配置。首先,每个实例都需要有唯一的服务器 ID。这是 MySQL 用于区分不同服务器的标识,在配置文件(通常是 my.cnf 或 my.ini)中可以通过 server - id 参数进行设置。例如:

[mysqld]
server - id = 1

在另一个实例上则设置为不同的值,如 server - id = 2

二、拥有备库的主 - 主复制结构概述

在一些更为复杂和对可靠性要求极高的场景中,单纯的主 - 主复制可能无法满足需求。拥有备库的主 - 主复制结构在此基础上进行了扩展,引入了一个或多个备库。这些备库可以作为主 - 主节点的额外副本,当主 - 主节点中的任何一个出现故障时,备库可以迅速接管,确保系统的持续运行。

这种结构增加了系统的容错能力。例如,在一个金融交易系统中,数据的完整性和可用性至关重要。如果只有两个主 - 主节点,当其中一个节点因为硬件故障、软件错误或网络问题而无法正常工作时,另一个节点可能无法独自承担所有的业务负载。而备库的存在可以在这种情况下迅速顶上,保证交易的正常进行。

备库与主 - 主节点之间同样通过 MySQL 的复制机制进行数据同步。主 - 主节点将自己的二进制日志(binary log)发送给备库,备库接收并应用这些日志,从而保持数据的一致性。

三、配置拥有备库的主 - 主复制结构

(一)主 - 主节点配置

  1. 配置服务器 ID 如前文所述,在两个主 - 主节点的配置文件中分别设置不同的 server - id。假设节点 A 的配置如下:
[mysqld]
server - id = 1
log - bin = /var/log/mysql/mysql - bin.log
binlog - do - db = your_database_name

这里 log - bin 指定了二进制日志的存储路径,binlog - do - db 表示只记录指定数据库的二进制日志。如果有多个数据库需要同步,可以使用逗号分隔。节点 B 的配置类似,但 server - id 设为不同值,如 server - id = 2

  1. 创建复制用户 在每个主 - 主节点上都需要创建用于复制的用户。以节点 A 为例,登录 MySQL 后执行以下命令:
CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;

这将创建一个名为 replication_user 的用户,允许其从任何主机连接,并授予复制从库相关的权限。在节点 B 上也执行类似操作,创建相同的用户。

  1. 获取主节点状态 在节点 A 上执行 SHOW MASTER STATUS; 命令,会得到类似如下结果:
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql - bin.000003 | 154      | your_database_name |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

记录下 FilePosition 的值,这将用于在节点 B 上配置从库。同样,在节点 B 上执行 SHOW MASTER STATUS; 并记录相应的值。

  1. 配置从库 在节点 B 上配置从库指向节点 A,执行以下命令:
CHANGE MASTER TO
    MASTER_HOST = 'node_a_ip_address',
    MASTER_USER ='replication_user',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql - bin.000003',
    MASTER_LOG_POS = 154;
START SLAVE;

这里 MASTER_HOST 是节点 A 的 IP 地址,MASTER_LOG_FILEMASTER_LOG_POS 是之前在节点 A 上通过 SHOW MASTER STATUS; 获得的值。然后启动从库。同样,在节点 A 上配置从库指向节点 B,只需将相应的参数替换为节点 B 的信息。

(二)备库配置

  1. 配置服务器 ID 在备库的配置文件中设置一个不同于主 - 主节点的 server - id,例如:
[mysqld]
server - id = 3
  1. 创建复制用户 与主 - 主节点类似,在备库上创建用于复制的用户:
CREATE USER'replication_user'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO'replication_user'@'%';
FLUSH PRIVILEGES;
  1. 配置从库指向主 - 主节点 假设备库要同时从节点 A 和节点 B 复制数据。先配置从节点 A 复制,执行以下命令:
CHANGE MASTER TO
    MASTER_HOST = 'node_a_ip_address',
    MASTER_USER ='replication_user',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql - bin.000003',
    MASTER_LOG_POS = 154;
START SLAVE;

然后配置从节点 B 复制,执行:

CHANGE MASTER TO
    MASTER_HOST = 'node_b_ip_address',
    MASTER_USER ='replication_user',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql - bin.000004',
    MASTER_LOG_POS = 200;
START SLAVE;

这里假设从节点 B 获得的 FilePosition 值不同。

四、数据一致性与冲突处理

在主 - 主复制结构中,由于两个主节点都可以独立写入,可能会出现数据一致性问题和写入冲突。例如,两个主节点同时对同一行数据进行不同的更新操作。

(一)数据一致性

MySQL 通过二进制日志和中继日志(relay log)机制来保证数据一致性。主节点在进行写入操作时,会将这些操作记录到二进制日志中。从节点(包括另一个主节点作为从库的情况)会读取主节点的二进制日志,并将其写入自己的中继日志,然后按照顺序应用这些日志中的操作,从而保持数据的一致性。

然而,在实际应用中,由于网络延迟等原因,可能会出现短暂的数据不一致情况。例如,节点 A 刚更新了一条数据,在节点 B 还未同步到这条更新时,客户端从节点 B 读取数据,就可能读到旧的数据。为了减少这种情况的影响,可以采用一些同步策略,如在读取数据前先等待一定时间,确保数据已经同步。

(二)冲突处理

当出现写入冲突时,MySQL 本身并没有内置的自动解决机制。一种常见的处理方法是应用程序层面的冲突检测与解决。例如,在写入数据前,应用程序可以先查询两个主节点上的数据状态,判断是否可能产生冲突。如果可能冲突,则根据业务逻辑进行处理,如选择一个主节点进行写入,或者对数据进行合并处理。

另一种方法是使用一些第三方工具或中间件,如 Orchestrator。Orchestrator 可以监控 MySQL 复制拓扑结构,当检测到冲突时,可以根据预设的规则进行处理,如暂停其中一个主节点的写入,直到冲突解决。

五、性能优化

(一)网络优化

主 - 主复制结构中,数据在不同节点之间传输,网络性能对复制效率有很大影响。可以通过以下方式优化网络:

  1. 使用高速网络:确保主 - 主节点和备库之间使用高速、低延迟的网络连接,如 10Gbps 或更高带宽的网络。
  2. 优化网络拓扑:减少网络跳数,避免网络瓶颈。合理规划网络拓扑结构,确保数据传输路径最短。
  3. 配置网络参数:在操作系统层面,可以调整一些网络参数,如 TCP 缓冲区大小等,以提高网络传输效率。例如,在 Linux 系统中,可以通过修改 /etc/sysctl.conf 文件来调整 net.ipv4.tcp_rmemnet.ipv4.tcp_wmem 等参数。

(二)数据库参数优化

  1. 调整复制相关参数
    • slave_parallel_workers:这个参数用于设置从库并行复制的线程数。适当增加该参数的值可以提高从库应用日志的速度,从而加快复制。例如,可以将其设置为 8 或更高,具体值需要根据服务器的 CPU 核心数和负载情况来确定。
    • sync_binlog:该参数决定了二进制日志刷新到磁盘的频率。默认值为 0,表示由操作系统决定何时刷新。设置为 1 可以确保每次事务提交时都将二进制日志刷新到磁盘,提高数据安全性,但会降低性能。可以根据业务需求在性能和安全性之间进行平衡,如设置为 100,表示每 100 次事务提交刷新一次二进制日志。
  2. 优化缓存参数
    • innodb_buffer_pool_size:InnoDB 存储引擎的缓冲池大小。增大这个值可以提高数据的缓存命中率,减少磁盘 I/O。一般建议将其设置为服务器物理内存的 60% - 80%。例如,如果服务器有 32GB 内存,可以将 innodb_buffer_pool_size 设置为 20GB 左右。
    • key_buffer_size:MyISAM 存储引擎的键缓冲区大小。对于使用 MyISAM 存储引擎的表,适当调整这个值可以提高查询性能。不过,随着 InnoDB 的广泛使用,这个参数的重要性相对降低。

六、监控与维护

(一)监控复制状态

  1. 使用 SHOW SLAVE STATUS 命令 在从库(包括主 - 主节点作为从库以及备库)上执行 SHOW SLAVE STATUS \G 命令,可以获取详细的复制状态信息。例如:
Slave_IO_State: Waiting for master to send event
Master_Host: node_a_ip_address
Master_User: replication_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql - bin.000003
Read_Master_Log_Pos: 154
Relay_Log_File: relay - bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql - bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

重点关注 Slave_IO_RunningSlave_SQL_Running 是否都为 Yes,如果有一个为 No,则表示复制出现问题。还可以查看 Seconds_Behind_Master 字段,它表示从库落后主库的时间(以秒为单位)。如果这个值较大,说明复制延迟严重。

  1. 使用 MySQL Enterprise Monitor 等工具 MySQL Enterprise Monitor 是官方提供的监控工具,可以直观地监控整个复制拓扑结构。它可以实时显示主 - 主节点和备库的状态、复制延迟情况、性能指标等信息,并提供报警功能。当复制出现异常时,可以及时通知管理员进行处理。

(二)维护操作

  1. 定期备份 即使有主 - 主复制和备库,定期备份仍然是非常重要的。可以使用 mysqldump 工具进行逻辑备份,例如:
mysqldump - u root - p your_database_name > backup.sql

也可以使用物理备份工具,如 InnoDB Hot Backup(XBXB)进行热备份,即在数据库运行时进行备份,不会影响正常业务。

  1. 故障恢复 当主 - 主节点或备库出现故障时,需要尽快进行恢复。如果是主 - 主节点故障,可以将备库提升为主库,并重新配置其他节点指向新的主库。例如,如果节点 A 故障,先在备库上执行 STOP SLAVE; 停止从节点 A 的复制,然后执行 RESET MASTER; 重置主库状态,再将其他节点(如节点 B)配置为从新的主库(备库提升后的)复制数据。

七、应用场景

(一)高可用性场景

在对系统可用性要求极高的场景中,如在线支付系统、电商平台等,拥有备库的主 - 主复制结构可以保证即使某个主节点出现故障,系统仍然可以正常运行。备库可以迅速接管故障节点的工作,确保交易的连续性和数据的完整性。

(二)负载均衡场景

对于读多写少的应用,主 - 主节点可以同时处理读请求,分担负载。而备库可以作为备用节点,在主节点负载过高时,也可以分担部分读请求。例如,一个新闻网站,大量用户同时访问网站读取新闻内容,主 - 主节点和备库可以共同处理这些读请求,提高系统的响应速度。

(三)异地数据中心

在企业拥有多个异地数据中心的情况下,可以采用这种结构。每个数据中心设置一个主 - 主节点,同时配置备库。数据在不同数据中心之间同步,既保证了本地数据的可用性,又能实现数据的异地备份和容灾。例如,一家跨国公司在不同国家的数据中心之间可以通过这种方式进行数据同步和管理。

通过以上对拥有备库的主 - 主复制结构在 MySQL 中的详细介绍,包括配置、数据一致性处理、性能优化、监控维护以及应用场景等方面,希望能帮助读者全面了解并在实际项目中合理应用这种强大的数据库复制拓扑结构。在实际应用中,需要根据具体的业务需求和系统架构进行灵活调整和优化,以充分发挥其优势。