一、问题起源
MySQL的主从同步一直有从库延迟的问题,背景资料网上很多,原因简单描述如下:
1、 MySQL从库上有一个IO线程负责从主库取binlog到写到本地。另外有一个SQL线程负责执行这些本地日志,实现命令重放;
2、 正常网络状况下IO线程没有性能问题(这个待会会用到),问题是SQL线程只有一个,更新速度跟不上。所以经常会看到从库的CPU idle很高,但同步性能就是上不去。
二、方案雏形
单线程的SQL线程是造成这个问题的主要原因。比较直接的想法是把它改成多线程版本,这个据说官方版本开发中,其实我们也有一个这样的patch,但是直接写大片代码在线上提供服务的slave机器上这种事儿,都会因为担心稳定性而很难推动(写patch的和运维的同学,你们懂的)。
所以打算用一个“第三方”工具中转,来实现多线程同步。基本结构如下:
说明:
1、这些transefer从master上各自同步一部分的数据,分别独立更新slave。多进程还是多线程均可。
2、Transfer与master之间异步更新日志,transfer与slve之间同步更新数据
3、从这可以看出这个方案的缺点之一:更新能够被独立分开。比较直观的想法是,按照表分。
三、关于transfer
作为这个关键的转发工具transfer,需要提供如下功能:
1、能够指定同步master中的哪部分数据,并且能够方便地修改这个配置以应对master的加表需求;
2、支持stop slave、start slave。支持快速切换到新主库的change master命令。
3、能够记录读取点,transfer自己重启或master重启后能够按照记录点继续读后面的binlog;
4、能够记录分发点,transfer自己重启或slave重启后能够按照记录点继续同步给slave
用起来就会发现还有好多要求。。。
四、方案实现
Transfer的这么多功能,自己造轮子就累了。这里直接用MySQL来充当此角色。为了方便描述,下文还将之称为transfer。Transfer更新slave在功能上可以使用federated引擎,但由于其纠结的实现导致性能上达不到要求,因此在MySQL框架层中作了一点修改――读到同步日志后,直接发送给slave。
方案简单描述如下:
1、 Slave机器上搭另外的若干个MySQL(transfer),将其设为Master的从库,且设置replicate-do-table, 每个transfer承担一部分的表。
2、 所有Transfer的更新目标都设置为slave,其更新方式是读到日志后直接mysql_real_query执行到slave上。
从这可以看出这个方案的缺点之二:只能支持statement格式的同步方式。其实row也能支持,后面再说。
五、仍然延迟?
在transfer放弃federated引擎改用直接发送后,性能提升不少,从库同步性能增加一倍,但从本文第一个图的数据对比就知道,延迟还很大。
发现这个时候slave的机器cpu已经很忙了,idle 20%一下――这个算是好消息,总比idle很高但性能上不去好。
实际上是因为每个transfer,虽然设置只同步其中的部分表,但在实现上是IO线程把master上的所有命令都备份到本地,然后在SQL线程执行的时候再判断,若不符合replicate-do-table,再放弃。
这样存在的问题,是n个transfer,磁盘写了n倍,更严重的是导致SQL线程空转。
我们上文提到整个流程中IO线程是比较空闲的,因此修改IO线程逻辑,在写入磁盘前先判断,若不符合本transfer的replicate-do-table设置,不写盘,直接放弃。
六、效果
从库的QPS由于线程切换会有抖动,但总的执行时间与主库相同。从库的cpu idle下降,与主库几乎同时恢复到100。
七、小结
描述完了,总结一下,方案的代价:
1、要求在slave机器上多配置n个transfer(是否在从库上均可)
2、目前只能支持statement的binlog格式,实际上row可以支持,方案定了,开发计划中。
3、跨表更新的语句,会按照其更新的第一个表,分发到唯一一个transfer,没有重复更新的问题,但有时序性问题。
方案的好处:
1、功能比较齐全。直接使用MySQL,原有的管理功能基本都能用,主库从库重启/换库的代价比较小。
2、开发量小,只在transfer上修改两处,不包括配置读取部分,300行以内
3、风险相对小。不直接修改master和slve上的代码,线上比较容易接收。
- 大小: 39.5 KB
- 大小: 27.8 KB
- 大小: 39.9 KB
分享到:
相关推荐
MySQL 主从同步配置是指将 MySQL 数据库的数据从一台服务器(主服务器)同步到另一台服务器(从服务器)的过程。这种配置可以实现数据的高可用性和灾难恢复,提高系统的整体性能和安全性。 二、 主从同步配置的基本...
在数据库管理领域,MySQL主从同步是一种常见的数据复制技术,它可以帮助我们构建高可用性和数据冗余性,从而提高系统的稳定性和可靠性。本文将详细介绍如何在Linux环境下配置MySQL的主从同步,并通过具体的步骤演示...
MySQL主从同步是一种常见的数据库高可用性和数据冗余策略,它允许数据在多个服务器之间实时复制,确保即使在一台服务器故障时,数据仍然可以被访问。以下是对搭建、修改和优化MySQL主从同步过程的详细解释: 1. **...
在Windows环境下,MySQL主从同步备份是一种常见的高可用性和数据冗余策略,确保数据的安全性和一致性。以下是详细步骤,适用于MySQL 5.0版本: 1. **创建备份账户**: 在主服务器A上,我们需要创建一个用于复制的...
MySQL主从同步是一种数据库复制技术,它允许数据从一个MySQL服务器(称为“主服务器”)实时复制到另一个或多个服务器(称为“从服务器”)。这种配置对于数据备份、负载均衡和高可用性至关重要。在Java开发中,了解...
MySQL主从同步是一种数据库复制技术,它允许一个MySQL服务器(主服务器)的数据被实时地复制到其他服务器(从服务器)上。这种同步可以确保数据的一致性,并在主服务器出现问题时提供故障转移的能力。实现主从同步的...
在Debian系统中实现MySQL主从同步复制是一种常见的数据库高可用性和负载均衡策略。这种技术可以确保数据的安全性并提高系统的整体性能。接下来,我们将详细介绍如何在Debian环境下配置MySQL的主从同步复制。 #### 1...
binlog 是 MySQL 的一种二进制日志文件,它记录了 MySQL 服务器上的所有操作,包括增删改查等。binlog 的格式可以是 Statement、Row 或 Mixed, Statement 格式记录的是 SQL 语句,Row 格式记录的是行级别的操作,...
MySQL主从半同步复制是介于异步复制和全同步复制之间的一种模式,它提供了更好的数据安全性和一致性,同时也尽可能地减少了性能损失。 首先,我们来了解一下什么是MySQL半同步复制。在半同步复制模式下,主服务器在...
MySQL主从同步是数据库架构中常见的一种高可用性解决方案。它可以实现数据的实时备份,分担主库读写操作压力,并提供数据的热备份。在Windows操作系统下配置MySQL主从同步涉及多个步骤,以下将详细解读配置的原理、...
### MySQL主从同步备份 #### 一、MySQL主从同步的作用与原理 ##### 作用 MySQL主从同步机制主要用于实现以下几种应用场景: 1. **数据分布**:通过将数据复制到多个从服务器,可以在不同地理位置分发数据,提高...
【Linux下MySQL主从同步复制】是MySQL数据库在分布式环境中实现数据备份和高可用性的一种常见策略。在Linux操作系统上,这一过程涉及到一系列步骤,包括安装MySQL服务、配置主从服务器、设置复制参数以及验证复制...
Mysql主从同步是指将数据从一个数据库服务器复制到其他服务器上,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上...
MySQL半同步复制(Semi-Synchronous Replication)是一种增强主从复制一致性的方法,它确保在主服务器上的事务提交之前,至少有一个从服务器接收到并应用了该事务的日志。 1. **半同步插件**:MySQL提供了一个名为`...
binlog 日志是 MySQL 服务器上的一种二进制日志,用于记录所有的数据库操作。 启用 binlog 日志 要启用 binlog 日志,需要在 MySQL 配置文件中添加以下配置: [mysqld] log-bin=mysql-bin server_id=1 binlog_...
MySQL 主从同步是一种常见的数据库高可用性和负载均衡解决方案,它允许数据从一个主数据库(Master)实时复制到一个或多个从数据库(Slave)。在这种配置下,所有写操作都在主库上执行,然后由从库自动并异步地复制...
MySQL的主从复制机制是一种数据冗余和高可用性的解决方案,通过该机制可以在一台或多台从服务器上复制主服务器的数据更新。这种方式通常用于备份、负载均衡以及提高数据可用性。 在MySQL主从复制的过程中,一个...