首页 » MySQL » MySQL Group Replication介绍

MySQL Group Replication介绍

 

2016-12-12,一个重要的日子,mysql5.7.17 GA版发布,正式推出Group Replication(组复制) 插件,通过这个插件增强了MySQL原有的高可用方案(原有的Replication方案),提供了重要的特性——多写,保证组内高可用,确保数据最终一致性

1. 背景

在介绍组复制之前,我们先简单介绍传统的异步复制和半同步复制:

1.1 传统复制

传统mysql复制是完全异步化的复制。下图描述了传统复制的原理:

async_replication_diagram

master事务的提交不需要经过slave relay的响应,relay log总是异步地发送到slave上去执行。由于master的提交不需要确保slave relay log是否被正确接受,当slave relay log接受失败,master无法感知,此时如果master发生切换,就会出现数据不一致!另外,在高并发的情况下,传统的主从复制,从节点可能会与主产生较大的延迟。

1.2 半同步复制

半同步复制是传统复制的变种,在master事务的commit之前,必须确保一个slave收到relay log并且响应给master以后,才能进行事务的commit。

semisync_replication_diagram

因为slave接受relay log之后有可能apply失败。这个时候master其实不知道slave的失败,照常提交了这个事务。并且,半同步复制只确保一个slave能够收到relay log,多slave的场景下,不能保证其他节点正确收到relay log,由此,当发生master切换后,半同步复制一样也会出现数据不一致的情况。

1.3 组复制

gr_replication_diagram

引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。

一个replication group由若干个节点(数据库实例)组成,组内各个节点维护各自的数据副本(Share Nothing),通过一致性协议实现原子消息和全局有序消息,来实现组内实例数据的一致。

2. 组复制介绍

2.1 数据一致性保证

对于只读(RO)事务,组间实例无需进行通讯,就可以处理事务;对于读写(RW)事务,组内所有节点必须经过通讯,共同决定事务提交与否。

引用mysql官方博客对于读写事务提交过程的描述,解释了如何保证了组内节点间数据的一致性的(难以翻译- -。):

To be precise, when a transaction is ready to commit at the originating server, the server will atomically broadcasts the write values (rows changed) and the correspondent write set (unique identifiers of the rows that were updated). Then a global total order will be established for that transaction. Ultimately, this means that all servers receive the same set of transactions in the same order. As a consequence, all servers apply the same set of changes in the same order, therefore they remain consistent within the group.

2.2 事务冲突处理

在高并发的多写模式下,节点间事务的提交可能会产生冲突,比如,两个不同的事务在两个节点上操作了同一行数据,这个时候就会产生冲突。首先,Group Replication(GR)能够识别到这个冲突,然后对此的处理是,依赖事务提交的时间先后顺序,先发起提交的节点能够正确提交,而后面的提交,会失败。

2.3 故障检测

GR自带故障检测机制,可以识别组内成员是否挂掉(组内节点心跳检测)。当一个节点失效,将由其他节点决定是否将这个失效的节点从group里面剔除。

2.4 组成员管理

GR需要维护组内节点的状态(在线?存活?挂掉?),对于失效的节点,由其他节点决定是否剔除。对于新加入的节点,需要维护它的视图与其他节点的视图保持一致。

2.5 容错能力

GR基于分布式一致性算法实现,一个组允许部分节点挂掉,只要保证大多数节点仍然存活并且之间的通讯是没有问题的,那么这个组对外仍然能够提供服务。

假设一个GR由2n + 1个节点,那么允许n个节点失效,这个GR仍然能够对外提供服务。比如有3个节点组成的一个GR,可允许1个节点失效,这个GR仍然能够提供服务。

Group Size Majority Instant Failures Tolerated
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2
6 4 2
7 4 3

GR一般由奇数个节点组成为佳。

2.6 两种模式

GR提供了single-primary和multi-primary两种模式。single-primary mode 组内只有一个节点负责写入,读可以从任意一个节点读取,组内数据保持最终一致;而multi-primary mode 为多写,即写会下发到组内所有节点,组内所有节点同时可读,也是能够保证组内数据最终一致性。一个GR的所有节点必须配置使用同一种模式,不可混用。

2.6.1 Single-Primary Mode

