Files
rikako-note/mysql/mysql集群/Mysql Group Replication.md
2025-10-17 11:32:48 +08:00

184 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [Mysql Group Replication](#mysql-group-replication)
- [Group Replication Background](#group-replication-background)
- [Replication Technologies](#replication-technologies)
- [group replication](#group-replication)
- [Group replication Use Cases](#group-replication-use-cases)
- [Exmaple Use Cases](#exmaple-use-cases)
- [Multi-primary and Single-Primary Modes](#multi-primary-and-single-primary-modes)
- [Single-Primary Mode](#single-primary-mode)
- [group\_replication\_enforce\_update\_everywhere\_checks](#group_replication_enforce_update_everywhere_checks)
- [group\_replication\_consistency](#group_replication_consistency)
- [Primary Election Algorithm](#primary-election-algorithm)
- [Finding the Primary](#finding-the-primary)
- [Multi-Primary Mode](#multi-primary-mode)
# Mysql Group Replication
`Mysql Group Replication`可以用于创建弹性、高可用、有容错的replication拓扑。
groups可以在single-primary mode下进行执行其支持自动的primary选举在同一时刻只有一个server接收更新操作。
另外groups也支持multi-primary mode部署此时所有servers都能够接收写操作即使多个写请求是并行发送的。
MGR存在一个内置的group membership service其在任一时刻都能为所有servers提供一致且可用的组视图。server可以加入和离开groupgroup view也会随之改变。在某些时刻server可能非预期的离开group在这种情况下failure detection机制将会自动感知并通知group去更新group view。
group replication是作为mysql server的插件被提供的。可以通过Innodb Cluster来部署`mysql server instances group`
> 为了部署多个mysql实例可以使用Innodb Cluster其能够通过Mysql Shell轻松的管理mysql server实例组。Innodb Cluster和Mysql Router无缝集成在应用连接到集群式无需在应用中编写failover流程。
## Group Replication Background
创建有容错性系统的最常用方式是`采用冗余组件的方案`,即使组件被移除,系统仍可按预期继续运行。这样将会增加系统的复杂性,特别的,`replicated databases`必须维护和管理多台server并且servers以集群的方式对外提供服务还需要处理其他若干的经典分布式系统问题如network partition或split brain问题。
mysql group replication提供了distributed state machine replication并保证了servers间的强协同server在作为同一group的一部分会自动的彼此之间进行协调。
对于待提交的事务majority of group必须就`事务在global transactions中的顺序`达成一致。决定事务commit或abort是由每个server单独处理的但是所有server中该事务提交/回滚状态都完全一致。如果存在network partition导致members不能就transaction order达成一致那么系统将不能继续处理直至该问题被解决。故而MGR中存在内置、自动的split-brain保护机制。
上述所有内容都由`GCS`Group Communication System协议提供其提供了如下内容
- 故障检测机制
- group membership service
- safe and completely ordered message delivery
上述所有机制都保证了数据在group of servers之间能够被一致的复制。GCS技术的核心基于`Paxos`算法实现其用作group communication engine。
### Replication Technologies
传统的mysql replication提供了一种简单的`source to replica`的复制方法:
- source为primary实例
- replica为secondaries实例
source将会应用事务并对事务进行提交。之后事务会异步的被发送到replicas接收到事务的replica会对事务进行重新执行statement-based replicaion或被应用row-based replication。在默认情况下所有的server都拥有数据的完整副本。
默认情况下mysql的异步replication示例图如下
<img src="https://dev.mysql.com/doc/refman/8.4/en/images/async-replication-diagram.png" style="width: 100%; max-width: 725px;">
除此之外还存在半同步的replication其在协议中添加了同步步骤。示例如下所示primary会等待replicas接收到事务并向primary返回ack在接收到ack后才会执行commit操作。
<img src="https://dev.mysql.com/doc/refman/8.4/en/images/semisync-replication-diagram.png" style="width: 100%; max-width: 725px;">
上面两张图为传统的asynchronous MYSQL replication protocol。
### group replication
group replication是一种用于实现fault-tolerant系统的技术。replication group是一系列servers的集合其中每个server都含有数据的完整副本servers之间通过message进行交互。
group中的communication layer提供了一系列保证例如atomic message和total order message delivery。
Mysql Group Replication基于这些特性、抽象实现了`multi-source update everywhere replication protocol`。一个replication group由多个server组成每个server在每时每刻都独立的执行事务。
- read/write事务都只在其被group同意之后才提交即对于read/write事务都要由整个group决定其是否能被提交故而提交操作并不是由源服务器单方面决定的。read/write transaction代表事务中包含写操作的事务
- read-only事务则是不需要group内其他server的协助立刻就能提交
`read/write`事务准备好在源server上提交时都会原子性的广播`write values``write set`
- write values代表被修改后的整行数据
- write set被修改数据的唯一标识符
由于transaction是被原子广播的故而要么`group中所有servers都接收到该事务`,要么`group中所有servers都未收到该事务`。并且,`对于所有servers其接收到的所有事务都相同并且所有事务按照相同的顺序被接收`,并且,会为所有事务建立一个`global total order`
但是事务在不同的servers上并行执行时可能会发生冲突。在被称为`certification`的过程中该冲突通过查看和比较两个不同并行事务的write sets来检测。在certification的过程中冲突检测在行级别执行如果两个并行的事务在不同的servers上执行并且修改了相同的行那么这将会存在冲突。
该冲突将会按照如下方案被解决对于在global total order中排序靠前的事务其将会在所有server上被提交而排序靠后的事务则是会终止在源服务器上被提交并且被group中的其他servers丢弃。
例如t1和t2在不同的servers上并发执行两者都修改了同一行t2的排序在t1之前那么在冲突中t2将会获胜而t1会回滚。上述规则则是分布式的`first commit wins rule`
> 如果两个事务发生冲突的可能性高于不冲突的可能性那么最好让其在相同的server上执行并且通过server的local lock机制来对事务进行同步而不是在不同的server上执行并因certification造成回滚。
对于已经被认证的事务进行`applying``externalizing`group replicaion允许server`在不破坏一致性和有效性的前提下`偏离`agreed order of the transactions``group replication`是一个最终一致性的系统代表incoming traffic降低或停止时所有的group members都将包含相同的data content。当traffic较高时事务可以以稍微不同的顺序进行externalizing并且事务在进行externalizing时在一些servers进行externalizing的时机也可能早于其他servers。`externalizing`指的即是实际提交事务并使事务的修改对client可见`applying`指的是server应用来自其他server的事务修改
例如在mulit-primary模式下一个本地事务可能在certification之后立马就被externalized即使一个来自remote server的transaction在global order中顺序更靠前并且尚未被applied。当certification过程中多个transactions间不涉及冲突时该操作是被允许的。
在single-primary模式下在primary server上可能小概率会发生`并发、非冲突的本地事务按照和global order agreed by group replication的顺序进行提交和externalized`
在不接受来自客户端写入操作的secondaries节点上事务总是按照agreed order被提交和externalized。
具体mysql group replication protocol的示意图如下所示
<img src="https://dev.mysql.com/doc/refman/8.4/en/images/gr-replication-diagram.png" style="width: 100%; max-width: 725px;">
### Group replication Use Cases
Group Replication通过将系统状态复制到一组servers能够创建一个有冗余性的容错系统。即使部分服务器随后fail只要不是所有或majority发生故障那么系统仍然可访问。
取决于group中故障server的数量不同group可能出现性能下降或可拓展性降低的情况但是整个系统仍然是可用的。server的故障是隔离和独立的故障由group membership service来进行追踪其基于分布式的failure detector该detector能够在任何server自愿退出或异常退出group时发送信号。
在该系统中无需进行server failover`multi-source update everywhere`的特性确保在单台server故障的场景下update操作的执行仍然不会受阻。总而言之mysql group replication保证了数据库服务是持续可用的。
需要认识到的是即使数据库服务整体是可用的当server非预期的退出时连接到该故障server的clients仍然需要被重定向或故障转移到其他server。该处理流程不应由group replication来处理而是应该由connector/load balancer/router/其他中间件来处理。
总之mysql group replication提供了一个高可用、高弹性、可靠的mysql服务。
#### Exmaple Use Cases
如下示例为group replication的典型用例场景
- `Elastic Replication`: 适用于高灵活度复制结构的环境servers的数量需要可以动态的增加或缩减并尽可能的减少副作用
- `Highly Available Shards`: sharding是一种实现`write scale-out`的流行方案可以使用mysql group replication来实现高可用shards其中每个shard都被映射到一个replication group
- `async source-replica replication的替代方案`: 在某些场景下使用单个source server可能会造成单点争用向整个group写入在特定场景下则更具有可拓展性MGR支持多主模式部署能够在group范围内缓解写压力
### Multi-primary and Single-Primary Modes
Group Replication可以在single-primary或multi-primary模式上工作。该group mode为一个group范围内的配置设置通过system variable `group_replication_single_primary_mode`来指定在所有group members中该variable必须都相同。
- `ON`: 该值代表single-primary mode也为变量的默认值
- `OFF`: 该值代表multi-primary mode
> 在group中所有的members其`group_replication_single_primary_mode`变量的值都必须相同
在group replication运行时并无法手动修改`group_replication_single_primary_mode`的值但是在group replication运行时可以使用`group_replication_switch_to_single_primary_mode()``group_replication_switch_to_multi_primary_mode()`方法来将group从一个模式切换到另一个模式。这些方法能够修改group的mode并且确保数据的一致性和安全性。
不管处于哪种mode下group replciation都不会处理client的failover其必须由中间件framework例如`Mysql Router`/`proxy`/`connector`/`应用本身`来处理。
#### Single-Primary Mode
在single-primary modegroup_replication_single_primary_mode=ONgroup中只存在一个`primary server`被设置为read/write mode。group中所有其他的members都被设置为read-only modesuper_read_only=ON。该primary server通常会引导整个集群的启动所有其他加入到group中的servers都会识别到primary server并且自动被设置为read-only mode.
在single-primary mode时group replication会强制只有一个server能够向group中写入相比于multi-primary modesingle-primary mode的数据一致性检查可以不那么严格DDL statements也无需额外谨慎的处理。
##### group_replication_enforce_update_everywhere_checks
`group_replication_enforce_update_everywhere_checks`选项能够启用/禁用`对group的严格一致性检查`。当在single-primary mode下部署时或将group的mode修改为single-primary mode时该system variable的值必须被设置为`OFF`
被指定为primary server的member可以按如下方式进行变更
- 如果该primary正常/非预期退出group那么新primary的选举将会自动被触发
- 可以通过`group_replication_set_as_primary()`方法将指定的member任命为primary
- 如果使用`group_replication_switch_to_single_primary_mode()`方法将group从multi-primary mode切换为single-primary mode那么将会自动选举出一个新的primary或者可以通过方法指定primary
当new primary server被选举出后自动或手动岂会被自动设置为read/write状态并且其他的group members将会变为`secondaries`,状态变为`read-only`,具体流程如下图所示:
<img src="https://dev.mysql.com/doc/refman/8.4/en/images/single-primary-election.png" style="width: 100%; max-width: 899px;">
当新primary被选中时可能会存在部分变更的积压这些变更已经在old primary中被应用但是还没有被应用到new primary中。在这种情况下直到new primary追上old primary之前read/write transaction可能造成冲突并被回滚而read-only transaction则可能会读取过时的数据。
通过group replication flow control mechanism将会将fast member和slow member的差异最小化在该机制被激活并经合理调优的情况下可以有效降低该上述情况的发生概率。
##### group_replication_consistency
可以通过该system variable来设置group的事务一致性级别从而解决上述问题。
- `BEFORE_ON_PRIMARY_FAILOVER`: 该值为默认值
- 将该变量设置为`BEFORE_ON_PRIMARY_FAILOVER`或更高级别时新选举出的primary将会暂时持有新事务直到primary完成积压changes的applying
##### Primary Election Algorithm
自动的primary member选举过程涉及每个member每个member都会查看group的new view对潜在的new primary members进行排序并且选择最合适的member。在每个member的决策过程中都会独立的在本地进行决策决策遵循mysql server的primary election algorithm。
> 由于所有的members都必须就决策达成一致如果其他group member运行的mysql server版本较低时members会调整其primary election algorithm令其行为和group内最低版本的mysql server保持一致。
在members选举primary时会考虑如下因素考虑顺序如下
- 首先考虑的因素为`哪个member运行最低的mysql server version`所有group members都会首先按照mysql server version进行排序
- 如果存在多个members都运行最低的mysql server version那么第二个考虑的因素为members中每个member的member weightmember weight由`group_replication_member_weight`进行指定
- `group_replication_member_weight` system variable通过一个范围为`0-100`的数字进行指定所有members的weight默认为50该值设置越小排序越靠后值设置越大排序越靠前
- 通过weighting function可以令硬件更好的member优先级更高或在primary计划维护时转移至特定的节点
- 如果存在多个members运行相同的mysql server version并且多个members都拥有最高的member weight那么考虑的第三个因素则是每个member UUID的字典序UUID通过`server_uuid` system variable来指定。拥有最小server UUID的member将会被选中为primary
##### Finding the Primary
在部署在single-primary mode下时如果要找出哪个server为当前的primary可以通过`performance_schema.replication_group_members`表中的`MEMBER_ROLE`来进行判断,示例如下:
```sql
mysql> SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;
+-------------------------+-------------+
| MEMBER_HOST | MEMBER_ROLE |
+-------------------------+-------------+
| remote1.example.com | PRIMARY |
| remote2.example.com | SECONDARY |
| remote3.example.com | SECONDARY |
+-------------------------+-------------+
```
#### Multi-Primary Mode
在multi-primary modegroup_replication_single_primary_mode=OFF没有member拥有特殊的role。任何member在加入group时都被设置为read/write模式即使在并发情况下也能执行write transaction。
如果一个member停止接收write transactions例如发生非预期的server exit连接到member的clients将会被重定向或failover到其他的任一处于read/write模式的member。group replciation本身并不会处理client-side failover可以使用中间件来处理例如mysql router。
<img src="https://dev.mysql.com/doc/refman/8.4/en/images/multi-primary.png" style="width: 100%; max-width: 899px;">
group replication是一个最终一致性的系统其代表当incoming traffic降低或停止时所有group members都会包含相同的数据内容。当traffic流动时某些members对transactions进行externalized的时机可能位于另一些members之前。尤其是某些member的写吞吐可能低于其他member导致连接到该member的client可能读取到过时数据。
在multi-primary mode下较慢的member也可能会积累过多的待认证事务和待applying的事务导致冲突和认证失败的风险更高。为了限制该问题可以采用group replication的flow control mechansim机制来最小化fast member和slow member的差异。
如果想要为group中的每个事务提供一致性保证可以使用`group_replication_consistency`系统变量实现。可以根据group中工作负载和数据读写的优先级来选择合适的设置同时应考虑提升一致性所引入的同步操作对性能带来的影响。可以针对独立的session来设置该系统变量从而保护对并发性敏感的事务。