Mysql集群:主从同步,负载均与读写分离

MySQL主从同步(Master-Slave Replication)是一种常用的数据库冗余和扩展策略。在这种架构中,一个MySQL服务器(称为主服务器,Master)将数据更改复制到一个或多个其他服务器(称为从服务器,Slave)。

主从同步基本原理

MySQL主从同步的基本原理如下:

  1. 主服务器上的数据更改(如插入、更新、删除操作)会记录在二进制日志(Binary Log)中。每个数据更改都会生成一个日志事件(Log Event),包括事务的提交、回滚等。
  2. 从服务器会启动一个I/O线程,连接到主服务器并请求二进制日志。I/O线程会从主服务器读取日志事件,并将它们写入从服务器的中继日志(Relay Log)。
  3. 从服务器还会启动一个SQL线程,从中继日志中读取日志事件并在从服务器上执行这些操作。这样,从服务器上的数据更改会与主服务器保持一致。

主从同步实践

在MySQL 5.7中配置一主一从同步,可以按照以下步骤进行:

配置主服务器(Master)

  1. 修改主服务器的配置文件(my.cnf或my.ini,通常位于/etc/mysql/或/etc/mysql/mysql.conf.d/目录下)。在[mysqld]部分添加以下配置:
  2. bash复制代码
  3. [mysqld] server-id=1 log-bin=mysql-bin binlog-format=ROW sync_binlog=1 binlog-do-db=your_database_name
  4. 其中:
  5. server-id:为主服务器分配一个唯一的ID,这里设置为1。
  6. log-bin:启用二进制日志,并指定日志文件的前缀。
  7. binlog-format:设置二进制日志的格式,这里使用ROW格式。
  8. sync_binlog:设置为1,表示每次事务提交时都将日志写入磁盘。这可以提高数据一致性,但可能会影响性能。
  9. binlog-do-db:指定需要同步的数据库名称。
  10. 重启MySQL服务使配置生效。在Linux系统中,可以使用以下命令:
  11. bash复制代码
  12. sudo service mysql restart
  13. 登录到MySQL,创建一个用于复制的用户并授权:
  14. bash复制代码
  15. CREATE USER 'repl_user'@'%' IDENTIFIED BY 'your_password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES;
  16. 获取主服务器的二进制日志文件名称和位置信息。这将在配置从服务器时用到:
  17. ini复制代码
  18. SHOW MASTER STATUS;
  19. 记下File和Position列的值,例如:mysql-bin.000001和154.

配置从服务器(Slave)

  1. 修改从服务器的配置文件(my.cnf或my.ini)。在[mysqld]部分添加以下配置:
  2. bash复制代码
  3. [mysqld] server-id=2 relay-log=mysql-relay-bin log-slave-updates replicate-do-db=your_database_name
  4. 其中:
  5. server-id:为从服务器分配一个唯一的ID,这里设置为2。
  6. relay-log:指定中继日志文件的前缀。
  7. log-slave-updates:设置从服务器记录二进制日志事件。
  8. replicate-do-db:指定需要同步的数据库名称。
  9. 重启MySQL服务使配置生效。
  10. 登录到MySQL,配置从服务器连接到主服务器:
  11. ini复制代码
  12. CHANGE MASTER TO MASTER_HOST='master_ip_or_hostname', MASTER_USER='repl_user', MASTER_PASSWORD='your_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
  13. 使用步骤1中获取的File和Position值替换MASTER_LOG_FILE和MASTER_LOG_POS。
  14. 启动从服务器的复制进程:
  15. ini复制代码
  16. START SLAVE;
  17. 检查从服务器的复制状态:
  18. sql复制代码
  19. SHOW SLAVE STATUS\G
  20. 确保Slave_IO_Running和Slave_SQL_Running的值都为Yes,表示复制正在正常运行。

主从同步复制策略

MySQL中的主从同步有多种复制策略,主要包括以下三种

  • 异步复制(Asynchronous Replication)
  • 半同步复制(Semi-Synchronous Replication)
  • 全同步复制(Synchronous Replication)

异步复制(Asynchronous Replication)

MySQL默认的复制策略是异步复制(Asynchronous Replication)。在异步复制中,主服务器在执行事务并将更改记录到二进制日志(Binary Log)后,不会等待从服务器的确认。主服务器会继续处理其他事务,而从服务器则负责在后台读取并应用这些日志事件。

异步复制的优势和劣势如下:

  • 优势:由于主服务器不需要等待从服务器的确认,异步复制具有较低的性能开销,可以提高主服务器的事务处理速度。
  • 劣势:异步复制可能导致主从服务器之间的数据不一致,因为在主服务器和从服务器之间可能存在一定的延迟。此外,在主服务器发生故障的情况下,从服务器可能无法获取到最近的数据更改,从而导致数据丢失。

半同步复制(Semi-Synchronous Replication)