这个模式下,group内只有一台节点可写可读,其他节点只可以读。对于group的部署,需要先跑起primary节点(即那个可写可读的节点,read_only = 0)然后再跑起其他的节点,并把这些节点一一加进group。其他的节点就会自动同步primary节点上面的变化,然后将自己设置为只读模式(read_only = 1)。

当primary节点意外宕机或者下线,在满足大多数节点存活的情况下,group内部发起选举,选出下一个可用的读节点,提升为primary节点。

primary选举根据group内剩下存活节点的UUID按字典序升序来选择,即剩余存活的节点按UUID字典序排列,然后选择排在最前的节点作为新的primary节点。

引用 MySQL 5.7 Reference Manual :

Upon primary member failure, an automatic leader election mechanism chooses the next primary member. The next primary is selected by ordering the remaining servers lexicographically (using their UUID) and picking the first member in the list.

single-primary-election

【特别重要】 在切换primary期间,mysql group不会处理应用重连接到新的主,这需要应用层自己或者由另外的中间件层(proxy or router)去保证。

如何查看group内哪个节点是作为primary节点,官方提供了一个方法:

mysql> SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member';
+--------------------------------------+
| VARIABLE_VALUE                       |
+--------------------------------------+
| 69e1a3b8-8397-11e6-8e67-bf68cbc061a4 |
+--------------------------------------+
1 row in set (0,00 sec)

得到的是实例节点的UUID。利用上面的SQL,加上performance_schema里的replication_group_members表,可以查出更细节的信息,包括hostname,port等,sql语句如下所示:

SELECT * 
FROM performance_schema.replication_group_members 
WHERE MEMBER_ID = (
  SELECT VARIABLE_VALUE
  FROM performance_schema.global_status
  WHERE VARIABLE_NAME= 'group_replication_primary_member'
);

另外,还可以通过以下SQL来直接判断当前节点是否为主节点,得到1表示主节点,0表示不是主节点:

mysql> SELECT IF((SELECT @@server_uuid) = (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'), 1, 0) as is_primary_node;
+-----------------+
| is_primary_node |
+-----------------+
|               1 |
+-----------------+
1 row in set (0.00 sec)

最后发现一个便捷的方式,可以通过直接查看read_only变量来判断节点是否为主节点:

mysql> select @@read_only;
+-------------+
| @@read_only |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

2.6.2 Multi-Primary Mode

多主模式,即多写,没有选择新primary的概念(无需进行选举),group内的所有机器都是primary节点,同时可以进行读写操作,并且数据是最终一致的。但是,这个模式下仍然存在一些使用限制,限制请看2.7.2小节介绍。

multi-primary

2.7 Requirements&Limitations

2.7.1 Requirements

部署GR有以下需求:

1) 架构

  • 存储引擎必须为innodb
  • 每个表必须提供主键
  • 只支持ipv4,网络带宽要好
  • 一个group最多只能有9个节点

2) 配置上

针对my.cnf,需要指定如下配置:


# Binary Log must be active.
log-bin[=log_file_name]

# Binary Log Format must be set to ROW.
binlog-format=row

# Global Transaction Identifiers must be turned on.
gtid-mode=ON

# Replication applier needs to have replication metadata repositories stored in system tables.
master-info-repository=TABLE
relay-log-info-repository=TABLE

# Transaction write set extraction must be enabled.
transaction-write-set-extraction=XXHASH64

# Servers need to log binary logs that are applied through the replication applier.
log-slave-updates

# Replication event checksums are not supported.
binlog-checksum=NONE

2.7.2 Limitations

以下是使用GR的限制:

  • 不支持Replication event checksums,需要在my.cnf里面配置,在上节已经提及
  • 不支持Savepoints
  • multi-primary mode部署方式不支持SERIALIZABLE事务隔离级别
  • multi-primary mode部署方式不能完全支持级联外键约束
  • multi-primary mode部署方式不支持在不同节点上对同一个数据库对象并发执行DDL(在不同节点上对同一行并发进行RW事务,后发起的事务会失败)

转自:http://blog.csdn.net/d6619309/article/details/53691352

官网介绍网址:https://dev.mysql.com/doc/refman/5.7/en/group-replication.html

原文链接:MySQL Group Replication介绍,转载请注明来源!

0