相似

  • 都是为了高可用以及高扩展而存在的模式。

共识算法Paxos

  • 分布式系统领域经典的共识算法有很多,如Raft和paxos,这一次我们先详细了解Paxox

Paoxs解决的问题

  • Paxos主要解决在一个由多个节点(或服务器)组成的分布式系统中,如何确保这些节点在面对网络延迟、节点故障或分区等不确定性情况下,能够对某一个值达成一致。

Paxos基本原理

  • Paxos算法分为基本Paxos和多Paxos两种变体。
基本Paxos
  • 提议者 (Proposer) 发起提案,提出一个编号和值,希望获得多数接受者的同意。
  • 接受者 (Acceptor) 对提案进行投票,并根据之前已经接受的提案决定是否同意新的提案。
  • 学习者 (Learner) 观察已经被多数接受者接受的提案,最终学习到共识值
基本Paxos阶段

Prepare 阶段:
提议者选择一个提案编号 n,向所有接受者发送 Prepare(n) 请求。
每个接受者在收到 Prepare(n) 请求后,如果 n 大于其之前响应过的所有提案编号,则承诺不再接受编号小于 n 的提案,并返回其已经接受的提案及其编号。

Accept 阶段:
提议者在收到多数接受者的响应后,选择最高编号的提案值(如果有),并发送 Accept(n, v) 请求,其中 v 是被选择的提案值或提议者自己的新值。
接受者在收到 Accept(n, v) 请求后,如果尚未承诺接受比 n 更大的编号,则接受该提

Multi-Paxos

多Paxos是Paxos协议的一个扩展和优化,用于在分布式系统中处理多个值的共识问题。它通过将多个共识实例串联在一起,提高了效率,使得在一组节点中可以连续不断地达成多个值的共识。

  • 在多Paxos中,提议者通常是固定的,这个固定的提议者称为领导(Leader)。领导者负责发起提案,并在一段时间内主导多个共识实例。

  • 多Paxos的每一个提案编号 n 对应于一个特定的共识实例。这样,领导者只需要在初次选举时进行Prepare阶段的操作,后续的提案就可以直接进入Accept阶段,大幅减少了通信轮次。

具体优化
  • 领导者选举:在多Paxos中,系统首先通过Paxos协议选出一个领导者。领导者负责在它的任期内发起多个提案。在每个共识实例中,领导者只需进行Accept阶段操作。
  • 省略Prepare阶段:一旦领导者被选定且多数接受者同意,它可以直接在每个共识实例中发起
  • Accept请求,而无需每次都从Prepare阶段开始。管道化:多Paxos可以支持管道化操作,即允许多个提案同时进行,以提高吞吐量。

MySQL Group Replication

原理

  • 多主架构: MGR是一个多主复制解决方案,允许多个节点同时接收和处理写操作。每个节点都可以处理读写请求,这样系统可以实现高可用性和负载均衡。

  • 一致性协议: MGR使用Paxos或Raft等一致性协议来确保多个节点之间的数据一致性。每次事务提交时,都会在组内传播,并通过一致性协议来决定事务是否提交成功。

  • 自动故障转移: 如果一个节点出现故障,MGR可以自动检测并将其从组中移除,同时其他节点继续提供服务。系统可以自动将新节点加入到复制组中,实现自动化管理。

  • 读写分离: 由于每个节点都可以接受写操作,因此在实现高可用性的同时,也具备一定的扩展能力。不过,通常建议设置部分节点为读专用,以分散负载。

流程架构

img

  1. Execute (执行)
    Master 1: 开始执行某个事务。这个操作是在本地节点上执行的,但尚未传播到其他节点。
  2. Certify (认证)
    所有参与共识的节点(Master 1、Master 2、Master 3)都会对事务进行认证。认证的目的是确保当前事务不会与其他事务产生冲突。这一步是基于全局事务顺序(GTS)来实现的。
    Master 1: 在本地节点上执行完事务后,会将其传递给其他节点进行认证。其他节点在收到这个事务后也会进行认证。
  3. Relay Log (中继日志)
    Master 2 和 Master 3: 在认证通过后,将事务记录到中继日志中。这一步是为了确保即使发生故障,也能够在恢复时继续执行未完成的事务。
  4. Apply (应用)
    Master 2 和 Master 3: 将中继日志中的事务应用到本地数据库中。这个步骤是将接收到的事务内容真正写入到数据库,从而保持与其他节点的数据一致性。
  5. Binlog (二进制日志)
    所有的 Master 节点在成功应用事务后,会将事务记录到二进制日志中(Binlog)。二进制日志记录了所有数据更改,通常用于数据恢复、复制等场景。
  6. Commit (提交)
    最后,所有 Master 节点都会将事务提交,正式结束这次事务处理。事务在所有节点上达成一致后,才会进行最终提交,这样可以确保整个集群的一致性。