半同步复制是介于异步复制和全同步复制之间的一种复制策略。在半同步复制中,当主服务器执行完一个事务并将更改记录到二进制日志后,它会等待至少一个从服务器确认已经接收到这些更改。确认接收后,主服务器才会提交事务并继续处理其他事务。这样,半同步复制可以确保至少有一个从服务器始终与主服务器保持数据一致,从而降低数据丢失的风险。

半同步复制的优势和劣势如下:

  • 优势:相较于异步复制,半同步复制提供了更好的数据一致性保证,降低了数据丢失的风险。
  • 劣势:由于主服务器需要等待从服务器的确认,半同步复制可能导致事务提交的延迟,影响性能。

为了启用半同步复制,需要在主服务器和从服务器上安装半同步插件,并在配置文件中启用相应的参数。

全同步复制(Synchronous Replication)

全同步复制是指在主服务器将数据更改记录到二进制日志后,等待所有从服务器确认已接收并应用这些更改。只有当所有从服务器都确认后,主服务器才会提交事务并继续处理其他事务。全同步复制可以确保主从服务器之间的数据始终保持一致,从而提供最高级别的数据一致性保证。

全同步复制的优势和劣势如下:

  • 优势:全同步复制提供了最高级别的数据一致性保证,几乎消除了数据丢失的风险。
  • 劣势:由于需要等待所有从服务器的确认,全同步复制可能会导致较大的性能开销和事务延迟。

MySQL本身并不直接支持全同步复制。然而,可以通过使用第三方解决方案来实现全同步复制,例如使用Galera Cluster或Percona XtraDB Cluster。

SQL Thread执行策略

在MySQL复制过程中,从服务器会启动一个SQL线程(SQL Thread)来应用从主服务器接收到的日志事件。这个线程会从中继日志(Relay Log)中读取日志事件,并在从服务器上执行这些操作。SQL线程的一些策略和特性如下:

  1. 单线程执行:默认情况下,MySQL复制中的SQL线程是单线程的。这意味着,尽管主服务器上的事务可能是并行执行的,但在从服务器上应用这些事务时,它们会按照顺序一个接一个地执行。这可能导致从服务器在高并发场景下出现性能瓶颈。
  2. 多线程复制:为解决单线程执行的性能问题,MySQL 5.6及更高版本引入了多线程复制(Parallel Replication)。在多线程复制中,从服务器可以启动多个工作线程并行地应用日志事件。多线程复制可以在一定程度上提高从服务器的性能,但它需要考虑数据一致性和线程之间的同步。要启用多线程复制,需要配置slave_parallel_type和slave_parallel_workers参数。
  3. 自动恢复:当从服务器重启或者复制过程中出现问题时,SQL线程会尝试自动恢复。这意味着,如果问题是暂时性的,例如网络波动,SQL线程会自动重新连接到主服务器并继续应用日志事件。然而,在某些情况下,例如数据不一致,SQL线程可能无法自动恢复,此时需要手动干预。
  4. 延迟复制:从MySQL 5.6开始,可以配置从服务器延迟复制指定的时间。这可以通过设置slave_delay参数来实现。延迟复制可以用于实现时间点恢复或者保护主服务器免受误操作的影响。需要注意的是,延迟复制可能会导致从服务器与主服务器之间的数据差异增大。
  5. 过滤器:在从服务器上,可以使用过滤器来指定需要应用哪些数据库和表的更改。这可以通过在配置文件中设置replicate-do-db、replicate-ignore-db、replicate-do-table和replicate-ignore-table参数来实现。过滤器可以用于减少从服务器上不需要的数据,并降低网络和存储资源的消耗。

主从同步常见问题:主备延迟

MySQL主从同步中,主备延迟(Master-Slave Lag)是指从服务器在复制主服务器上的数据更改时可能出现的延迟。

假设有如下过程

  1. 主库 A 执行完成一个事务,写入 binlog,我们把这个时刻记为 T1;
  2. 之后传给备库 B,我们把备库 B 接收完这个 binlog 的时刻记为 T2;
  3. 备库 B 执行完成这个事务,我们把这个时刻记为 T3。

网络正常的时候,日志从主库传给备库所需的时间是很短的,即 T2-T1 的值是非常小的。也就是说,网络正常情况下,主备延迟的主要来源是备库接收完 binlog 和执行完这个事务之间的时间差

我们可以使用Seconds_Behind_Master作为衡量主备延迟(Master-Slave Lag)的一个指标。

Seconds_Behind_Master是MySQL从服务器上的一个状态变量,用于表示从服务器在复制主服务器上的数据更改时的延迟。它以秒为单位表示从服务器在处理二进制日志(Binary Log)时落后主服务器的时间。

要查看Seconds_Behind_Master的当前值,可以在从服务器上执行以下命令:

bash复制代码SHOW SLAVE STATUS\G

