MySQL之复制(十四)

复制

复制有多快

关于复制的一个比较普遍的问题是复制到底有多快?简单来讲,它与MySQL从主库复制事件并在备库重放的速度一样快。如果网络很慢并且二进制日志事件很大,记录二进制日志和在备库上执行的延迟可能会非常明显。如果查询需要执行很长事件而网络很快。通常可以认为查询事件占据了更多的复制时间开销。
更完整的答案是计算每一步花费的时间,并找到应用种耗时最多的那一部分。一些人可能只关注主库上记录事件和将事件复制到中继日志的时间间隔。对于那些想要了解更多细节的人,我们可以做一个快速的实验。
前面详细地描述了复制的过程和Giuseppe Maxia提供的测量高精度复制速度的方法。我们创建了一个非确定性的用户自定义函数(UDF),以微妙精度返回系统时间:

mysql>SELECT NOW_USEC();

首先将NOW_USEC()函数的值插入到主库的一张表种,然后比较它在备库上的值,以此来测量复制的速度。为了测量延迟,我们在一台服务器上开启两个MySQL实例,以避免由于时钟引起的不精确。我们将其中一个实例配置为另一个的备库,然后在主库实例上执行如下语句:

mysql>CREATE TABLE test.lag_test( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, now_usec VARCHAR(26) NOT NULL);
mysql> INSERT INTO test.lag_test(now_usec) VALUES (NOW_USEC());

我们使用的是VARCHAR列,因为MySQL内建的时间类型只能精确到秒(尽管一些时间函数可以执行小于秒级别的计算),剩下的就是比较主备的差异。这里我们使用Federated表.在备库上执行:

mysql>CREATE TABLE test.master_varl (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, now_usec VARCHAR(26) NOT NULL) ENGINE=FEDERATED CONNECTION='mysql://user:pass@127.0.0.1/test/lag_test';

简单的关联和TIMESTAMPDIFF()函数可以微妙精度显示主库和备库上执行查询的延迟。

mysql>SELECT m.id, TIMESTAMPDIFF(FRAC_SECOND, m.now_usec,s.now_usec) AS usec_lag FROM test.lag_test as s INNER JOIN test.master_val AS m USING(id);

这里得到的usec_lag是476.我们使用Perl脚本向主库插入1 000行数据,每个插入间有10毫秒的延时,以避免主备实例竞争CPU是按。然后创建一个临时表来存储每个时间的延迟:

mysql>CREATE TABLE test.lag AS SELECT TIMESTAMPDIFF(FRAC_SECOND, m.now_usec, s.now_usec) AS lag FROM test.master_val AS m INNER JOIN test.lag_test AS s USING(id);

接着根据延迟时间分组,可以看到最常见的延迟时间是多少:

mysql>SELECT ROUND(lag/ 1000000.0, 4) * 1000 AS msec_lag COUNT(*) FROM lag GROUP BY msec_lag ORDER BY msec_lag;

结果显示大多数小查询在主库上的执行时间和备库上的执行时间间隔大多数小于0.3毫秒。复制过程种没有计算的部分是事件在主库上记录到二进制日志需要多长事件传递到备库。有必要知道这一点,因为备库越快接收到日志事件越好。如果备库已经接收到了事件,它就能在主库崩溃时提供一个拷贝。尽管测量结果没有精确地显示这部分需要多少事件,但理论上非常快(例如,仅仅受限于网络速度)。MySQL二进制日志转储线程并没有通过轮询的方式从主库请求事件,而是由主库来通知备库新的实践,因为前者低效且缓慢。从主库读取一个二进制日志事件是一个阻塞型网络调用,当主库记录事件后,马上就开始发送。因此可以说,只要复制线程被环形并且能够通过网络传输数据,事件就会很快到达备库

MySQL复制的高级特性

Oracle对MySQL5.5的复制有着明显的改进。更多的特性还在开发种,MySQL5.6将包含这些特性。一些改进使得复制更加强健,例如,增加了多线程(并行)复制以减少当前单线程复制的瓶颈。另外,还有一些改进增加了一些高级特性,使得复制更加灵活并可控制。
第一个是半同步复制,基于Google多年前所做的工作。这是自MySQL5.1引入行复制后最大的改进。它可以帮助你确保备库拥有主库数据的拷贝,减少了潜在的数据丢失危险。半同步复制在提交过程种增加了一个延迟:当提交事务时,在客户端接收到查询结束反馈前必须保证二进制日志已经传输到至少一台备库上。主库将事务提交到磁盘上之后会增加一些延迟。同样的,这也增加了客户端的延迟,因此其执行大量事务的速度不会比将这些事务传递给备库的速度更快。关于半同步,有一些普遍的误解,下面时它不会去做的:

  • 1.在备库提示其已经受到事件前,会阻塞主库上的事务提交。事实上在主库上已经完成事务提交,只有通知客户端被延迟了
  • 2.直到备库执行事务后,才不会阻塞客户端。备库在接收到事务后发送反馈而非完成事务后发送
  • 3.半同步不总是能够工作。如果备库一直没有回应已收到事件,会超时并转化为正常的异步复制模式