使用限制

  1. 事务一致性
    MySQL MGR 强制要求使用 InnoDB 存储引擎,因为它支持事务和行级锁。
    不支持非事务性存储引擎(如 MyISAM),使用这些引擎的表不会被复制,从而导致数据不一致。
  2. 全局事务标识符(GTID)
    MySQL MGR 依赖 GTID 进行复制,因此在配置时必须启用 GTID(gtid_mode=ON)。
    不能在同一个实例上同时使用 MGR 和传统的基于二进制日志的复制。
  3. 表的主键
    表中必须有主键或唯一索引,MGR 依赖这些来确保数据一致性和避免冲突。
    没有主键的表可能导致冲突检测机制失效,进而造成数据不一致。
  4. 写入冲突
    多主模式下,多个节点可以同时写入数据,可能会产生写入冲突。MGR 通过冲突检测机制解决这些冲突,但在高并发情况下,可能影响性能或导致事务回滚。
  5. 网络延迟和分区
    MGR 对网络延迟敏感,延迟较高时可能会影响复制的性能。
    在网络分区的情况下,MGR 可能会分裂为多个子组,这可能会导致服务不可用或数据不一致。
  6. 兼容性限制
    MGR 不支持部分 MySQL 特性,例如:
    不支持外部锁(例如 LOCK TABLES 和 FLUSH TABLES WITH READ LOCK)。
    不支持临时表的跨节点复制。
    不支持在不同模式下(READ_WRITE, READ_ONLY, OFF)进行组内成员角色的动态切换。
  7. 资源消耗
    由于 MGR 需要维护组内成员的一致性,尤其在多主模式下,资源消耗(如 CPU 和内存)比传统主从复制要高。
    在大数据量高并发写入的场景下,可能会影响性能,必须注意容量规划。

MySQL Master-Slave

原理:

  1. 单主多从架构: 在Master-Slave模式中,一个数据库作为主库(Master),其他数据库作为从库(Slave)。所有写操作都由主库处理,而从库只接收来自主库的复制日志进行更新。
  2. 异步复制: 通常情况下,从库以异步方式从主库获取更新。主库完成写操作后,立即返回给客户端,从库稍后复制这些更新。这种模式下,从库的数据可能会有短暂的延迟。异步复制是mysql默认的复制方式,主库写入binlog即可成功后返回给客户端,不等待binlog日志传递的过程,如果主库宕机,就有可能会出现丢失数据的情况。
  3. 半同步复制:加了数据的安全性。因为主库在提交事务前确保至少一个从库已经接收并应用了该事务,从而降低了主库故障时数据丢失的风险。坏处也有由于主库在提交事务之前需要等待从库的 ACK,增加了事务的等待时间,这可能会对性能产生一定影响。如果从库的响应速度较慢,或者网络延迟较大,都会导致主库提交事务的时间延长。
  4. 手动故障切换: 当主库故障时,需要手动将其中一个从库提升为主库,并重新配置其他从库指向新的主库。这通常需要借助外部工具或手动操作来完成。
  5. 读写分离: 通过配置读写分离,客户端可以将读请求发送到从库,而写请求发送到主库,从而减轻主库的负载。

流程架构之异步复制

image-20240812102902244

Master 端的操作

Binlog(Binary Log):
主服务器(Master)在处理写操作(如 INSERT、UPDATE、DELETE 等)时,会将这些操作记录在二进制日志(Binlog)中。二进制日志是一个顺序写入的文件,记录了所有对数据库进行更改的 SQL 语句,这些语句将用于在从服务器上重放。

Dump:
在主服务器上,Dump 线程负责从 Binlog 中读取这些变化,并将其发送给请求同步数据的从服务器(Slave)。这个线程会持续运行

Slave 端的操作

IO Thread(IO 线程):
从服务器上有一个 IO 线程,它向主服务器发送请求,要求主服务器发送新的 Binlog 数据。IO 线程接收到主服务器发送的二进制日志更新后,会将其写入到本地的中继日志(Relay Log)中。

Relay Log(中继日志):
中继日志是从服务器上的一个临时存储区域,用于保存从主服务器接收到的二进制日志数据。这个日志可以被视为主服务器 Binlog 的本地副本。

SQL Thread(SQL 线程):
从服务器上的 SQL 线程负责从中继日志中读取 SQL 语句并在从服务器上执行这些语句。这些 SQL 语句是从主服务器同步过来的,执行这些语句的目的是让从服务器的数据库状态与主服务器保持一致。

流程架构之半同步复制

image-20240812103919203

MySQL 半同步复制工作原理

1. **主库执行事务 (Execute)**:

  • 当主库(Master)接收到一个写操作时,首先会在主库上执行这个事务。此时,事务被记录在主库的二进制日志(Binlog)中。

2. **生成 Binlog 并发送给从库 (Binlog)**:

  • 主库在执行事务后,会将该事务生成的二进制日志(Binlog)发送给所有配置了半同步复制的从库(Slave)。

3. **从库接收并写入中继日志 (Relay Log)**:

  • 从库接收到主库发送的 Binlog 后,将其写入到中继日志(Relay Log)中。

4. **从库应用日志 (Apply)**:

  • 从库将中继日志中的内容应用到本地数据库,完成对数据的更新。

5. 从库返回 ACK

  • 在从库成功应用完日志后,会发送一个确认信号(ACK)给主库。这个步骤确保了主库知道至少有一个从库已经成功应用了该事务。

6. **主库提交事务 (Commit)**:

  • 主库在收到至少一个从库的 ACK 后,才会正式提交该事务。这就是“半同步”复制的关键点:主库确保至少有一个从库成功接收并应用了事务后,才认为事务提交成功。

7. 主库继续处理其他事务

  • 在事务提交之后,主库可以继续处理后续的事务操作。