我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Pulsar负载均衡原理及优化方案详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Pulsar负载均衡原理及优化方案详解

前言

前段时间我们在升级 Pulsar 版本的时候发现升级后最后一个节点始终没有流量。

虽然对业务使用没有任何影响,但负载不均会导致资源的浪费。

和同事沟通后得知之前的升级也会出现这样的情况,最终还是人工调用 Pulsar 的 admin API 完成的负载均衡。

这个问题我尝试在 Google 和 Pulsar 社区都没有找到类似的,不知道是大家都没碰到还是很少升级集群。

我之前所在的公司就是一个版本走到黑?

Pulsar 负载均衡原理

当一个集群可以水平扩展后负载均衡就显得非常重要,根本目的是为了让每个提供服务的节点都能均匀的处理请求,不然扩容就没有意义了。

在分析这个问题的原因之前我们先看看 Pulsar 负载均衡的实现方案。

# Enable load balancer
loadBalancerEnabled=true

我们可以通过这个 broker 的这个配置来控制负载均衡器的开关,默认是打开。

但具体使用哪个实现类来作为负载均衡器也可以在配置文件中指定:

# Name of load manager to use
loadManagerClassName=org.apache.pulsar.broker.loadbalance.impl.ModularLoadManagerImpl

默认使用的是 ModularLoadManagerImpl

    static LoadManager create(final PulsarService pulsar) {
        try {
            final ServiceConfiguration conf = pulsar.getConfiguration();
            // Assume there is a constructor with one argument of PulsarService.
            final Object loadManagerInstance = Reflections.createInstance(conf.getLoadManagerClassName(),
                    Thread.currentThread().getContextClassLoader());
            if (loadManagerInstance instanceof LoadManager) {
                final LoadManager casted = (LoadManager) loadManagerInstance;
                casted.initialize(pulsar);
                return casted;
            } else if (loadManagerInstance instanceof ModularLoadManager) {
                final LoadManager casted = new ModularLoadManagerWrapper((ModularLoadManager) loadManagerInstance);
                casted.initialize(pulsar);
                return casted;
            }
        } catch (Exception e) {
            LOG.warn("Error when trying to create load manager: ", e);
        }
        // If we failed to create a load manager, default to SimpleLoadManagerImpl.
        return new SimpleLoadManagerImpl(pulsar);
    }

broker 启动时会从配置文件中读取配置进行加载,如果加载失败会使用 SimpleLoadManagerImpl 作为兜底策略。

当 broker 是一个集群时,只有 leader 节点的 broker 才会执行负载均衡器的逻辑。

Leader 选举是通过 Zookeeper 实现的。

默然情况下成为 Leader 节点的 broker 会每分钟读取各个 broker 的数据来判断是否有节点负载过高需要做重平衡。

而是否重平衡的判断依据是由 org.apache.pulsar.broker.loadbalance.LoadSheddingStrategy 接口提供的,它其实只有一个函数:

public interface LoadSheddingStrategy {
    
    Multimap<String, String> findBundlesForUnloading(LoadData loadData, ServiceConfiguration conf);
}

根据所有 broker 的负载信息计算出一个需要被 unload 的 broker 以及 bundle。

这里解释下 unload 和 bundle 的概念:

  • bundle 是一批 topic 的抽象,将 bundlebroker 进行关联后客户端才能知道应当连接哪个 broker;而不是直接将 topic 与 broker 绑定,这样才能实现海量 topic 的管理。
  • unload 则是将已经与 broker 绑定的 bundle 手动解绑,从而触发负载均衡器选择一台合适的 broker 重新进行绑定;通常是整个集群负载不均的时候触发。

ThresholdShedder 原理

LoadSheddingStrategy 接口目前有三个实现,这里以官方默认的 ThresholdShedder 为例:

它的实现算法是根据带宽、内存、流量等各个指标的权重算出每个节点的负载值,之后为整个集群计算出一个平均负载值。

# 阈值
loadBalancerBrokerThresholdShedderPercentage=10

当集群中有某个节点的负载值超过平均负载值达到一定程度(可配置的阈值)时,就会触发 unload,以上图为例就会将最左边节点中红色部分的 bundle 卸载掉,然后再重新计算一个合适的 broker 进行绑定。

阈值存在的目的是为了避免频繁的 unload,从而影响客户端的连接。

问题原因

当某些 topic 的流量突然爆增的时候这种负载策略确实可以处理的很好,但在我们集群升级的情况就不一定了。

假设我这里有三个节点:

  • broker0
  • broker1
  • broker2

集群升级时会从 broker2->0 进行镜像替换重启,假设在升级前每个 broker 的负载值都是 10。

  • 重启 broker2 时,它所绑定的 bundle 被 broker0/1 接管。
  • 升级 broker1 时,它所绑定的 bundle 又被 broker0/2 接管。
  • 最后升级 broker0, 它所绑定的 bundle 会被broker1/2 接管。

