Pulsar 负载均衡与transaction_coordinator_assign

news/2024/7/10 0:24:43 标签: 负载均衡, pulsar, 中间件

背景与现状

TC加载到哪个broker上取决于transaction_coordinator_assign-partition-${TC ID}分区加载到哪个broker上。

默认transaction_coordinator_assign有16个分区,因此默认有16个TC,我们需要根据集群机器/broker数目来设置合理的TC个数。
为了保证集群压力均衡,和为了提高服务可用性,我们需要让TC尽量均衡地打散到整个集群机器上,避免所有TC加载到某几台机器。

  • 可用性:比如说,如果16个TC都加载到两三台broker上,那么在集群滚动升级的时候,重启该broker就会导致大量TC同时不可用,这就会明显影响到客户端了。
  • 负载均衡:而且broker承载TC本身也会造成一定的资源消耗,如TC需要跟客户端、TB、TP进行协调,某个broker承载太多TC会导致该机器的负载过高。

transaction_coordinator_assign目前是属于pulsar/system namespace下面的。
目前我们是不对pulsar/system namespace的bundles执行load shedding的,即只会在第一次加载bundle的时候使用hash分配尽量均匀地在当前可用broker列表上均匀地分布,之后不会再对这些bundle进行shedding切换。除非该broker重启导致bundle被卸载,或者管理员执行amdin命令导致bundle被unload,从而触发bundle assign。

存在的问题

那么目前就会有如下问题:
因为broker滚动重启都是有一定时间间隔的,而且一般是一台broker恢复完再重启下一台。
如果集群一开始一台broker都没有在线,然后开始启动集群,那么就会导致所有TC都加载到第一个启动的broker上了
如下图,中间shutdown集群一段时间,然后启动集群,导致16个TC全部加载到broker1上面去了,后面broker2~broker5启动起来后,也不会分配到任何TC。
在这里插入图片描述
这个问题只在集群初启动时会出现,当集群是滚动重启升级时不会有问题,因为集群始终有大量的broker可用,能够保证transaction_coordinator_assign-partition-${TC ID}分区尽量均衡地分配到所有broker上。

要解决这个问题,目前来说也比较简单,集群启动完成后把broker1重启一下,这样所有TC就会重新加载到所有其他broker上了。
如下图:
在这里插入图片描述
还有一个case,举个例子:如果一开始集群broker个数为2,16个TC分配到这两个broker上,后续机器扩容到5台,那么类似地,TC不会分配到新加入的3台机器上。
同样地,对集群滚动重启一轮就没啥问题了。

动态负载均衡

关于是否对transaction_coordinator_assign进行动态负载均衡的分析
前面也说了,目前我们是不对pulsar/system namespace的bundles执行load shedding的。因此transaction_coordinator_assign是不会进行动态负载均衡
那有必要做动态的负载均衡吗?

动态负载均衡肯定是有好处的,上面问题出现的根源就是无法适应集群加入新broker的情况

bundle负载度量

但是目前所有的负载均衡算法,在分配bundle的时候,都是根据bundle的流量吞吐、消息速率来估测(度量)它会造成多大负载。对于普通业务topic而言这是合适的,但是对于pulsar/system下面的bundle这是不合适的,因为transaction_coordinator_assign本身是没有流量的,transaction_coordinator_assign造成的负载是TC的运行本身
因为shedding算法一般都会从负载大到小挑选bundle执行unload,然后load到低负载broker上,因此在执行shedding时,pulsar/system下面的bundle基本都不会被挑选出来进行shedding,也就是说,开没开动态负载均衡都差不多

因此,就算要启用动态负载均衡,也应该要另起一套负载估测逻辑。那该如何估测呢?

首先,目前客户端在使用事务时,都是直接与所有TC建立链接,然后使用round robin模式挑选TC为它服务,比如说,先在TC 1创建事务txn1,下一次就在TC 2那创建事务txn2。

因此,理论上集群的每个TC造成的负载都是几乎相同的。因此我们可以用TC的个数来作为bundle的负载单位

broker负载度量

