主从复制的实现方案

读写分离技术架构图

主从复制的实现方案_第1张图片

        实现读写分离的技术架构选型如上;需要自己去实践主从复制;为了节省资源,当然系统并发量并没有那么大,选择一主一丛;强制读主库,为了解决主从同步延迟带来的影响;对于实时性要求高的强制读主库;GTID 主要是一种事务标识技术,用来跟踪复制的进度和状态,使得复制和故障恢复更加可靠在一定程度上解决了数据延迟问题;可以基于GTID 的复制方式进行主从同步(是一种异步方式);

        半同步方式是最合适的,由于资源有限实现不了;半同步方式可以1主2从;防止主库数据的丢失。

使用 GTID 的优势:

        复制的简化:GTID 为每个事务分配一个唯一的全局标识符,这意味着在复制和故障恢复时,只需指定 GTID,而不是文件名和文件偏移量。

        自动故障恢复:因为 GTID 能够明确跟踪哪些事务已经在从服务器上执行,所以在主服务器出现问题时,可以更容易地实现故障转移和自动恢复。

        正常的延迟应保持在100ms以内,20ms左右是比较理想的。主要是针对查询及时性要求高的情况

        但是,程序员用到主从库,心里就要有个意识,延迟随时可能发生,甚至会非常严重,在程序设计与开发的时候,要考虑到这个因素。

        场景1:写后立即读。在一个请求中,写入数据后,立即数据库中读取数据。

        这种读的场景,写入和读取的时间间隔小于1ms,比正常的主从延迟时间更短,解决方案就是强制读主库。

        场景2:读后写。这种典型场景就是insertOrUpdate,不存在插入,存在就更新。

        如果两个请求的时间间隔小于主从延迟的时间间隔,第二次的请求因为读不到,就会执行insert。当然可以用强制读主库的方式解决问题;

上面2个:解决方案就是强制读主库

针对这2中场景在编码时要注意走强制读主库;对查询性能要求比较高的情况,也需要强制读主库;

其他的需要各业务系统需要强制读主库的情况需要相关人员开会具体来评估!  

1 主从复制前的准备工作

1.1 主从库创建前需要检查的一些事项

  • 主从两端数据库版本一定要保持一致。
  • 主从库参数建议相同,比如字符集、sql_mode这类参数要设置一样。
  • 从库服务器性能不能过于落后主库,以免因服务器性能产生主从延迟。
  • 所有表强制拥有主键,因为无主键表同步到从库极易产生主从延迟。
  • 建议从库设为read only,以防人为误操作从库数据。
  • 监控主从延迟及状态,及时解决同步中断或延迟问题

1.2 需要在从库中创建所有数据库和数据表,将主库数据表的数据全量导入到从库中。

        可以自己通过mysqldump进行数据导出,然后再用source进行数据恢复到从库中去。

        注意事项:如果主库里面有初始化数据,那么在主从复制前需要把数据先导入到从库以保证初始一致性!

2 GTID主从复制配置流程

  1. 主服务器配置

配置文件

        打开MySQL配置文件。根据你的操作系统和MySQL安装,它通常位于 /etc/my.cnf, /etc/mysql/my.cnf, 或 /etc/mysql/mysql.conf.d/mysqld.cnf。

添加或修改以下行:

[mysqld]

server-id=1              # 每个MySQL服务器需要一个唯一的ID

log-bin                  # 启用二进制日志

gtid-mode=ON            # 启用GTID

enforce-gtid-consistency = ON    # 强制GTID一致性

binlog-format=ROW        # 使用ROW格式的二进制日志

重启MySQL

保存文件并重启MySQL:

service mysql restart       # 或使用 systemctl restart mysql,具体取决于你的系统

创建复制用户

登陆MySQL,创建一个用户供从服务器用来复制数据。

CREATE USER 'replication_user'@'%' IDENTIFIED BY 'password';GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';

FLUSH PRIVILEGES;

注: 出于安全考虑,你应将 '%' 替换为从服务器的具体IP地址,并使用强密码。

  1. 从服务器配置

配置文件

        和主服务器类似,打开从服务器的MySQL配置文件,添加或修改以下行:

[mysqld]

server-id=2         # 为从服务器分配一个唯一ID

