淘宝店铺怎么上传自己做的网站,升级wordpress 错误:连接服务器时出错_请检查设置.,定制衣服的app叫什么,网站数据报表开源生态
众所周知#xff0c;MySQL主备库#xff08;两节点#xff09;一般通过异步复制、半同步复制#xff08;Semi-Sync#xff09;来实现数据高可用#xff0c;但主备架构在机房网络故障、主机hang住等异常场景下#xff0c;HA切换后大概率就会出现数据不一致的问…开源生态
众所周知MySQL主备库两节点一般通过异步复制、半同步复制Semi-Sync来实现数据高可用但主备架构在机房网络故障、主机hang住等异常场景下HA切换后大概率就会出现数据不一致的问题简称RPO!0因此但凡业务数据有一定的重要性都不应该选择MySQL主备架构两节点的数据库产品推荐选择RPO0的多副本架构。
MySQL社区对于RPO0的多副本技术演进
MySQL官方开源推出了基于组复制的MySQL Group ReplicationMGR高可用解决方案内部通过XCOM封装了 Paxos 协议提供了数据一致性的保障。阿里云 PolarDB-X来源于阿里电商双十一、异地多活的业务打磨和验证在2021年10月份进行了全内核开源全面拥抱MySQL开源生态。PolarDB-X 定位为一款集中分布式一体化数据库其数据节点Data NodeDN采用了自研的X-Paxos协议高度兼容MySQL 5.7/8.0不仅提供了金融级高可用能力还同时具备高扩展的事务引擎、灵活的运维容灾、低成本的数据存储的特点参考《PolarDB-X 开源 | 基于Paxos的MySQL三副本》。 PolarDB-X集中分布式一体化的理念数据节点DN可以被独立出来作为集中式标准版形态完全兼容单机数据库形态。当业务增长到需要分布式扩展的时候架构原地升级成分布式形态分布式组件无缝对接到原有的数据节点不需要数据迁移也不需要应用侧做改造即可享受分布式带来的可用性与扩展性架构说明《集中分布式一体化》 MySQL的MGR和PolarDB-X的标准版DN两者从最底层的原理上都采用了Paxos协议那么在实际使用上具体的表现和差异如何呢本文从架构对比、关键差异、测试对比方面进行分别详细阐述。
MGR/DN简称说明MGR代表MySQL MGR的技术形态、DN代表PolarDB-X 单DN集中式标准版的技术形态。
TL;DR
详细对比分析比较长可以先看一下总结和结论有兴趣的话可以顺着总结在后续文章中找一下线索。
MySQL MGR一般的业务和公司都不建议使用因为需要有专业的技术知识和运维团队才有机会用好本文也复现了MySQL MGR三个业界流传已久的暗坑
暗坑1MySQL MGRXCOM协议走了全内存模式默认是不满足RPO0的数据一致性保证本文后续有testcase复现丢数的问题需要显示配置一个参数才可以保证目前MGR的设计上性能和RPO无法兼得暗坑2MySQL MGR在有网络延迟下性能比较拉胯文章中测试了4钟网络场景的对比包括同城3机房、两地三中心性能参数配置下跨城只有同城的1/5如果再开启RPO0的数据保证性能更没法看。因此MySQL MGR更适合用在同机房场景跨机房容灾不适合暗坑3MySQL MGR的多副本架构备节点的故障都会让主节点Leader出现流量跌0不太符合常理。文章中重点尝试开启MGR的单Leader模式对标MySQL以前的主备副本架构模拟备副本的宕机和恢复的两个动作备节点的运维操作也会让主节点Leader出现流量跌0持续10来秒整体的可运维性比较差。因此MySQL MGR在主机运维上要求比较高需要专业的DBA团队 PolarDB-X Paxos相比于MySQL MGR在数据一致性、跨机房容灾、节点运维上都没有MGR类似的坑但也有个别小缺点、以及容灾上的优点
简单的同机房场景下小并发下的只读性能、高并发下的纯写性能比MySQL MGR略低5%左右同时多副本的网络发送性能上有进一步的优化空间优点100%兼容MySQL 5.7/8.0的特性同时在多副本的备库复制、故障切换路径上做了比较多的精简优化高可用切换RTO8秒业界常见的4钟容灾场景都表现不错可以替换semi-sync半同步、MGR等
1. 架构对比
名词解释
MGR/DN简称说明
MGRMySQL MGR的技术形态后续内容简称MGRDN阿里云PolarDB-X 集中式标准版的技术形态其中分布式下的数据节点DN可以被独立出来作为集中式标准版形态完全兼容单机数据库后续内容简称DN
MGR MGR 支持单主、多主模式完全复用 MySQL 的复制系统包括 Event、Binlog Relaylog 、Apply、Binlog Apply Recovery、GTID。与DN的关键区别在于 MGR 事务日志多数派达成一致的切入点在主库事务提交之前。
Leader 事务提交前调用before_commit钩子函数group_replication_trans_before_commit进入 MGR 的多数派复制MGR 借助 Paxos 协议将 THD 上缓存的 Binlog Events 同步所有在线节点MGR 收到多数派应答后确定可以提交事务THD 进入事务组提交流程 开始写本地 Binlog更新Redo回复客户端OK报文
Follower MGR 的 Paxos Engine 持续侦听来自 Leader 的协议消息经过完整的一次 Paxos 共识过程确认这个(批Event 在集群已经达到多数派将接收的Event写入 Relay LogIO Thread Apply Relay LogRelay Log应用走完整的组提交流程备库会最终会生成自己的binlog文件 MGR采用上述流程的原因是因为MGR默认是多主模式每个节点都可以写所以单个Paxos Group内Follower节点需要将接受的日志先转成RelayLog然后结合自身作为Leader接收的写事务提交在两阶段组提交流程中生产Binlog文件提交最终事务。
DN DN 复用了 MySQL的基础数据结构和函数级代码但是将日志复制、日志管理、日志回放、崩溃恢复环节跟X-Paxos 协议紧密结合在了一起形成了自己的一套多数派复制和状态机机制。与MGR的关键区别在于 DN 事务日志多数派达成一致的切入点在主库事务提交过程中。
Leader 进入事务的组提交流程在组提交的Flush阶段将各THD 上的 Events 写入 Binlog 文件然后再通过X-Paxos将日志异步广播给所有 Follower在组提交的Sync阶段先持久化Binlog然后更新X-Paxos 持久化的位点在组提交的Commit阶段先要等待 X-Paxos 收到多数派应答后然后提交这组事务最后回复客户端OK报文
Follower X-Paxos 持续侦听来自 Leader 的协议消息收到一个(组) Events写入到本地 Binlog回应答收到下一个消息其中携带了已经达成多数派的位点Commit indexSQL Apply线程后台持续应用接收到的Binlog日志最多只应用到多数派位点位置 这种设计的原因是DN当前只支持单主模式所以X-Paxos 协议层面的日志就是 Binlog 本身Follower也省去了 Relay Log其持久化的日志和 Leader 等的日志的数据内容是等价相同的。
2. 关键差异
2.1. Paxos协议效率 MGR
MGR的Paxos协议基于Mencius协议实现属于Multi-Paxos理论区别在于Mencius在降低主节点负载提高吞吐量上做了优化改进MGR的Paxos协议的由XCOM组件实现支持多主和单主模式部署单主模式时Leader 上 Binlog 向 Follower 节点的原子广播每批消息(一个事务)的广播是标准的一次Multi-Paxos 过程一个事务的多数派的满足XCOM至少需要经历AcceptAckAcceptLearn三个报文交互即至少1.5个RTT开销。最多需要经历PrepareAckPrepareAcceptAckAcceptLearn三个报文交互即最多一共2.5个RTT开销由于Paxos协议是在XCOM模块内高内聚完成的MySQL复制系统不感知 所以Leader必须等待完整的 Paxos 过程完毕才能进行事务本地提交包括Binlog的持久化和组提交Follower在完成多数派提交后会异步进行Events的持久化到Relay Log然后由SQL Thread应用和组提交生产Binlog由于Paxos同步的日志是进入组提交流程前没有排序的Binlog所以Leader 上 Binlog Event 的顺序和 Follower 节点上 Relay Log 的 Event 顺序未必相同 DN
DN的Paxos协议是基于Raft协议实现也属于Multi-Paoxs理论区别在于Raft协议更强Leadership保障和工程稳定性保证DN的Paxos协议由X-Paoxs组件完成默认是单主模式单主模式时Leader 上 Binlog 向 Follower 节点的原子广播每批消息的广播是标准的一次 Raft过程。一个事务的多数派的满足X-Paoxs只需要经历AppendAckAppend 两个报文交互只有1个RTT开销Leader 发给 Follower 日志后只要多数派满足它就提交事务不等待第二阶段的 Commit Index 广播Follower在完成多数派提交的前提需要要全部事务日志必须持久化这点与MGR的XCOM有显著差别 MGR只需要在XCOM内存中接收到即可Commit Index 在后续消息和心跳消息中带过去Follower在CommitIndex推高后再进行Apply EventLeader 和 Follower 的 Binlog 内容顺序一致Raft 日志无空洞并且用 Batching/Pipeline机制加大日志复制吞吐量相比MGR事务提交时Leader始终只有一次来回的延迟对延迟敏感的分布式应用十分很关键
2.2. RPO
理论上 Paxos 和 Raft 都可以保证数据一致性以及 Crash Recovery 后已经达成多数派的日志不丢失但是在具体工程上还是有区别。 MGR
XCOM 完全封装了 Paxos 协议而它的所有协议数据又都是先缓存在内存中默认情况事务达成多数派不要求日志持久化。 在多数派宕机、Leader故障的情况下在会有 RPO ! 0严重问题。假设一极端场景
MGR集群由三个节点ABC组成 其中AB同城独立机房C是跨城。A是Leader BC是Follower节点在Leader A节点上发起事务001 Leader A将事务001的日志广播给BC节点通过Paxos协议满足多数派即可认为事务可以提交。AB节构成了多数派C节点由于跨城网络延迟并没有收到事务001的日志下一个时刻Leader A提交了事务001并返回Client 成功此时表示事务001已经提交到数据库此刻 B节点的Follower上事务001的日志还在XCOM 缓存中还没来得及刷到 RelayLog中此刻C节点的Follower上仍然没有接收到A节点的Leader的发过来的事务001日志此时AB节点宕机 A节点故障长时间不能恢复B节点很快重启恢复 BC两节点继续提供读写服务由于宕机时事务001日志并没有持久化到节点B的RelayLog中也没有被节点C接收到因此此刻BC节点其实都已经丢失了事务001并且无法找回这种多数派宕机的场景下导致了RPO!0
社区默认参数下事务达成多数派不要求日志持久化不保证RPO0可以认为是XCOM工程实现中为了性能的取舍。要想保证绝对的RPO0 需要将控制读写一致性的参数group_replication_consistency配置为AFTER但这样的话事务达成多数派除了需要1.5个RTT网络开销外还需要一次日志IO开销性能会很差。 DN
PolarDB-X DN采用X-Paxos实现分布式协议 与MySQL的Group Commit流程深度绑定在一个事务进行提交时强制要求多数派确认落盘持久化后才能允许真正提交。这里多数派落盘是指主库的Binlog落盘备库的IO线程接收到主库的日志并落盘持久化到自己Binlog中。因此即使在极端场景下所有节点故障数据也不会丢失也能保证RPO0。
2.3. RTO
RTO时间与系统本身冷重启的时间开销密切相关反映到具体基础功能上就是故障检测机制-崩溃恢复机制-选主机制-日志追平
2.3.1. 故障检测
MGR
每个节点周期性向其他节点发送心跳包检测其他节点是否健康心跳周期固定是1s无法调整当前节点如果发现其他节点超过group_replication_member_expel_timeout默认5s后没有响应则视为失效节点并从集群中踢出像网络闪断或者异常重启这种异常待网络恢复后单个故障节点自己会尝试自动加入集群然后追平日志 DN
Leader节点周期性向其他节点发生心跳检包检查其他节点是否健康心跳周期为选举超时时间的1/5。选举超时时间由参数consensus_election_timeout控制 默认5s所以Leader节点心跳周期默认1sLeader如果发现其他掉线了仍然继续周期性想其他所有节点发送心跳包以确保其他节点崩溃恢复后能及时接入。但是Leader节点不再向已经掉线的节点发送事务日志非Leader节点不发送心跳检测包但是非Leader节点如果发现超过consensus_election_timeout时间没有收到Leader节点的心跳则触发重新选举像网络闪断或者异常重启这种异常待网络恢复后故障节点自己会自动加入集群因此在故障检测方面DN提供了更多运维配置接口对于跨城部署场景故障的识别度会更加准确 2.3.2. 崩溃恢复
MGR XCOM实现的Paxos协议是内存态多数派的达成不要求持久化协议状态以存活的多数派节点内存状态为准。如果所有节点都挂掉也就无法恢复协议了集群重启后此时需要人工介入进行恢复如果只是单个节点崩溃恢复但是Follower节点落后Leader节点较多事务日志此刻Leader 上的 XCOM 缓存的事务日志已经清除了就只能走Global Recovery 或 Clone流程XCOM缓存大小由group_replication_message_cache_size控制默认1GBGlobal Recovery 是指节点重新加入集群时通过从其他节点获取所需的缺失事务日志Binary Log来恢复数据。这个过程依赖于集群中至少有一个节点保留了所有需要的事务日志Clone依赖Clone Plugin用于数据量较大或缺失较多日志时的恢复。它通过将整个数据库的快照复制到崩溃的节点然后通过最新事务日志进行最终同步Global Recovery 和 Clone 流程通常是自动化的但在某些特殊情况下如网络问题或者其他两个节点XCOM缓存都清除了这时需要人工介入解决 DN X-Paxos协议使用Binlog持久化崩溃恢复时会先完整恢复已提交事务。对于悬挂事务需要等待XPaxos协议层先达成一致确定主备关系后再进行提交或者回滚处理。 整个流程全自动化。即使如果所有节点都挂掉集群重启也能自动恢复对于Follower节点落后Leader节点很多事务日志场景只要Leader上Binlog文件没有删除Follower节点就一定追上因此在崩溃恢复方面DN是完全不需要人工介入的
2.3.3. 选主
单主模式下 MGR的XCOM和DN X-Paxos 这种强 Leader 模式的选主所遵循的基本原则是一样的--集群已共识的日志不能回退。 但是到未共识的日志时存在差异 MGR
选主更多意义上是接下来哪个节点充当 Leader 服务这个 Leader 当选时不一定拥有最新的共识日志所以它需要从集群的其他节点同步最新日志待日志追平后提供读写服务这样的好处是Leader 本身的选择是个策略化的产物比如权重比如顺序。 MGR通过group_replication_member_weight参数控制各节点权重劣处是新当选的Leader本身可能复制延迟较多需要继续追平日志或者应用延迟较多需要继续追平日志应用才能提供读写服务。这会导致RTO时间较长 DN
选主就是协议意义上的哪个节点拥有集群全部多数派的日志它就可以当选 Leader所以这个节点之前可能是 Follower也可能是 Logger而 Logger 是不能提供读写服务的等它把日志同步给其他节点后自己就主动让出 Leader 角色为了能确保指定节点成为LeaderDN使用乐观权重策略强制权重策略来限定当主顺序使用策略化多数派机制确保新主零延迟立刻能提供读写服务因此在选主方面DN不仅支持与MGR一样的策略化选择还支持强制权重策略 2.3.4. 日志追平
日志追平是指主备之间日志存在日志复制延迟备库需要追平日志。对于重启恢复的节点通常都是以备库开始恢复并且已经和主库产生了比较的的日志复制延迟需要向主库追平日志。对于那些和 Leader 物理距离较远的节点多数派达成通常和它们没关系它们总是存在复制日志延迟一直在追平日志。这些情况都需要具体工程实现来确保日志复制延迟的及时解决。 MGR
事务日志都在 XCOM 缓存中而缓存默认只有1G所以复制落后很多的 Follower 节点请求日志的时候很容易缓存早已被清理此时这个落后的 Follower 会自动踢出集群然后以前面崩溃恢复提到Global Recovery 或 Clone流程追平后再自动加入集群。如果遇到如网络问题或者其他两个节点XCOM缓存都清除的情况这时需要人工介入解决为什么一定要先踢出集群因为多写模式故障节点极大影响性能且 Leader 的缓存对它没有任何作用异步追平后再加进来为什么不能使用直接读取Leader本地的Binlog文件因为前面提到的XCOM协议是全内存态Binlog 和 Relay Log 中没有任何关于 XCOM 的协议信息 DN
数据都在 Binlog 文件上只要 Binlog 没有清理那按需发送就好了不存在踢出集群的情况为了降低主库从Binlog文件中读取老的事务日志带来的IO抖动DN优先从FIFO Cache中读取最近缓存的事务日志 FIFO Cache由参数consensus_log_cache_size控制默认64M如果FIFO Cache中老的事务日志已经更新的事务日志淘汰掉了DN会尝试从Prefetch Cache中读取之前缓存的事务日志Prefetch Cache有参数consensus_prefetch_cache_size控制默认64M如果Prefetch Cache中也没有需要的老的事务日志DN会尝试发起异步IO任务批量从Binlog文件中读取指定事务日志前后若干连续的日志放置在Prefetch Cache中等待DN下一次重试读取因此在追平日志方面DN完全不需要人工介入 2.4. 备库回放延迟
备库回放延迟是同一个事务在主库完成提交的时刻与在备库完成事务应用的时刻之间的延迟这里考验的是备库Apply应用日志的性能。它影响的是异常发生时备库成为新主后需要多久才能自身数据应用完毕可以提供读写服务。 MGR
MGR备库从主库接收落盘的是RelayLog文件Apply应用时需要重新将RelayLog读取经历完整两阶段组提交流程生产对应的数据和Binlog文件这里事务应用效率与主库上事务提交效率相同默认的双一配置innodb_flush_log_at_trx_commit、sync_binlog会导致备库应用同样资源开销较大 DN
DN备库从主库接收落盘的就是Binlog文件应用时需要重新将Binlog读取只需要经历一阶段组提交流程生产对应的数据即可由于DN支持完整的Crash Recover备库应用不需要开启innodb_flush_log_at_trx_commit1因此实际上不受双一配置的影响因此在备库回放延迟方面DN备库回放效率会远大于MGR 2.5. 大事务影响
大事务不仅影响普通事务提交在分布式系统中还影响整个分布式协议运行的稳定性严重情况下一个大事务就会导致整个集群较长时间的不可用。 MGR
MGR对大事务的支持没有任何优化 只是增加了参数group_replication_transaction_size_limit控制大事务上限默认143M最大2GB当事务日志超过大事务限制后会直接报错事务无法提交 DN
针对大事务带来的分布式系统的不稳定问题 DN采取大事务拆分大对象拆分的方案进行根治 DN会将大事务的事务日志进行逻辑拆分物理拆分的方式拆分为一个个小块的的事务日志每个小块的事务日志使用完整的Paxos提交保证基于大事务拆分的方案DN对大事务的大小不做任何限制用户可以随意使用 同样能保证RPO0详细说明见《PolarDB-X 存储引擎核心技术 | 大事务优化》因此在大事务问题的处理上DN能做到不受大事务影响
2.6. 部署形态
MGR
MGR支持单主、多主的部署模式多主模式下每个节点可读可写单主模式时主库可读可写备库只能只读MGR高可用部署至少三节点部署也即至少三份数据和日志 不支持日志副本Logger形态MGR不支持只读节点的扩展但是支持MGR主从复制模式的组合实现类似拓扑扩展 DN
DN支持单主模式部署单主模式时单主模式时主库可读可写备库只能只读DN高可用部署至少三节点部署但支持日志副本Logger形态也即Leader、Follower都是全功能副本Logger相比缺少只有日志没有数据并且没有被选举权。 这样的话三节点高可用部署只需要2份数据3份日志的存储开销低成本部署DN支持只读节点部署支持只读副本Learner形态相比全功能副本仅是不具备投票权通过Learner副本实现下游对主库的订阅消费 2.7. 特性小结 MGR DN 协议效率 事务提交耗时 1.5~2.5 RTT 1个 RTT 多数派持久化方式 XCOM内存保存 Binlog持久化 可靠性 RPO0 默认不保证 完全保证 故障检测 所有节点相互检查网络负载高 心跳周期无法调整 主节点周期检查其他节点 心跳周期参数可调 多数派崩溃恢复 人工介入 自动恢复 少数派崩溃恢复 大部分自动恢复特殊情况人工介入 自动恢复 选主 自由指定选主顺序 自由指定选主顺序 日志追平 落后日志不能超过XCOM 1GB缓存 BInlog文件不删除 备库回放延迟 两阶段双一很慢 一阶段双零较快 大事务 默认限制不超过143MB 无大小限制 形态 高可用成本 全功能三副本3份数据存储开销 Logger日志副本2份数据存储 只读节点 借助主从复制实现 协议自带Leaner只读副本实现
3. 测试对比
MGR是MySQL 5.7.17开始引入的但更多MGR相关特性都只在MySQL 8.0上才有并且在MySQL 8.0.22及之后的版本整体会更稳定可靠。因此我们选择双方的最新版8.0.32版本进行对比测试。
考虑到PolarDB-X DN和MySQL MGR在对比测试时存在测试环境差异、编译方式差异、部署方式差异、运行参数差异、测试手段差异进而可能导致测试对比数据不准确本文在各项细节上采用如下方式进行 测试准备 PolarDB-X DN MySQL MGR[1] 硬件环境 使用同一台96C 754GB内存的物理机SSD磁盘 操作系统 Linux 4.9.168-019.ali3000.alios7.x86_64 内核版本 使用基于社区8.0.32版本的内核基线 编译方式 使用相同的RelWithDebInfo编译 运行参数 使用相同的PolarDB-X官网售卖32C128G规格相同参数 部署方式 单主模式
注
MGR默认开启了流控而PolarDB-X DN默认关闭流控。因此对MGR的group_replication_flow_control_mode单独配置关闭这样MGR的性能会是最好的点查时MGR有明显so读取瓶颈因此对MGR的replication_optimize_for_static_plugin_config单独配置开启这样MGR的只读性能会是最好的
3.1. 性能
性能测试是大家在选型数据库时首先关注的一点。这里我们使用官方sysbench工具构建16张表每张表1千万数据进行OLTP场景的性能测试测试对比不同OLTP场景下不同并发时两者的表现。考虑到实际部署的不同情况 我们分别模拟下面4种部署场景
同机房一个机房内部署三节点机器之间互相ping带0.1ms的网络延迟同城三中心同地域三个机房部署三节点机房之间互相ping带1ms的网络延迟比如上海地域的三个机房两地三中心两地三个机房部署三节点同城机房之间ping带1ms的网络同城和异地之间带30ms的网络延迟比如上海/上海/深圳三地三中心三地三个机房部署三节点比如上海/杭州/深圳杭州-上海之间ping带5ms左右的网络延迟杭州/上海 到深圳距离最远的为30ms的网络延迟
说明
a. 考虑4个部署场景性能的横向对比两地三中心、三地三中心都采用3副本的部署模式真实生产业务可以扩展到5副本的部署形态。
b. 考虑到实际使用高可用数据库产品时对RPO0的严格限制但是MGR默认配置RPO0这里在各部署场景下我们继续增加MGR RPO0和RPO0的对比测试。
MGR_0 表示 MGR RPO 0 情况的数据MGR_1 表示 MGR RPO 0 情况的数据DN 表示 DN RPO 0 情况的数据 3.1.1. 同机房 1 4 16 64 256 oltp_read_only MGR_1 688.42 2731.68 6920.54 11492.88 14561.71 MGR_0 699.27 2778.06 7989.45 11590.28 15038.34 DN 656.69 2612.58 7657.03 11328.72 14771.12 MGR_0 vs MGR_1 1.58% 1.70% 15.45% 0.85% 3.27% DN vs MGR_1 -4.61% -4.36% 10.64% -1.43% 1.44% DN vs MGR_0 -6.09% -5.96% -4.16% -2.26% -1.78% oltp_read_write MGR_1 317.85 1322.89 3464.07 5052.58 6736.55 MGR_0 117.91 425.25 721.45 217.11 228.24 DN 360.27 1485.99 3741.36 5460.47 7536.16 MGR_0 vs MGR_1 -62.90% -67.85% -79.17% -95.70% -96.61% DN vs MGR_1 13.35% 12.33% 8.00% 8.07% 11.87% DN vs MGR_0 205.55% 249.44% 418.59% 2415.07% 3201.86% oltp_write_only MGR_1 761.87 2924.1 7211.97 10374.15 16092.02 MGR_0 309.83 465.44 748.68 245.75 318.48 DN 1121.07 3787.64 7627.26 11684.37 15137.23 MGR_0 vs MGR_1 -59.33% -84.08% -89.62% -97.63% -98.02% DN vs MGR_1 47.15% 29.53% 5.76% 12.63% -5.93% DN vs MGR_0 261.83% 713.78% 918.76% 4654.58% 4652.96% 从测试结果可以看出
在只读场景无论是对比MGR_1RPO0还是MGR_0RPO0DN与MGR之间的差异稳定在-5%~10%之间可以认为基本相同。RPO是否等于0对只读事务不影响在读写混合、只写事务场景在DNRPO0相比MGR_1时RPO0性能提升了5%~47%并且呈现低并发时DN性能优势明显高并发时优势不明显的特点。 这是由于低并发时DN的协议效率更高但高并发下DN和MGR的性能热点都在刷脏上所致而在相同的RPO0的前提下在读写混合、只写事务场景在DN相比MGR_0性能提升了2倍-46倍并且随着并发提高DN性能优势加强的特点。也难怪MGR默认也要为了性能而舍弃RPO0
3.1.2. 同城三中心 TPS对比 1 4 16 64 256 oltp_read_only MGR_1 695.69 2697.91 7223.43 11699.29 14542.4 MGR_0 691.17 2708.6 7849.98 11636.94 14670.99 DN 645.11 2611.15 7628.39 11294.36 14647.22 MGR_0 vs MGR_1 -0.65% 0.40% 8.67% -0.53% 0.88% DN vs MGR_1 -7.27% -3.22% 5.61% -3.46% 0.72% DN vs MGR_0 -6.66% -3.60% -2.82% -2.94% -0.16% oltp_read_write MGR_1 171.37 677.77 2230 3872.87 6096.62 MGR_0 117.11 469.17 765.64 813.85 812.46 DN 257.35 1126.07 3296.49 5135.18 7010.37 MGR_0 vs MGR_1 -31.66% -30.78% -65.67% -78.99% -86.67% DN vs MGR_1 50.17% 66.14% 47.82% 32.59% 14.99% DN vs MGR_0 119.75% 140.01% 330.55% 530.97% 762.86% oltp_write_only MGR_1 248.37 951.88 2791.07 5989.57 11666.16 MGR_0 162.92 603.72 791.27 828.16 866.65 DN 553.69 2173.18 5836.64 10588.9 13241.74 MGR_0 vs MGR_1 -34.40% -36.58% -71.65% -86.17% -92.57% DN vs MGR_1 122.93% 128.30% 109.12% 76.79% 13.51% DN vs MGR_0 239.85% 259.96% 637.63% 1178.61% 1427.92% 从测试结果可以看出
在只读场景无论是对比MGR_1RPO0还是MGR_0RPO0DN与MGR之间的差异稳定在-7%~5%之间可以认为基本相同。RPO是否等于0对只读事务不影响在读写混合、只写事务场景在DNRPO0相比MGR_1时RPO0性能提升了30%~120%并且呈现低并发时DN性能优势明显高并发时优势不明显的特点。 这是由于低并发时DN的协议效率更高但高并发下DN和MGR的性能热点都在刷脏上所致而在相同的RPO0的前提下在读写混合、只写事务场景在DN相比MGR_0性能提升了1倍-14倍并且随着并发提高DN性能优势加强的特点。也难怪MGR默认也要为了性能而舍弃RPO0
3.1.3. 两地三中心 TPS对比 1 4 16 64 256 oltp_read_only MGR_1 687.76 2703.5 7030.37 11580.36 14674.7 MGR_0 687.17 2744.41 7908.44 11535.35 14656 DN 657.06 2610.58 7591.21 11174.94 14545.45 MGR_0 vs MGR_1 -0.09% 1.51% 12.49% -0.39% -0.13% DN vs MGR_1 -4.46% -3.44% 7.98% -3.50% -0.88% DN vs MGR_0 -4.38% -4.88% -4.01% -3.12% -0.75% oltp_read_write MGR_1 29.13 118.64 572.25 997.92 2253.19 MGR_0 26.94 90.8 313.64 419.17 426.7 DN 254.87 1146.57 3339.83 5307.85 7171.95 MGR_0 vs MGR_1 -7.52% -23.47% -45.19% -58.00% -81.06% DN vs MGR_1 774.94% 866.43% 483.63% 431.89% 218.30% DN vs MGR_0 846.07% 1162.74% 964.86% 1166.28% 1580.79% oltp_write_only MGR_1 30.81 145.54 576.61 1387.64 3705.51 MGR_0 28.68 108.86 387.48 470.5 476.4 DN 550.11 2171.64 5866.41 10381.72 14478.38 MGR_0 vs MGR_1 -6.91% -25.20% -32.80% -66.09% -87.14% DN vs MGR_1 1685.49% 1392.13% 917.40% 648.16% 290.73% DN vs MGR_0 1818.10% 1894.89% 1413.99% 2106.53% 2939.12% 从测试结果可以看出
在只读场景无论是对比MGR_1RPO0还是MGR_0RPO0DN与MGR之间的差异稳定在-4%~7%之间可以认为基本相同。RPO是否等于0对只读事务不影响在读写混合、只写事务场景在DNRPO0相比MGR_1时RPO0性能提升了2倍~16倍并且呈现低并发时DN性能优势明显高并发时优势不明显的特点。 这是由于低并发时DN的协议效率更高但高并发下DN和MGR的性能热点都在刷脏上所致而在相同的RPO0的前提下在读写混合、只写事务场景在DN相比MGR_0性能提升了8倍-29倍并且随着并发提高DN性能优势加强的特点。也难怪MGR默认也要为了性能而舍弃RPO0
3.1.4. 三地三中心 TPS对比 1 4 16 64 256 oltp_read_only MGR_1 688.49 2747.69 7853.91 11722.71 15292.73 MGR_0 687.66 2756.3 8005.11 11567.89 15055.69 DN 656.06 2600.35 7657.85 11227.56 14562.86 MGR_0 vs MGR_1 -0.12% 0.31% 1.93% -1.32% -1.55% DN vs MGR_1 -4.71% -5.36% -2.50% -4.22% -4.77% DN vs MGR_0 -4.60% -5.66% -4.34% -2.94% -3.27% oltp_read_write MGR_1 26.01 113.98 334.95 693.34 2030.6 MGR_0 23.93 110.17 475.68 497.92 511.99 DN 122.06 525.88 1885.7 3314.9 5889.79 MGR_0 vs MGR_1 -8.00% -3.34% 42.02% -28.19% -74.79% DN vs MGR_1 369.28% 361.38% 462.98% 378.11% 190.05% DN vs MGR_0 410.07% 377.34% 296.42% 565.75% 1050.37% oltp_write_only MGR_1 27.5 141.64 344.05 982.47 2889.85 MGR_0 25.52 155.43 393.35 470.92 504.68 DN 171.74 535.83 1774.58 4328.44 9429.24 MGR_0 vs MGR_1 -7.20% 9.74% 14.33% -52.07% -82.54% DN vs MGR_1 524.51% 278.30% 415.79% 340.57% 226.29% DN vs MGR_0 572.96% 244.74% 351.15% 819.15% 1768.36% 从测试结果可以看出
在只读场景无论是对比MGR_1RPO0还是MGR_0RPO0DN与MGR之间的差异稳定在-5%~0%之间可以认为基本相同。RPO是否等于0对只读事务不影响在读写混合、只写事务场景在DNRPO0相比MGR_1时RPO0性能提升了2倍~5倍并且呈现低并发时DN性能优势明显高并发时优势不明显的特点。 这是由于低并发时DN的协议效率更高但高并发下DN和MGR的性能热点都在刷脏上所致而在相同的RPO0的前提下在读写混合、只写事务场景在DN相比MGR_0性能提升了2倍-17倍并且随着并发提高DN性能优势加强的特点。也难怪MGR默认也要为了性能而舍弃RPO0 3.1.5. 部署对比
为了明显对比不同部署方式下性能的变化差异我们选择上述测试中oltp_write_only场景256并发下不同部署方式下的MGR和DN的TPS数据以机房测试数据为基线计算对比不同部署方式时TPS数据相比基线的比例以此感知跨城部署时性能变化差异 MGR_1 (256并发) DN (256并发) DN相比于MGR的性能优势 同机房 16092.02 15137.23 -5.93% 同城三中心 11666.16 (72.50%) 13241.74 87.48% 13.50% 两地三中心 3705.51 (23.03%) 14478.38 (95.64%) 290.72% 三地三中心 2889.85 (17.96%) 9429.24 (62.29%) 226.28% 从测试结果可以看出
随着部署方式的扩大化MGR_1RPO0的TPS下降明显相比同机房部署同城跨机房部署性能下降27.5% 跨城两地三中心、三地三中心部署性能下降77%~82%这是由于跨城部署RT增加导致而DNRTO0则相对稳定相比同机房部署同城跨机房、两地三中心部署性能下降4%~12% 三地三中心在高网络延迟下部署时性能下降37%这也是由于跨城部署RT增加导致。不过得益于DN的BatchPipeline机制跨城带来的影响可以通过提高并发的来解决比如三地三中心架构下在512并发下基本可以对齐同城、两地三中心下的性能吞吐由此可见跨城部署对MGR_1RPO0的影响很大
3.1.6. 性能抖动
实际使用中我们不仅关注性能数据如何还需要关注性能抖动情况。毕竟如果抖动像过山车一样对实际用户的体验也非常差。我们对TPS实时输出数据监控展示考虑到sysbenc工具本身不支持输出性能抖动的监测数据于是采用数学上的变异系数作为对比指标
变异系数Coefficient of Variation CV 变异系数是标准差除以平均值通常用来比较不同数据集的波动情况尤其是当平均值差异较大时。CV 越大数据相对于平均值的波动越大
以256并发下oltp_read_write场景为例我们统计分析MGR_1RPO0、DNRPO0在同机房、同城三中心、两地三中心、三地三中心五种部署模式下的TPS抖动情况。 实际抖动图如下实际各场景抖动指标数据如下 CV 同机房 同城三中心 两地三中心 三地三中心 MGR_1 10.04% 8.96% 6.02% 8.63% DN 3.68% 3.78% 2.55% 4.05% MGR_1/DN 272.83% 237.04% 236.08% 213.09% 从测试结果可以看出
MGR在oltp_read_write场景下TPS呈现不稳定的状态中间竟然无缘无故猛跌现象在多个部署场景多次试验中均发现这个现象。 相比下DN就十分稳定计算变异系数CV MGR的CV很大6%~10%同机房延迟最小的情况时竟然还达到最大值10%而DN的CV为比较稳定2%~4% DN比MGR的性能稳定性基本高到2倍由此可见MGR_1RPO0的性能抖动比较大 3.2. RTO
分布式数据库的核心特点就是高可用集群中任何一个节点的故障都不影响整体的可用性。针对同机房场景部署一主两备的3节点典型部署形态我们尝试对对一下三种场景进行可用性的测试
中断主库然后重启观察过程中集群恢复可用性的RTO时间中断任意一个备库然后重启观察过程中主库的可用性表现 3.2.1. 主库宕机重启
无负载情况下 kill leader 监控集群各节点状态变化以及是否可写 MGR DN 起始正常 0 0 kill leader 0 0 发现异常节点时间 5 5 3节点降为2节点时间 23 8 MGR DN 起始正常 0 0 kill leader自动拉起 0 0 发现异常节点时间 5 5 3节点降为2节点时间 23 8 2节点恢复3节点时间 37 15 从测试结果可以看出在无压力的情况下
DN的RTO在8-15s 降为2节点需要8s恢复3节点需要15s;MGR的RTO在23-37s 降为2节点需要23s恢复3节点需要37sRTO表现DN整体优于MGR
3.2.2. 备库宕机重启
使用sysbench进行oltp_read_write场景下16个线程的并发压测在图中第10s的时刻手动kill一个备节点观察sysbench的的实时输出TPS数据。 从测试结果图中可见
中断备库后MGR的主库TPS大幅下降持续20s左右才恢复正常水平。根据日志分析这里经历了检测故障节点变成unreachable状态、将故障节点踢出MGR集群两个过程。这个测试证实了MGR社区流传很久的一个缺陷在3节点中即使只有1个节点不可用整个集群就有一段时间的剧烈抖动不可用针对单主时MGR存在单节点故障整个实例不可用的问题社区从8.0.27中引入了MGR paxos single leader功能解决但默认关闭。 这里我们将group_replication_paxos_single_leader开启后继续验证这次中断备库后主库性能保持稳定并且稍微还有所提升了原因应该与网络负载降低有关对于DN中断备库后主库TPS反而立刻上升约20% 随后一直保持稳定集群也一直处于可用状态。这里和MGR相反的表现原因是中断一个备库后主库每次只用向剩下一个备库发送日志网络收发包流程效率更高了 继续测试我们将备库重启恢复观察主库TPS数据变化 从测试结果图中可见
MGR在5s时刻从2节点恢复成3节点但同样存在着主库不可用 持续时间大约12s。尽管备库节点最终加入集群但MEMBER_STATE状态一直为RECOVERING说明此时正在追数据对group_replication_paxos_single_leader开启后的场景同样进行备库重启的验证结果MGR在10s时刻从2节点恢复成3节点但仍然出现了持续时间大约7s的不可用时间看来这个参数并不能完全解决单主时MGR存在单节点故障整个实例不可用的问题。对于DN备库在10s时刻从2节点恢复成3节点主库一直保持可用状态。 这里TPS会有短暂的波动这个是由于重启后备库日志复制延迟落后较多需要从主库拉取落后的日志因此对主库产生少量影响待日志追评后整体性能就处于稳定状态。 3.3. RPO
为了构造MGR多数派故障RPO0场景我们使用社区自带的MTR Case方式对MGR进行故障注入测试设计的Case如下
--echo
--echo ############################################################
--echo # 1. Deploy a 3 members group in single primary mode.
--source include/have_debug.inc
--source include/have_group_replication_plugin.inc
--let $group_replication_group_name aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
--let $rpl_group_replication_single_primary_mode1
--let $rpl_skip_group_replication_start 1
--let $rpl_server_count 3
--source include/group_replication.inc--let $rpl_connection_name server1
--source include/rpl_connection.inc
--let $server1_uuid SELECT server_uuid
--source include/start_and_bootstrap_group_replication.inc--let $rpl_connection_name server2
--source include/rpl_connection.inc
--source include/start_group_replication.inc--let $rpl_connection_name server3
--source include/rpl_connection.inc
--source include/start_group_replication.inc--echo
--echo ############################################################
--echo # 2. Init data
--let $rpl_connection_name server1
--source include/rpl_connection.inc
CREATE TABLE t1 (c1 INT PRIMARY KEY);
INSERT INTO t1 VALUES(1);--source include/rpl_sync.inc
SELECT * FROM t1;--let $rpl_connection_name server2
--source include/rpl_connection.inc
SELECT * FROM t1;--let $rpl_connection_name server3
--source include/rpl_connection.inc
SELECT * FROM t1;--echo
--echo ############################################################
--echo # 3. Mock crash majority members--echo # server 2 wait before write relay log
--let $rpl_connection_name server2
--source include/rpl_connection.inc
SET GLOBAL debug d,wait_in_the_middle_of_trx;--echo # server 3 wait before write relay log
--let $rpl_connection_name server3
--source include/rpl_connection.inc
SET GLOBAL debug d,wait_in_the_middle_of_trx;--echo # server 1 commit new transaction
--let $rpl_connection_name server1
--source include/rpl_connection.inc
INSERT INTO t1 VALUES(2);
# server 1 commit t1(c12) record
SELECT * FROM t1;
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
--echo # server 1 crash
--source include/kill_mysqld.inc--echo # sleep enough time for electing new leader
sleep 60;--echo
--echo # server 3 check
--let $rpl_connection_name server3
--source include/rpl_connection.inc
SELECT * FROM t1;
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
--echo # server 3 crash and restart
--source include/kill_and_restart_mysqld.inc--echo # sleep enough time for electing new leader
sleep 60;--echo
--echo # server 2 check
--let $rpl_connection_name server2
--source include/rpl_connection.inc
SELECT * FROM t1;
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
--echo # server 2 crash and restart
--source include/kill_and_restart_mysqld.inc--echo # sleep enough time for electing new leader
sleep 60;--echo
--echo ############################################################
--echo # 4. Check alive members, lost t1(c12) record--echo # server 3 check
--let $rpl_connection_name server3
--source include/rpl_connection.inc
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
--echo # server 3 lost t1(c12) record
SELECT * FROM t1;--echo
--echo # server 2 check
--let $rpl_connection_name server2
--source include/rpl_connection.inc
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
--echo # server 2 lost t1(c12) record
SELECT * FROM t1;!include ../my.cnf[mysqld.1]
loose-group_replication_member_weight100[mysqld.2]
loose-group_replication_member_weight90[mysqld.3]
loose-group_replication_member_weight80[ENV]
SERVER_MYPORT_3 mysqld.3.port
SERVER_MYSOCK_3 mysqld.3.socketCase运行结果如下 ############################################################
# 1. Deploy a 3 members group in single primary mode.
include/group_replication.inc [rpl_server_count3]
Warnings:
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the START SLAVE Syntax in the MySQL Manual for more information.
[connection server1]
[connection server1]
include/start_and_bootstrap_group_replication.inc
[connection server2]
include/start_group_replication.inc
[connection server3]
include/start_group_replication.inc############################################################
# 2. Init data
[connection server1]
CREATE TABLE t1 (c1 INT PRIMARY KEY);
INSERT INTO t1 VALUES(1);
include/rpl_sync.inc
SELECT * FROM t1;
c1
1
[connection server2]
SELECT * FROM t1;
c1
1
[connection server3]
SELECT * FROM t1;
c1
1############################################################
# 3. Mock crash majority members
# server 2 wait before write relay log
[connection server2]
SET GLOBAL debug d,wait_in_the_middle_of_trx;
# server 3 wait before write relay log
[connection server3]
SET GLOBAL debug d,wait_in_the_middle_of_trx;
# server 1 commit new transaction
[connection server1]
INSERT INTO t1 VALUES(2);
SELECT * FROM t1;
c1
1
2
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
CHANNEL_NAME MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION MEMBER_COMMUNICATION_STACK
group_replication_applier 127.0.0.1 13000 ONLINE PRIMARY 8.0.32 XCom
group_replication_applier 127.0.0.1 13002 ONLINE SECONDARY 8.0.32 XCom
group_replication_applier 127.0.0.1 13004 ONLINE SECONDARY 8.0.32 XCom
# server 1 crash
# Kill the server
# sleep enough time for electing new leader# server 3 check
[connection server3]
SELECT * FROM t1;
c1
1
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
CHANNEL_NAME MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION MEMBER_COMMUNICATION_STACK
group_replication_applier 127.0.0.1 13002 ONLINE PRIMARY 8.0.32 XCom
group_replication_applier 127.0.0.1 13004 ONLINE SECONDARY 8.0.32 XCom
# server 3 crash and restart
# Kill and restart
# sleep enough time for electing new leader# server 2 check
[connection server2]
SELECT * FROM t1;
c1
1
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
CHANNEL_NAME MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION MEMBER_COMMUNICATION_STACK
group_replication_applier 127.0.0.1 13002 ONLINE PRIMARY 8.0.32 XCom
group_replication_applier 127.0.0.1 13004 UNREACHABLE SECONDARY 8.0.32 XCom
# server 2 crash and restart
# Kill and restart
# sleep enough time for electing new leader############################################################
# 4. Check alive members, lost t1(c12) record
# server 3 check
[connection server3]
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
CHANNEL_NAME MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION MEMBER_COMMUNICATION_STACK
group_replication_applier NULL OFFLINE
# server 3 lost t1(c12) record
SELECT * FROM t1;
c1
1# server 2 check
[connection server2]
select CHANNEL_NAME,MEMBER_HOST,MEMBER_PORT,MEMBER_STATE,MEMBER_ROLE,MEMBER_VERSION,MEMBER_COMMUNICATION_STACK from performance_schema.replication_group_members order by MEMBER_PORT;
CHANNEL_NAME MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION MEMBER_COMMUNICATION_STACK
group_replication_applier NULL OFFLINE
# server 2 lost t1(c12) record
SELECT * FROM t1;
c1
1复现丢数的Case大概逻辑是这样的
MGR由3个节点组成单主模式Server 1/2/3其中Server 1为主库并初始化1条记录c11故障注入Server 2/3在写Relay Log时会hang住连接到Server 1节点写入了c12的记录事务commit也返回了成功然后Mock server1的异常crash机器故障不能恢复无法访问此时剩下Server 2/3形成多数派正常重启Server 2/3快速恢复但是Server 2/3无法恢复集群可用状态连接Server 2/3节点查询数据库记录仅看到了c11的记录Server 2/3都丢失了c12 根据以上Case可见对于MGR当多数派宕机主库不可用备库恢复后存在数据丢失的RPO0的情况原本已返回客户端commit成功的记录丢了。
而对于DN多数派的达成需要日志在多数派中都持久化所以即使在上述场景下数据也不会丢失也能保证RPO0。 3.4. 备库回放延迟
MySQL的传统主备模式下备库一般会包含IO线程和Apply线程引入了Paxos协议后替换了IO线程同步主备库binlog的工作备库的复制延迟主要就看备库Apply回放的开销我们这里成为备库回放延迟。
我们使用sysbench测试oltp_write_only场景测试100并发下 不同event数量时 备库回放出现延迟的持续时间。备库回放延迟时间通过监控performance_schema.replication_applier_status_by_worker表的APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP列来实时查看各worker是否工作来断定复制是否结束 从测试结果图中可见
相同写入数据量下DN的备库回放所有日志的完成时间远远优于MGRDN的的耗时仅是MGR的3%~4%。 这对主备切换的及时性十分关键。随着写入数量的增加DN相比MGR的备库回放延迟优势继续保持十分稳定。分析备库回放延迟原因MGR的备库回放策略采用group_replication_consistency默认值为EVENTUAL即RO和RW事务在执行之前都不等待应用前面的事务。这样可以保证主库写入性能的最大化但是备库延迟就会比较大通过牺牲备库延迟和RPO0来换取主库的高性能写入开启MGR的限流功能可以平衡性能和备库延迟但主库的性能就会打折扣
3.5. 测试小结 MGR DN 性能 读事务 持平 持平 写事务 RPO0时性能不如DN RPO0时性能远不如DN 跨城部署性能下跌严重27%~82% 写事务性能远高于MGR 跨城部署性能下降较小4%~37% 抖动 性能抖动厉害抖动范围6~10% 比较平稳3%只有MGR一半 RTO 主库宕机 5s发现异常23s降为两节点 5s发现异常8s降为两节点 主库重启 5s发现异常37s恢复三节点 5s发现异常15s恢复三节点 备库宕机 主库持续20s出现流量跌0 需要显式开启group_replication_paxos_single_leader后可缓解 主库持续高可用 备库重启 主库持续10s出现流量跌0 显式开启group_replication_paxos_single_leader也无效 主库持续高可用 RPO Case复现 多数派宕机时RPO0 性能和RPO0两者不能兼得 RPO 0 备库延迟 备库回放耗时 主备延迟很大 性能和主备延迟两者不能兼得 整体备库回放的总耗时是MGR的4% 是MGR的25倍 参数 关键参数 group_replication_flow_control_mode流控默认开启需要配置关闭提高性能replication_optimize_for_static_plugin_config静态插件优化默认关闭需要开启提高性能group_replication_paxos_single_leader默认关闭需要开启提升备库宕机主库稳定性group_replication_consistency默认关闭不保证RPO0强要求RPO0时需要配置AFTERgroup_replication_transaction_size_limit默认143M遇到大事务时需要调大binlog_transaction_dependency_tracking默认COMMIT_ORDERMGR时需要调整为WRITESET来提高备库回放性能 默认配置不需要专业人员定制化配置
4. 总结
经过深入的技术剖析与性能对比PolarDB-X DN凭借其自研的X-Paxos协议和一系列优化设计在性能、正确性、可用性及资源开销等方面展现出对MySQL MGR的多项优势但MGR在MySQL生态体系内也占据重要地位但需要考虑备库宕机抖动、跨机房容灾性能波动、稳定性等各种情况因此如果想用好MGR必须配备专业的技术和运维团队的支持。
在面对大规模、高并发、高可用性需求时PolarDB-X存储引擎以其独特的技术优势和优异的性能表现相比于MGR在开箱即用的场景下PolarDB-X基于DN的集中式标准版在功能和性能都做到了很好的平衡成为了极具竞争力的数据库解决方案。