代码的逻辑看上去有点复杂 。
接下来 , 我们通过一个具体的示例看看 flow_control_step 函数的实现逻辑 。
基于案例定量分析测试集群有三个节点组成:127.0.0.1:33061,127.0.0.1:33071 和 127.0.0.1:33081 。
运行在多主模式下 。
使用 sysbench 对 127.0.0.1:33061 进行插入测试(oltp_insert) 。
为了更容易触发流控,这里将 127.0.0.1:33061 节点的 group_replication_flow_control_applier_threshold 设置为了 10 。
以下是触发流控时 127.0.0.1:33061 的日志信息 。
[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 7841 (177), applied 0 (0), local 7851 (177), quota 146 (156) mode=1'[Note] [MY-011726] [Repl] Plugin group_replication reported: 'Flow control - update member stats: 127.0.0.1:33071 stats certifier_queue 0, applier_queue 0 certified 7997 (186), applied 8000 (218), local 0 (0), quota 146 (156) mode=1'[Note] [MY-011726] [Repl] Plugin group_replication reported: 'Flow control - update member stats: 127.0.0.1:33081 stats certifier_queue 0, applier_queue 15 certified 7911 (177), applied 7897 (195), local 0 (0), quota 146 (156) mode=1'[Note] [MY-011727] [Repl] Plugin group_replication reported: 'Flow control: throttling to 149 commits per 1 sec, with 1 writing and 1 non-recovering members, min capacity 177, lim throttle 0'
以 127.0.0.1:33081 的状态数据为例,我们看看输出中各项的具体含义:
- certifier_queue 0:认证队列的长度 。
- applier_queue 15:应用队列的长度 。
- certified 7911 (177):7911 是已经认证的总事务数,177 是上一周期进行认证的事务数(m_delta_transactions_certified) 。
- applied 7897 (195):7897 是已经应用的总事务数,195 是上一周期应用的事务数(m_delta_transactions_applied) 。
- local 0 (0):本地事务数 。括号中的 0 是上一周期的本地事务数(m_delta_transactions_local) 。
- quota 146 (156):146 是上一周期的 quota_size,156 是上一周期的 quota_used 。
- mode=1:mode 等于 1 是开启流控 。
触发流控后,会调用 flow_control_step 计算下一周期的 m_quota_size 。
1. 循环遍历各节点的状态信息 。集群的吞吐量(min_capacity)取各个节点 m_delta_transactions_certified 和 m_delta_transactions_applied 的最小值 。具体在本例中,min_capacity = min(177, 186, 218, 177, 195) = 177 。
2. min_capacity 不能太小,不能低于 lim_throttle 。im_throttle 的取值逻辑如下:
- 初始值是 0.05 * min (group_replication_flow_control_applier_threshold, group_replication_flow_control_certifier_threshold) 。
具体在本例中,min_capacity = 0.05 * min(10, 25000) = 0.5 。
- 如果设置了 group_replication_flow_control_min_recovery_quota 且 num_non_recovering_members 为 0,则会将 group_replication_flow_control_min_recovery_quota 赋值给 min_capacity 。
num_non_recovering_members 什么时候会为 0 呢?在新节点加入时,因为认证队列中积压的事务过多而触发的流控 。
- 如果设置了 group_replication_flow_control_min_quota,则会将 group_replication_flow_control_min_quota 赋值给 min_capacity 。
4. quota_size 不能太大,不能超过 group_replication_flow_control_max_quota 。
5. 注意,这里计算的 quota_size 是集群的吞吐量,不是单个节点的吞吐量 。如果要计算当前节点的吞吐量,最简单的办法是将 quota_size / 有实际写操作的节点数(num_writing_members) 。
怎么判断一个节点是否进行了实际的写操作呢?很简单,上一周期有本地事务提交,即 m_delta_transactions_local > 0 。具体在本例中,只有一个写节点,所以 , 当前节点的 quota_size 就等于集群的 quota_size , 即 159 。
推荐阅读
- RAID5 IO处理之replace代码详解
- Linux Block模块之IO合并代码解析
- 从0开始写一个简单的vite hmr 插件
- React魔法堂:echarts-for-react源码略读
- 惠普星13Air锐龙版怎么样_惠普星13Air锐龙版性能表现
- 我的世界如何去末影之地(我的世界如何从末影之地回家)
- 记一次 .NET 某企业OA后端服务 卡死分析
- 【C++】从零开始的CS:GO逆向分析3——写出一个透视
- ysoserial commonscollections6 分析
- 实例分析Scheduled Thread Pool Executor与Timer的区别