还有一个优先级的问题。比如说,broker1加载了所有TC,但是因为没加载什么业务流量,导致CPU负载(资源使用率,或者说scores)比较低,但是broker2、broker3一个TC都没加载,反而因为加载了大部分流量导致CPU负载比较高。
那么我们在分配TC的时候,应不应该把TC切换到broker2、broker3身上?
应该。因为我们可以先保证把TC均摊到三个broker身上,然后再使用原来的动态负载均衡算法把业务流量均衡好就行。

目前的负载均衡算法还使用BrokerData来对Broker本身的负载进行度量,也就是根据CPU负载等资源使用率来判定低载broker
因此我们在对TC进行负载均衡时,也需要更新broker负载的度量标准,新标准也很简单:TC的个数

至此,针对TC的动态负载均衡算法的框架已经搭好了,具体的实现算法就各显神通了。
参考AvgShedder的实现,下面举个例子:
对所有broker承载的TC个数进行统计排序得到一个queue,假设根据承载的TC个数对broker 进行编号,编号为broker1 ~ broker N,broker1承载最多的TC,broker N承载最少的TC。
计算broker1比broker2的TC个数差值M,则如果broker 1上面能找到满足下面条件的bundle:

  • 包含transaction_coordinator_assign-partition-${TC ID}分区的个数小于等于M
    那么就可以将该bundle切换到broker N上面。

http://www.niftyadmin.cn/n/389375.html

相关文章

SAP-QM-物料主数据-质量管理视图字段解析

过账到质检库存:要勾选,否则收货后库存不进入质检库存HU检验:收货到启用HU管理的库位时产生检验批,例如某个成品物料是收货到C002库位,该库位启用了HU管理,那么此处要勾选。但是如果勾选了,却收…

Optional类详解及使用方法示例

Optional类是java8中引入的一个非常有用的类,它可以用来解决空指针异常带来的不便。这个类可以将对象包装为一个Optional对象,如果该对象为空,则可以使用一些默认值或者执行一些默认操作。Optional 是 Java 实现函数式编程的强劲一步&#xf…

推进开源法律知识普及|2023开放原子全球开源峰会开源法律与合规分论坛即将启幕

随着开源在推动创新、促进协作方面的作用日益凸显,开源领域的法律与合规问题日益受到关注。 6月11日,开放原子全球开源峰会开源法律与合规分论坛将在北京经济开发区国家信创园召开,论坛以“开源知识产权的深度现实与广阔未来”为主题&#x…

大湾区C++模拟题

大湾区信息学创新大赛模拟题 一、单项选择题(15题共30分) 1.计算机的运算速度取决于给定的时间内,它的处理器所能处理的数据量。处理器一次能处理的数据量叫字长。已知64位奔腾处理器一次能处理64个信息,相当于( A …

OpenMMLab-AI实战营第二期——2.人体关键点检测与MMPose

文章目录 1. 人体姿态估计的介绍和应用2-1. 2D姿态估计概述2.1 任务描述2.2 基于回归2.3 基于热力图2.3.1 从数据标注生成热力图(高斯函数)2.3.2 使用热力图训练模型2.3.3 从热力图还原关键点 2.4 自顶向下2.5 自底向上2.6 单阶段方法 2-2. 2D姿态估计详…

笔记本电脑无法正常启动怎么办?

随着计算机技术的发展,笔记本电脑在性能上已经不比台式机落后,并且因其便于携带的优势,受到广大用户的喜爱。那么,在笔记本电脑无法正常启动时,我们该怎么办呢? 笔记本电脑无法正常启动的原因 笔记本电脑无…

activiti启动流程实例

/*** 启动流程实例*/Testpublic void testStartProcess(){ // 1、创建ProcessEngineProcessEngine processEngine ProcessEngines.getDefaultProcessEngine(); // 2、获取RunTimeServiceRuntimeService runtimeService processEngine.getRuntimeService(); // …

5个编写技巧,有效提高单元测试实践

1. 什么是单元测试 “在计算机编程中,单元测试又称为模块测试,是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最…