以下是一些可能导致主备延迟的原因:

  1. 网络延迟:主服务器和从服务器之间的网络连接可能会出现延迟,尤其是在跨地域或云环境中。当网络延迟较高时,从服务器接收主服务器发送的二进制日志数据会变慢,从而导致主备延迟。
  2. 主服务器负载:当主服务器上的负载很高时,它可能会花费更多的时间来生成和发送二进制日志。这可能导致从服务器在接收到日志数据时出现延迟。
  3. 从服务器负载:从服务器上的负载也可能导致主备延迟。如果从服务器在执行其他任务(例如查询、备份等)时资源不足,它可能会花费更多的时间来应用主服务器上的数据更改。
  4. 单线程SQL线程:默认情况下,MySQL复制使用单线程SQL线程在从服务器上应用主服务器的数据更改。在高并发场景下,单线程SQL线程可能成为性能瓶颈,导致主备延迟。可以通过启用多线程复制来缓解这一问题。
  5. 大事务或者慢查询:在主服务器上执行的大事务或者慢查询可能会导致从服务器在应用这些更改时出现延迟。优化查询性能和分割大事务可以帮助减少主备延迟。
  6. 延迟复制:MySQL允许配置从服务器延迟复制指定的时间。这是通过设置slave_delay参数实现的。延迟复制可以用于实现时间点恢复或保护主服务器免受误操作的影响,但会导致从服务器与主服务器之间的数据差异增大。

Mysql中间件: 负载均衡与读写分离(MyCat)

MySQL中间件是位于应用程序和MySQL数据库之间的软件层,用于处理应用程序与数据库之间的通信。以下是一些常见的MySQL中间件,它们提供了连接管理、查询路由、负载均衡、读写分离等功能:

  1. ProxySQL:ProxySQL是一个高性能、高可用的MySQL代理和负载均衡器。它提供了查询路由、连接池、多路复用、查询缓存等高级功能,适用于对数据库服务进行优化和管理的场景。
  2. MyCAT:MyCAT是一个基于Java的MySQL中间件,主要用于实现数据库的分片、读写分离和负载均衡。它提供了灵活的配置和插件机制,可以根据具体需求进行定制。

下面的例子将展示如何使用MyCAT进行负载均衡和读写分离

部署MySQL主从服务器

准备一个MySQL主从服务器环境,至少包括一个主服务器(Master)和一个或多个从服务器(Slave)。主服务器负责处理写操作(INSERT、UPDATE、DELETE),从服务器负责处理读操作(SELECT)。

安装并配置MyCAT

下载MyCAT

访问MyCAT的GitHub仓库(github.com/MyCATApache…),在“Releases”页面下载最新版本的MyCAT。也可以直接使用wget命令下载:

bash复制代码wget <https://github.com/MyCATApache/Mycat-Server/releases/download/><latest-version>/mycat-<latest-version>-bin.tar.gz

请将<latest-version>替换为实际的版本号。

解压MyCAT

解压下载的MyCAT压缩包:

bash复制代码tar -zxvf mycat-<latest-version>-bin.tar.gz

配置MyCAT

进入MyCAT解压后的目录,编辑conf/schema.xml文件以配置数据库信息。在<dataHost>标签中,配置主从服务器的信息:

xml复制代码<dataHost name="dataHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master" url="192.168.0.2:3306" user="root" password="123456">
        <readHost host="slave1" url="192.168.0.3:3306" user="root" password="123456"/>
        <readHost host="slave2" url="192.168.0.4:3306" user="root" password="123456"/>
    </writeHost>
</dataHost>

请将url、user和password替换为实际MySQL主从服务器信息。

然后,在<schema>标签中配置数据库模式和表信息:

xml复制代码<schema name="mydb" checkSQLschema="false" sqlMaxLimit="100">
    <table name="user" primaryKey="id" dataNode="dataNode1" rule="rule1"/>
</schema>

这里的name属性应实际数据库名称相匹配,table标签中的name属性应与实际数据表名称相匹配。

配置MyCAT监听端口

编辑conf/server.xml文件,配置MyCAT的监听端口。默认情况下,MyCAT监听在8066端口。可以根据需要修改该端口。

启动MyCAT

在MyCAT的目录中,运行以下命令启动MyCAT:

bash复制代码./bin/mycat start

将应用程序连接到MyCAT

将应用程序连接到MyCAT而不是直接连接到MySQL服务器。修改应用程序的数据库连接配置,将其指向MyCAT服务器的IP地址和监听端口。例如,在Java应用程序中,可以修改application.properties文件:

xml复制代码spring.datasource.url=jdbc:mysql://<mycat-server-ip>:<mycat-server-port>/<your-database-name>?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
spring.datasource.username=<mycat-username>
spring.datasource.password=<mycat-password>
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

将<mycat-server-ip>、<mycat-server-port>、<your-database-name>、<mycat-username>和<mycat-password>替换为实际MyCAT和数据库信息。

现在,应用程序将通过MyCAT与MySQL数据库通信。MyCAT会自动将写操作路由到主服务器(Master),将读操作路由到从服务器(Slaves)。这样,在应用程序层面,无需关心数据库的负载均衡和读写分离,可以专注于业务逻辑的实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值