从源码分析 MGR 的流控机制( 五 )


2022-08-27T19:01:50.699939+08:00 63 [Note] [MY-011726] [Repl] Plugin group_replication reported: 'Flow control - update member stats: 127.0.0.1:33061 stats certifier_queue 0, applier_queue 0 certified 217069 (1860), applied 1 (0), local 217070 (1861), quota 28566 (1857) mode=1'2022-08-27T19:01:50.699955+08:00 63 [Note] [MY-011726] [Repl] Plugin group_replication reported: 'Flow control - update member stats: 127.0.0.1:33071 stats certifier_queue 0, applier_queue 2 certified 218744 (157), applied 218746 (165), local 0 (0), quota 28566 (1857) mode=1'2022-08-27T19:01:50.699967+08:00 63 [Note] [MY-011726] [Repl] Plugin group_replication reported: 'Flow control - update member stats: 127.0.0.1:33081 stats certifier_queue 16383, applier_queue 0 certified 0 (0), applied 0 (0), local 0 (0), quota 28566 (1857) mode=1'2022-08-27T19:01:50.699979+08:00 63 [Note] [MY-011727] [Repl] Plugin group_replication reported: 'Flow control: throttling to 141 commits per 10 sec, with 1 writing and 0 non-recovering members, min capacity 157, lim throttle 100'最后,会将 127.0.0.1:33071 这个节点 1s 的配额(157 * 0.9)当作 127.0.0.1:33061 10s 的配额 。
所以,我们会观察到下面这个现象:
执行时间   TPS19:01:50   4919:01:51   9319:01:52    119:01:53    119:01:54    119:01:55    119:01:56    119:01:57    119:01:58    119:01:59    119:02:00    1127.0.0.1:33061 在头两秒就使用完了所有配额 , 导致后面的事务会等待 1s(mysql_cond_timedwait 的超时时长)才处理 。因为模拟时指定的并发线程数是 1,所以这里的 TPS 会是 1 。
为什么不是被 flow_control_step 中的m_flow_control_cond 信号释放呢?因为127.0.0.1:33061 这个节点的 group_replication_flow_control_period 是 10,所以 flow_control_step 10s 才会执行一次 。
group_replication_flow_control_applier_threshold
待应用的事务数如果超过 group_replication_flow_control_applier_threshold 的设置,则会触发流控 , 该参数默认是 25000 。
group_replication_flow_control_certifier_threshold
待认证的事务数如果超过 group_replication_flow_control_certifier_threshold 的设置 , 则会触发流控,该参数默认是 25000 。
group_replication_flow_control_min_quota
group_replication_flow_control_min_recovery_quota
两个参数都会决定当前节点下个周期的最小配额,只不过 group_replication_flow_control_min_recovery_quota 适用于新节点加入时的分布式恢复阶段 。group_replication_flow_control_min_quota 则适用于所有场景 。如果两者同时设置了,group_replication_flow_control_min_quota 的优先级更高 。两者默认都为 0,即不限制 。
group_replication_flow_control_max_quota
当前节点下个周期的最大配额 。默认是 0,即不限制 。
group_replication_flow_control_member_quota_percent
分配给当前成员的配额比例 。有效值 0 - 100 。默认为 0,此时,节点配额 = 集群配额 / 上个周期写节点的数量 。
注意,这里的写节点指的是有实际写操作的节点,不是仅指 PRIMARY 节点 。毕竟不是所有的 PRIMARY 节点都会有写操作 。
另外,设置配额比例时,不要求所有节点的配额比例加起来等于 100 。
group_replication_flow_control_hold_percent
预留配额的比例 。有效值 0 - 100,默认是 10 。预留的配额可用来处理落后节点积压的事务 。
group_replication_flow_control_release_percent
当流控结束后,会逐渐增加吞吐量以避免出现突刺 。
下一周期的 quota_size = 上一周期的 quota_size * (1 + group_replication_flow_control_release_percent / 100) 。有效值 0 - 1000,默认是 50 。
总结1. 从可用性的角度出发,不建议线上关闭流控 。虽然主节点出现故障的概率很?。?但墨菲定律告诉我们,任何有可能发生的事情最后一定会发生 。在线上还是不要心存侥幸 。
2. 流控限制的是当前节点的流量,不是其它节点的 。
3. 流控参数在各节点应保持一致,尤其是 group_replication_flow_control_period 。

推荐阅读