赞
踩
当客户端提交一个事务到MySQL的集群后,直到客户端收到集群返回成功响应,这个过程种,MySQL集群需要执行很多操作:
这些操作的时序非常重要,这里面的“时序”,说的就是这些操作的先后循环。同样的操作,因为时序不同,对应用程序来说,有很大的差异。比如,如果先复制binlog,等binlog复制到从节点上之后,主节点再去提交事务,这种情况下,从节点的binlog一直和主节点是同步的,任何情况下主节点宕机也不会丢数据。但是如果把这个时序倒过来,先提交事务再复制binlog,性能就会非常好,但是存在丢失数据的风险。
MySQL提供了几个参数来配置这个时序,我们先来看一下默认情况下的时序是怎么样的。
提交事务和复制这两个流程在不同的线程中执行,互相不会等待,这是异步复制。异步复制没有办法保证数据能够第一时间复制到从库上
与异步相对的是同步复制。同步复制的时序和异步复制基本是一样的,唯一的区别是,什么时候给客户端返回响应。
同步复制这种方式在实际项目中,基本没法用,原因有两个:
为了解决这个问题,MySQL从5.7版本开始,增加了一种半同步复制。异步复制是事务线程完全不等复制响应;同步复制是事务线程要等待所有的复制响应;半同步复制介于两者之间,事务线程不用等所有的复制成功响应,只要一部分复制响应回来之后,就可以给客户端返回了
比如说,一主二从的集群,配置成半同步复制,只要数据成功复制到任意一个从库上,主库的事务线程就直接返回了。这种半同步复制的方式,它兼顾了异步复制和同步复制的优点:
那,实际应用中,选择半同步是需要注意哪些问题呢?
另外,虽然我们配置了同步或者半同步复制,并且要等待复制成功后再提交事务,还是有一种特别容易被忽略、可能存在丢数据风险的情况:
在MySQL中,无论是复制还是备份恢复,依赖的都是全量备份和binlog:
这种基于“快照 + 操作日志”的方法,不是 MySQL 特有的。比如说,redis cluster中,它的全量备份称为snapshot,操作日志叫做backlog,它的主从复制方式几乎和MySQL是一模一样的。
几乎所有的存储系统和数据库,都是用这一套方法来解决备份恢复和数据复制问题的。这一套方法其实是有理论基础的,叫做复制状态机 (Replication State Machine)
也就是说,任何一个存储系统,无论它存储的是什么数据,用什么样的数据结构,都可以抽象成一个状态机。
复制数据的时候,只要基于一个快照,按照顺序执行快照之后的所有操作日志,就可以得到一个完全一样的状态。在从节点持续的从主节点上复制操作日志并执行,就可以让从节点上的状态数据和主节点保持同步。
主从同步做数据复制时,一般可以采用几种复制策略。性能最好的是异步复制,主节点上先记录操作日志,再更新状态数据,然后异步把操作日志复制到所有从节点上,并在从节点执行操作日志,得到和主节点相同的状态数据。
异步复制的缺点是可能存在主从延迟,如果主节点宕机,可能会丢数据。另外一种常用的策略是半同步复制,主节点等到操作日志最少成功复制到N个从节点之后,再更新状态,这种方式再性能、高可用和数据可靠性几个方面都比较平衡,很多分布式存储系统默认使用这种方式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。