relay-log-index=slave-relay-bin.index          # 指定继电日志的索引文件名称

relay-log=slave-relay-bin   # 指定继电日志的名称

log-bingtid-mode=ON

enforce-gtid-consistencybinlog-format=ROW

重启MySQL

service mysql restart

3. 配置从服务器连接到主服务器

在从服务器上运行以下命令,用主服务器的详细信息替换占位符:

CHANGE MASTER TO

    MASTER_HOST='master_server_ip',

    MASTER_USER='replication_user',

    MASTER_PASSWORD='password',

    MASTER_AUTO_POSITION=1;

  1. 启动复制

        在从服务器上运行:

        START SLAVE;

5. 验证

        在主服务器上:

        你可以查看二进制日志状态:

        SHOW MASTER STATUS;

        在从服务器上:

        检查从服务器状态:

        SHOW SLAVE STATUS\G;

重点关注以下几个字段:

        Slave_IO_State: 显示从服务器的I/O线程的状态,如果正常,它应该显示 “Waiting for master to send event”。

        Slave_IO_Running 和 Slave_SQL_Running: 这两个都应该是 "Yes"。

        Seconds_Behind_Master: 显示从服务器落后于主服务器的秒数,这可以用来判断复制的延迟。

          这些步骤应该帮助你详细配置MySQL的GTID主从复制。记得根据你的具体需求和环境调整配置。

3 主从复制验证

        主从复制监控MySQL 的 GTID 主从复制的监控可以通过多种方式来完成。这里我将列举一些常用的方法来查看主从同步的延迟和失败情况。

        1. 使用 SQL 查询

                查看从服务器的状态:可以在从服务器上执行以下 SQL 语句来获取复制的状态:

                SHOW SLAVE STATUS\G;

                这个命令将显示从服务器的复制状态,其中包含了很多有用的信息。例如:

                Seconds_Behind_Master:显示从服务器复制落后于主服务器的时间,用秒表示。这可以帮助你了解主从同步的延迟情况。

                Slave_IO_Running 和 Slave_SQL_Running:这两个状态应该都是 “Yes”,如果不是,说明有错误发生。

                 Last_Error:如果从服务器在复制过程中遇到错误,这里会显示错误信息。

查看主服务器的二进制日志状态:

               SHOW MASTER STATUS\G;

                这个命令会显示主服务器的二进制日志文件名和位置,这对于非 GTID 的复制模式更有用,但也可以用来确认主服务器的二进制日志状态。

2. 使用监控工具

        有很多现成的监控工具可以帮助你监控 MySQL 的主从复制状态,例如:

        Percona Monitoring and Management (PMM):这是一个开源的数据库监控工具,支持 MySQL 和其他数据库。可以提供详细的复制延迟和状态信息。

        Zabbix:也是一个流行的开源监控工具,可以通过插件或模板来监控 MySQL 主从复制。

  1. 自定义脚本

        你也可以编写自定义脚本来定期检查从服务器的状态,并将信息记录到日志文件或发送通知。

        例如,一个简单的 bash 脚本可以这样写:

#!/bin/bash

        SLAVE_STATUS=$(mysql -u root -p'password' -e "SHOW SLAVE STATUS\G")

        SECONDS_BEHIND=$(echo "$SLAVE_STATUS" | grep "Seconds_Behind_Master" | awk '{ print $2 }')

if [ "$SECONDS_BEHIND" -gt "0" ]; then

  echo "Slave is $SECONDS_BEHIND seconds behind master."

else

  echo "Slave is in sync with master."

        请确保替换 'password' 为实际的 MySQL 密码,并根据实际情况调整脚本。

        综上所述,有多种方法可以监控 MySQL 使用 GTID 的主从复制状态。你可以选择最适合你的环境和需求的方法。

4 GTID主从复制办法