只要在这之后没有发生流量激增到触发负载的阈值,那么当前的负载情况就会一直保留下去,也就是 broker0 会一直没有流量。

经过我反复测试,现象也确实如此。

./pulsar-perf monitor-brokers --connect-string pulsar-test-zookeeper:2181

通过这个工具也可以查看各个节点的负载情况

优化方案

这种场景是当前 ThresholdShedder 所没有考虑到的,于是我在我们所使用的版本 2.10.3 的基础上做了简单的优化:

  • 当原有逻辑走完之后也没有获取需要需要卸载的 bundle,同时也存在一个负载极低的 broker 时(emptyBundle),再触发一次 bundle 查询。
  • 按照 broker 所绑定的数量排序,选择一个数量最多的 broker 的 第一个 bundle 进行卸载。

修改后打包发布,再走一遍升级流程后整个集群负载就是均衡的了。

但其实这个方案并不严谨,第二步选择的重点是筛选出负载最高的集群中负载最高的 bundle;这里只是简单的根据数量来判断,并不够准确。

正当我准备持续优化时,鬼使神差的我想看看 master 上有人修复这个问题没,结果一看还真有人修复了;只是还没正式发版。

github.com/apache/puls…

整体思路是类似的,只是筛选负载需要卸载 bundle 时是根据 bundle 自身的流量来的,这样会更加精准。

总结

不过看社区的进度等这个优化最终能用还不知道得多久,于是我们就自己参考这个思路在管理台做了类似的功能,当升级后出现负载不均衡时人工触发一个逻辑:

  • 系统根据各个节点的负载情况计算出一个负载最高的节点和 bundle 在页面上展示。
  • 人工二次确认是否要卸载,确认无误后进行卸载。

本质上只是将上述优化的自动负载流程改为人工处理了,经过测试效果是一样的。

Pulsar 整个项目其实非常庞大,有着几十上百个模块,哪怕每次我只改动一行代码准备发布测试时都得经过漫长的编译+ Docker镜像打包+上传私 服这些流程,通常需要1~2个小时;但总的来说收获还是很大的,最近也在提一些 issue 和 PR,希望后面能更深入的参与进社区。

以上就是Pulsar负载均衡原理及优化方案详解的详细内容,更多关于Pulsar负载均衡的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Pulsar负载均衡原理及优化方案详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Pulsar负载均衡原理及优化方案详解

这篇文章主要为大家介绍了Pulsar负载均衡原理及优化方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-07

聊一聊Pulsar负载均衡原理及优化

当一个集群可以水平扩展后负载均衡就显得非常重要,根本目的是为了让每个提供服务的节点都能均匀的处理请求,不然扩容就没有意义了。

负载均衡原理最全详解

总的来说,一般是LVS做4层负载,Nginx或者Haproxy做7层负载,性能上LVS>HA>Nginx,功能性和便利性上Nginx>HA>LVS。

Nginx负载均衡实践与优化方案

摘要:本文主要介绍了Nginx负载均衡的实践与优化方案,通过具体的代码示例展示了如何配置Nginx来实现负载均衡,并对常见的负载均衡算法进行了解析。同时,还介绍了一些优化策略,如缓存策略、压缩策略等,以提高系统的性能和稳定性。引言在现代we
2023-10-21

负载均衡原理详解(万字图文总结)

负载均衡(Load Balancing),是指将流量、或计算,负载均匀分配到多个服务器、或资源上。比如:在处理大量的用户请求时,负载均衡器可以分配流量到多个 Web 服务器上,以保证应用的高可用性和响应速度。

负载均衡的原理及使用方法是什么

负载均衡是一种用于分配网络请求负载的技术,它通过将网络请求分配给多个后端服务器来提高系统的性能、可靠性和可扩展性。负载均衡的原理是基于以下几个方面:1. 请求调度:负载均衡器接收到来自客户端的请求后,会根据一定的算法(如轮询、最小连接数、最
2023-09-01

DNS服务器负载均衡配置的原理及优缺点

本篇内容介绍了“DNS服务器负载均衡配置的原理及优缺点”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!负载均衡技术能够平衡服务器集群中所有的服
2023-06-10

Spring Cloud 远程接口调用OpenFeign负载均衡实现原理详解

容器在启动过程中会找到所有@FeignClient的接口类,然后将这些类注册为容器Bean,而每一个Feign客户端对应的是FactoryBean对象FeignClientFactoryBean。

阿里云服务器配置负载均衡详解及调节方法

随着互联网的发展,网站和应用程序的需求量越来越大,因此,如何有效地进行服务器负载均衡成为了一个重要的问题。本文将详细介绍如何在阿里云服务器上配置负载均衡,并提供具体的调节方法。一、什么是负载均衡负载均衡是一种技术,通过在多个服务器之间分配请求,使得每个服务器都能均衡地处理负载,从而提高系统的处理能力和服务质量。负
阿里云服务器配置负载均衡详解及调节方法
2023-12-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录