尽管如此,这仍然是一个很好用的工具,有助于确保备库提供更好的冗余度和持久性。在性能方面,从客户端的角度来看,增加了事务提交的延时,延时的多少取决于网络传输,数据写入和刷新到备库磁盘的时间(如果开启了配置)以及备库反馈的网络时间。听起来似乎这是累加的,但测试表明这些几乎是不中国要的,也许延迟是由其他原因引起的。Giuseppe Maxia发现每次提交大约延时200微妙.对于小事务开销可能会比较明显,这也是预期中的。
事实上半同步复制在某些场景下确实能够提供足够的灵活性以改善性能,在主库关闭sync_binlog的情况下保证更加安全。写入远程的内存(一台备库反馈)比写入本地的磁盘(写入并刷新)要更快。Henrik Ingo运行了一些性能测试表明,使用半同步复制相比在主库上进行强持久化的性能有两倍的改善。在任何系统上都没有绝对的持久化)只有更加高的持久化层次——并且看起来半同步复制应该是一种比其他替代方案开销更小的系统数据持久化方法。
除了半同步复制,MySQL5.5还提供了复制心跳,保证备库一直与主库相联系,避免悄无声息地断开连接。如果出现断开的网络连接,备库会注意到丢失的心跳数据。当使用基于行的复制时,还提供了一种改进的能力来处理主库和备库上不同的数据类型。有几个选项可以用于配置复制元数据文件是如何刷新到磁盘以及在一次崩溃后如何处理中继日志,减少了备库崩溃恢复后出现问题的概率

其他复制技术

MySQL内建的复制并不是将数据从一台服务器复制到另外一台服务器的唯一办法,尽管大多时候是最好的办法。前面已经讨论了MySQL复制的一些扩展性技术,如Oracle GoldenGate,但对大多数工具我们都不熟悉,因此无法讨论太多。但是有两个我们需要指出来,第一个是Percona XtraDB Cluster的同步复制。另一个是Continuent的Tungsten Replicator.
Tungsten是一个用Java编写的开源的中间件复制产品。它的功能和Oracle GoldenGate类似,并且开起来在未来发布的版本中将逐步增加许多的特性。例如,在服务器间复制数据、自动数据分片、在备库并发执行更新(多线程复制)、当主库失败时提升备库、跨平台复制,以及多源复制(多个复制源到一个目标)。它是Tungsten数据库的clustering suite的开源版本。
Tungsten同样实现了多主库集群,可以把写入指向集群中任意一台服务器。这种架构实现通常都包含冲突发现与解决。这一点很难做到,并且不总是需要的。Tungsten的实现稍微做了点限制,不是所有的数据都能在所有的节点写入,每个节点被标记为记录系统,以接收特定的数据。例如,在西雅图的办公室可以拥有并写入它的数据,然后复制到休斯敦和巴尔的摩。在休斯敦和巴尔的摩本地可以实现低延迟读数据,但在这里Tungsten不允许写入数据,这样数据冲突就不存在了。当然休斯敦和巴尔的摩可以更新它们自己的数据,并被复制到其他地点。这种"记录系统"方案解决了人们需要在环形结构中频繁调整内建MySQL复制的问题。
Tungsten Replicator不仅仅时嵌入或管理MySQL复制,而是直接替代它。它通过读取主库的二进制日志来获得数据更新,那里正是内建MySQL复制工作结束的地方,然后由Tungsten Replicator接管。它读取二进制日志,并抽取事务,然后再备库执行它们。
该过程比MySQL复制本身有更丰富的功能集。实际上,Tungsten Replicator是第一个提供MySQL并行复制支持的。它声称能够提供最多三倍的复制速度改善,具体取决于负载特性,基于该架构以及对该产品的了解,这看起来是可信的。
一下是关于Tungsten Replicator中值得欣赏的部分:

  • 1.它提供了内建的数据一致性检查
  • 2.提供了插件特性,因此可以编写自己的函数。MySQL的复制源代码非常难以理解并且很难去修改。即使非常聪明的程序员再试图修改时,也会引入新的Bug,因而能有途径去修改复制而无须修改MySQL的复制代码,是非常理想的。
  • 3.拥有全局事务ID,能够帮助你了解每个服务器相互之间的状态而无须去匹配二进制日志名和偏移量
  • 4.它是一个高可用的解决方案,能够快速地将一台备库提升为主库
  • 5.提供异构数据复制(例如,在MySQL和PostgreSQL之间或者MySQL和Oracle之间)
  • 6.支持不同版本的MySQL复制,以防止MySQL复制不能反向兼容。这对某些升级的场景非常有用。当升级运行得不理想时,你可能无法设计一个可行的回滚方案,或者必须升级服务器到一个并不是你期望的版本
  • 7.并行复制的设计非常适用于共享应用程序或多任务应用程序
  • 8.Java应用能够明确地写入主库并从备库读取
  • 9.得益于Giuseppe Maxia作为QA主管的大量工作,现在比以往更加简单并且更加容易配置和管理。
    以下是它的一些缺点:
  • 1.它比内建的MySQL复制更加复杂,有更多可变动的地方需要配置和管理,毕竟它是一个中间件
  • 2.在你的应用栈中需要多学习和理解一个新的工具
  • 3.它并不像内建的MySQL复制那样轻量级,并且没有同样的性能。使用Tungesten Replicator进行单线程复制比MySQL的单线程复制要慢
  • 4.作为MySQL复制并没有经过广泛的测试和部署,所以Bug和问题的风险很高。

总而言之,Tungtsten是可用的,并且在积极的开发中,稳定地释放新的特性和功能,拥有一个可替代内建MySQL复制的选择,这非常棒,使得MySQL能够适用于更多的应用场景,并且足够灵活,能够满足内建的MySQL复制可能永远无法满足的需求

  • 34
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coffee_babe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值