基于GTID的主从复制

        GTID是MySQL 5.6的新特性,其全称是Global Transaction Identifier,可简化MySQL的主从切换以及Failover。GTID用于在binlog中唯一标识一个事务。当事务提交时,MySQL Server在写binlog的时候,会先写一个特殊的Binlog Event,类型为GTID_Event,指定下一个事务的GTID,然后再写事务的Binlog。

       在基于GTID的复制中,首先从服务器会告诉主服务器已经在从服务器执行完了哪些事务的GTID值,然后主库会有把所有没有在从库上执行的事务,发送到从库上进行执行,并且使用GTID的复制可以保证同一个事务只在指定的从库上执行一次,这样可以避免由于偏移量的问题造成数据不一致。也就是说,无论是级联情况,还是一主多从的情况,都可以通过GTID自动找位置,而无需像之前那样通过File_name和File_position找主库binlog位置了。

        基于GTID的主从复制与上面基于二进制文件位置的主从复制搭建步骤类似,同样简单展示下搭建过程:

3.1 确认主从库配置,开启GTID

# 主库参数配置 要有以下参数

vim /etc/my.cnf

[mysqld]

        server-id = 137

        log-bin = binlog  

        binlog_format = row

        gtid-mode = ON //开启gtid模式

        enforce-gtid-consistency = ON   //强制gtid一致性,用于保证启动gitd后事务的安全

# 从库建议配置以下参数

vim /etc/my.cnf

 [mysqld]

        server-id = 138

        log-bin = binlog  

        binlog_format = row

        gtid-mode = ON

        enforce-gtid-consistency = ON

        relay-log = relay-bin

        read_only = on

3.2 创建同步账号,保持主从库数据一致

        若主库刚初始化完成或者主库端保留有全部二进制文件,则从库无需手动同步数据。否则需要手动同步数据使得主从一致。

        # 主库创建同步账号create user 'repl'@'%' identified by '123456';grant replication slave on *.* to 'repl'@'%';

        # 若主库刚初始化或保留有完整二进制文件 则无需执行下面步骤

        # 全备主库数据mysqldump -uroot -pxxxx -A -R -E --single-transaction  > all_db.sql

        # 从库端恢复mysql -uroot -pxxxx < all_db.sql

3.3 进入从库,开启主从复制

        # 进入从库MySQL命令行 执行change master语句连接主库CHANGE MASTER TO         MASTER_HOST='MySQL主服务器IP地址',  

        MASTER_PORT=3306,

        MASTER_USER='repl',  

        MASTER_PASSWORD='123456',  

        MASTER_AUTO_POSITION = 1;

        # 开启主从复制 并坚持状态start slave;

        show slave status \G

5 主从复制配置需要注意的参数

2.1:限制从服务器为只读

        在从服务器上设置:read_only = ON,但是此限制对拥有SUPER权限 的用户均无效。

阻止所有用户:

        mysq>FLUSH TABLES WITH READ LOCK;

2.2在主节点设置参数

        sync_binlog=1: Mysql开启bin-log日志使用bin-log时,默认情况下,并不是每次执行写入就与硬盘同步,这样在服务器崩溃时,就可能导致bin-log最后的语句丢失。可以通过这个参数来调节,sync_binlog=N,使执行N次写入后,与硬盘同步。1是最安全的,但是也是最慢的。

如果用到innode 存储引擎:

        innodb_flush_logs_at_trx_commit=ON(刷写日志:在事务提交时,要将内存中跟事务相关的数据立即刷写到事务日志中去。)

        innodb_support_xa=ON (分布式事务:基于它来做两段式提交功能)

        sync_master_info=1:每次给从节点dump一些事件信息之后,主节点的master info 信息会立即同步到磁盘上。让从服务器中的 master_info 及时更新。

2.3 在每个slave节点

        skip_slave_start =ON (跳过自动启动,使用手动启动)

        relay_log也会在内从中先缓存,然后在同步到relay_log中去,可以使用下面参数使其立即同步。

        sync_relay_log =1 ,默认为10000,即每10000次sync_relay_log事件会刷新到磁盘。为0则表示不刷新,交由OS的cache控制。

        sync_relay_log_info=1每间隔多少事务刷新relay-log.info,如果是table(innodb)设置无效,每个事务都会更新.

你需要根据自己的具体需求、系统负载和数据安全性要求来决定是否和如何设置这些参数。

6 GTID 主从复制失败处理方式

主从复制的实现方案_第2张图片

        GTID 主从复制中的数据同步失败可以由多种原因引起,例如网络问题、硬盘空间不足、主从服务器版本不兼容等。以下是一些常见的解决步骤:

1. 识别问题

        首先,你需要确定问题的根源。在从服务器上执行以下命令来查看复制的状态和可能的错误:

        SHOW SLAVE STATUS\G;

        检查 Last_Error 和 Last_IO_Error 字段,这里会显示从服务器在尝试复制数据时遇到的最后一个错误。

  1. 解决具体问题

        网络问题:检查从服务器到主服务器的网络连接。确保网络是稳定的,防火墙和网络策略允许连接。

        硬盘空间:确保主从服务器都有足够的硬盘空间。磁盘空间不足会导致复制失败。

        版本兼容性:确保主从服务器的 MySQL 版本是兼容的。

        错误的事务或查询:有时,某些特定的事务或查询可能会导致复制失败。你需要根据错误消息来解决这些特定问题。

3. 重启复制

        一旦问题被解决,你可能需要重启复制进程。在从服务器上执行以下命令:

        STOP SLAVE;

        START SLAVE;

        这会停止并重新启动从服务器的复制进程。

4. 验证复制状态

        再次执行 SHOW SLAVE STATUS\G; 命令,检查 Slave_IO_Running 和 Slave_SQL_Running 字段。如果都是 “Yes”,说明复制已恢复。

5. 数据一致性检查

        你可能需要使用一些工具,如 pt-table-checksum 从 Percona Toolkit,来检查主从服务器的数据一致性。如果数据不一致,你可能需要重新同步数据。

6. 监控和日志

        增加监控和日志记录,以便于快速识别和解决未来可能出现的问题。记录详细的错误信息,持续监控主从延迟和状态。

7. 处理错误

        针对特定的错误代码和消息,可能需要采取特定的操作来修复错误。例如,跳过某个造成错误的事务(虽然这需要谨慎操作,因为它可能导致数据不一致)。

        每个复制错误都有其具体的背景和上下文,解决方案可能因情况而异。始终确保在采取任何纠正措施之前都充分了解问题的根源和潜在影响。

7 GTID 主从复制数据同步延迟处理办法

        GTID 主从复制中的数据同步延迟是一个常见问题,可以由许多因素引起,包括网络延迟、硬件性能限制、大量的写操作等。以下是一些常见的处理延迟的方法:

1. 诊断问题

        监控工具: 使用 MySQL 的监控工具,例如 Percona Monitoring and Management 或 Zabbix,来监控复制延迟。

        SHOW SLAVE STATUS: 通过运行 SHOW SLAVE STATUS\G; 语句,并查看 Seconds_Behind_Master 的值来手动检查延迟。

2. 优化服务器性能

        硬件升级: 增加更多的 RAM、使用更快的 CPU 或 SSD。

        配置优化: 调整 MySQL 配置以更好地匹配你的硬件和工作负载。

3. 网络优化

        带宽: 确保网络带宽足够,减少网络延迟。

        位置: 如果可能,将主从服务器放在物理位置接近的地方。

4. 减少写操作

        批处理: 批量处理写操作,减少单个事务的大小。

        读写分离: 将读操作从主服务器移到从服务器,减轻主服务器的负担。

5. 优化查询

        索引: 确保数据库表正确索引,优化查询。

        查询优化: 优化慢查询,减少复杂查询。

6. 其他 MySQL 参数调整

        并行复制: 如果使用的 MySQL 版本支持,可以开启并行复制来减少延迟。

        日志: 调整二进制日志和 relay log 的设置,优化 IO 操作。

7. 故障恢复计划

        自动化: 在允许的情况下,实现故障检测和恢复的自动化。

        备份: 保持数据的定期备份。

示例

        如果你发现 Seconds_Behind_Master 的值较高,需要确定延迟的原因。这可能是由于网络延迟、主服务器上的大量写操作或从服务器的性能限制。

        例如,你可以检查从服务器的 CPU 和内存使用情况,查看是否有性能瓶颈。如果从服务器的资源使用率高,可能需要升级硬件或优化 MySQL 配置。

        如果延迟是由大量写操作引起的,可以考虑优化写操作,例如通过批处理或优化查询来减少写操作的数量和复杂性。

        每个情况都是唯一的,因此重要的是先诊断问题的原因,然后根据具体情况采取适当的行动。

你可能感兴趣的:(项目实战经验分享,java,mysql,架构,数据库)