当前位置: 首页 > news >正文

Kafka 负载均衡挑战及解决思路

本文转载自 Agoda Engineering,介绍了在实际应用中,如何应对 Kafka 负载均衡所遇到的各种挑战,并提出相应的解决思路。本文简要阐述了 Kafka 的并行性机制、常用的分区策略以及在实际操作中遇到的异构硬件、不均匀工作负载等问题。通过深入分析这些挑战,并提供具体的解决方案,本文旨在帮助读者更好地理解和应用 Kafka 的负载均衡技术,从而提高系统的整体性能和稳定性。

以下大部分内容翻译自原文 how-we-solve-load-balancing-challenges-in-apache-kafka,并已获得原作者同意。

思维导图

Kafka 负载均衡解决方案

Kafka 并行性

Kafka 通过分区来实现并行性,如下图所示,生产者(Producer)产生的消息会按照一定的分区策略分配到多个分区(Partition)中,消费组中的每个消费者会分别负责消费其中的若干个分区。

Kafka 分区演示

分区策略:

  • 轮询(Round Robin):默认情况下,Kafka 使用轮询策略将消息均匀地分配到所有分区。
  • 哈希(Key Hashing):如果消息有分区键,Kafka 会对键进行哈希计算,将消息分配到特定的分区。
  • 自定义分区策略:开发者可以实现自定义的分区器(Partitioner)逻辑,以满足特定需求。

如果要使用轮询或者哈希策略来达到“负载均衡”的目的,那么需要满足以下 2 个假设:

  1. 消费者拥有相同的处理能力,
  2. 消息的工作量相等。

然而,在实践中,这些假设往往不成立。

现实挑战

1. 异构硬件

不同代的服务器硬件性能不同,导致处理速率存在差异。例如,使用不同代硬件进行处理的基准显示性能存在显着差异:

不同服务器处理速率差异举例

2. 每条 Kafka 消息的工作负载不均匀

下图显示了在一个时间窗口内到达的 12 条消息。在这里,生产者向该主题中的六个分区中的每一个发布两条消息。因此,每个 worker 消耗来自 2 个分区的数据,这意味着每个 worker 需要处理 4 条消息。

使用循环分区器和循环分配器来分发消息的先前供应系统的演示。每个 worker 都分配有相同数量的消息。

不同的消息可能需要不同的处理步骤集。例如,处理消息可能涉及调用第三方 HTTP 端点,并且不同的响应大小或延迟可能会影响处理速率。此外,对于涉及数据库操作的应用程序,其数据库查询的延迟可能会根据查询参数而波动,从而导致处理速率发生变化。

3. 过度配置问题

由于工作负载和处理效率不同,为了达到系统吞吐量的需求,可能会出现过度配置问题,从而导致资源浪费。

假设我们的高吞吐量和低吞吐量的处理速率分别为 20 msg/s 和 10 msg/s(根据表 1 中的数据进行简化)。使用两个较快的处理器和一个较慢的处理器,我们预计总容量为 20+20+10 = 50 条消息/秒。但是,当保持消息的循环分配时,我们无法达到此容量。下图显示了如果流量持续达到每秒 50 条消息时会发生什么情况。

如果传入流量保持在 50 条消息/秒,则慢速处理器无法处理总体消息 1/3 的负载,从而导致累积延迟。为了避免高延迟,向该系统添加了额外的资源以维持处理。

从这个例子中我们可以看到,我们的处理器服务一次最多只能接受 30 条消息,以防止滞后并确保及时传递更新。

在这种情况下,要实际每秒处理 50 条消息,我们必须总共扩展到 5 台机器,以保证及时处理所有消息。由于这种不适当的分配逻辑(66.7%的过度配置),我们会向该系统过度配置额外的两台机器。

为了每秒处理 50 条消息,我们需要扩展到五台机器以确保及时处理所有消息。由于这种不适当的分配逻辑(66.7% 的过度配置),这会导致向该系统过度配置两台额外的机器。

静态解决方案

1. 在相同的 Pod(机器)上部署

考虑控制服务部署中使用的硬件类型以缓解问题。如果您在虚拟机上部署服务并拥有充足的资源和性能相同的硬件,则此方法是可行的。

然而,由于成本效益和灵活性下降,在私有云环境中通常不建议采用这种策略,主要是因为同时升级所有现有硬件可能具有挑战性。如果它非常适合您的情况,则可以使用Kubernetes 关联性将 Pod 分配给某些类型的节点。

2. 加权负载均衡

如果容量是可预测的并且大部分时间保持静态,则为不同的消费者分配不同的权重可以帮助最大限度地利用可用资源。例如,在为表现较好的消费者赋予更高的权重后,我们可以将更多流量路由给这些消费者。

动态解决方案

虽然我们可以估计消息的容量和工作负载来设计静态规则来确定加权负载平衡策略,但由于以下几个因素,这种方法在实际生产环境中可能并不总是可行:

  • 消息的工作负载并不统一,这使得估计机器容量变得困难。
  • 依赖关系(例如网络和第三方连接)不稳定,有时会导致实际处理中的容量发生变化。
  • 该系统经常添加新功能,增加额外的维护工作以保持权重更新。

为了解决这些问题,我们可以动态监控每个分区中的当前滞后并根据当前流量状况做出相应响应。

有 2 种思路:

  1. 生产者角度:使用自定义算法根据滞后的消息数量来确定每个分区的流量,这种生产者称为滞后感知生产者(Lag-aware Producer)。
  2. 消费者角度:这些消费者旨在监控当前滞后的消息数量,并可以在必要时取消订阅以触发负载重新平衡。通常,可以采用自定义的重新平衡策略来调整分区分配。这种消费者称为滞后感知消费者(Lag-aware Comsumer)。

1. 从生产者角度出发

如此图所示,生产者可以使用自定义算法根据滞后确定每个分区的流量。为了减少对 Kafka 代理的调用次数,系统可以维护一个内部延迟缓存,而不是在发布每条消息之前调用 Kafka 代理。

在此示例中,分区 4 和 6 的延迟比其他分区高得多。应减少从内部生产者发送到这些分区的流量。

使用滞后数据,定制的算法被设计为向经历高滞后的分区发布更少的流量,向低滞后的分区发布更多流量,以平衡每个分区上的工作负载。当滞后平衡且稳定时,此方法应确保消息的均匀分布。

不适用情况:

  1. 纯消费者应用程序:您的应用程序不控制消息生成。
  2. **多个消费者组:**当生成的消息被多个消费者组消费时,生产者可能会为其他消费者组产生不必要的倾斜负载,因为滞后只是特定于一个消费者组的信息。

相同队列长度算法

该算法将每个分区滞后视为处理的队列大小。获取滞后信息后,它会发布适当数量的消息以填充短队列。此方法更适合由于异构硬件而导致的倾斜滞后分布,其中高性能 Pod(机器)在大多数情况下能够更快地处理。

相同队列长度算法的演示。最初,不同队列的长度不同。该算法尝试生成不同数量的消息,以在所有队列中实现相同的队列长度。这里,队列长度和 Kafka lag 是同一个概念,代表尚未处理的消息数量

异常值检测算法

该算法利用统计方法来确定所有分区的上离群值,并暂时停止那些慢速离群值的发布过程。在原文章中,针对 Agoda 的特定需求,他们提出了 IQR(四分位距)和 STD(标准差)异常值检测算法。算法流程图如下所示。

异常值检查算法流程

  • 慢速分区:(已关闭)由于存在延迟,这些分区的消息生成已停止。
  • 好的分区:(打开)照常发布并均匀分发到所有好的分区。
  • OK 分区:(观察/半开放)为了提高性能不佳的机器的性能,当系统尝试将慢速分区提升为良好分区时,会添加一个观察期。通过仅生成一小部分消息并进行观察,可以将该观察阶段优化为“半开放”状态。当滞后获取间隔相对较长时,半开放是有益的,因为它可以防止消费者延迟等待传入消息而更新的滞后数据尚未查询的情况。

2. 从消费者角度出发

这里 Adoga 提出的思路是:遇到高延迟的实例可以主动取消订阅主题以触发重新平衡。在重新平衡期间,可以使用自定义的分配器来平衡所有消费者实例之间的分区。

触发重新平衡的成本非常昂贵,因为急切的重新平衡会停止消费者组中的所有处理。Kafka 2.4中引入的增量协作再平衡协议已经最大限度地减少了性能影响,允许更频繁的再平衡以更好地分配每个分区上的负载。

为了增强重新分配的灵活性,分区的数量应该大于 worker 的数量。这一比率应根据应用程序而有所不同,并假设一个工作线程至少可以处理来自一个分区的负载以避免饥饿。

在此示例中,工作程序 3 在速度较慢的硬件上运行,导致分区 5 和 6 出现更高的延迟。因此,工作程序 3 可能会主动取消订阅主题以触发重新平衡并更有效地重新分配分区。在此示例中,应实现自定义分配器以根据机器指标和滞后信息重新分配分区。

总结

本文从 Kafka 并行性的一般实现出发,探讨了 Kafka 实现负载均衡在现实实践中可能遇到的各种挑战,并从静态调整和动态调整两个方面给出了解决思路,特别注重讨论了动态调整策略,并分别从生产者和消费者的角度提出了解决方案。

总之,通过在 Kafka 中实现负载均衡,可以有效地将工作负载分配到可用资源之间,从而显著提高服务性能。具体的算法和策略需要根据实际情况进行选择和调整。

相关文章:

Kafka 负载均衡挑战及解决思路

本文转载自 Agoda Engineering,介绍了在实际应用中,如何应对 Kafka 负载均衡所遇到的各种挑战,并提出相应的解决思路。本文简要阐述了 Kafka 的并行性机制、常用的分区策略以及在实际操作中遇到的异构硬件、不均匀工作负载等问题。通过深入分…...

【Java面试】二十一、JVM篇(中):垃圾回收相关

文章目录 1、类加载器1.1 什么是类加载器1.2 什么是双亲委派机制 2、类装载的执行过程(类的生命周期)3、对象什么时候可以被垃圾回收器处理4、JVM垃圾回收算法4.1 标记清除算法4.2 标记整理算法4.3 复制算法 5、分代收集算法5.1 MinorGC、Mixed GC、Full…...

深入理解预处理

1.预定义符号 C语言设置了⼀些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。 __FILE__ //进⾏编译的源⽂件 __LINE__ //⽂件当前的⾏号 __DATE__ //⽂件被编译的⽇期 __TIME__ //⽂件被编译的时间 __STDC__ //如果编译器遵循ANSI C&…...

DSP28335:定时器

1.定时器介绍 1.1 定时器工作原理 TMS320F28335的CPU Time有三个,分别为Timer0,Timer1,Timer2,其中Timer2是为操作系统DSP/BIOS保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分…...

系统架构理解

一、统一提前查好所有数据后续逻辑用到啥取啥,还是等用到对应数据的时候再查 1、用到啥查啥: 优势:减少依赖调用次数,减轻服务器压力;代码逻辑清晰,没有太多分支判断 劣势:无法避免串行调用&am…...

uni-app页面的跳转三种方式,功能作用有什么区别?

一、三种方式的作用 1、uni.reLaunch 作用是关闭所有页面,然后打开新的页面 类似于重新启动应用,打开的页面栈会被清空,只显示新打开的页面。使用uni.reLaunch方法可以实现整个应用的重定向 uni.reLaunch({url: /pages/login/login }) 2、…...

React 通信:深层传递(Props、Context、Children Jsx)

在之前的文章 探讨:围绕 props 阐述 React 通信 中总结了关于“父子”组件传值,但是当需要在组件树中深层传递参数以及需要在组件间复用相同的参数时,传递 props 就会变得很麻烦。 实际案例: 下述展示有两种状态:① 详…...

《Windows API每日一练》5.1 键盘基础

本节我们讲述关于键盘的一些基础知识。当我们按下一个键盘按键时,会产生一个键盘按键消息。这一点你能确定吗?假如是一个菜单快捷键消息,或者是一个子窗口控件消息呢?这就超出了本节讨论的范围,我们将在菜单和子窗口控…...

Class.forName()方法总结

Class.forName()方法总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!Class.forName()方法是Java反射机制中的一个重要方法,它用于动态加载类并返…...

Python | Leetcode Python题解之第168题Excel表列名称

题目: 题解: class Solution:def convertToTitle(self, columnNumber: int) -> str:ans list()while columnNumber > 0:columnNumber - 1ans.append(chr(columnNumber % 26 ord("A")))columnNumber // 26return "".join(an…...

【ARMv8/ARMv9 硬件加速系列 3.5.2 -- SVE 向量寄存器 有多少位数?】

文章目录 SVE 向量寄存器SVE 向量寄存器大小SVE 可伸缩性的好处SVE 寄存器长度示例SVE 向量寄存器 在 ARMv9 架构中,包括其 Scalable Vector Extension (SVE) 和 Scalable Vector Extension 2 (SVE2) 的增强,向量寄存器(通常称为 Z 寄存器)的大小设计为可伸缩的,以便在不…...

Vulkan入门系列2- 绘制三角形(未完待续)

概述: Vulkan的学习曲线是比较陡峭的,学习Vulkan刚开始像是在爬一个陡坡,等上了这个陡坡之后,后面学习曲线就相对比较平缓了。那么在Vulkan中绘制一个三角形,就相当于是在爬这样一个陡坡,因为绘制三角形需…...

企业UDP文件传输工具测速的方式(下)

在前一篇文章中,我们深入讨论了UDP传输的基本概念和镭速UDP文件传输工具如何使用命令行快速进行速度测试。现在,让我们进一步探索更为高级和灵活的方法,即通过整合镭速UDP的动态或静态库来实现网络速度的测量,以及如何利用这一过程…...

Artalk-CORS,跨域拦截问题

今天重新部署Artalk之后,遇到了CORS——跨域拦截的问题,卡了好一会记录一下。 起因 重新部署之后,浏览器一直提示CORS,之前在其他项目也遇到过类似的问题,原因就在于跨域问题。...

SSL证书怎样配置部署更安全?

在互联网上,SSL证书是用于加密网站与用户之间传输的数据的一种数字证书。它通过建立安全的连接,确保网站的身份和保护用户的隐私,是网站安全的重要组成部分。然而,要想让SSL证书发挥最大的作用,除了检查证书是否过期外…...

M1失效后,哪个是观察A股的关键新指标?

M1失效后,哪个是观察A股的关键新指标? 央地支出增速差(地方-中央支出增速的差值)或许是解释沪深300定价更有效的前瞻指标。该数值扩张,则有利于大盘指数,反之亦然,该指标从2017年至今对大盘指数…...

springboot集成积木报表,怎么将平台用户信息传递到积木报表

springboot集成积木报表后怎么将平台用户信息传递到积木报表 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选新的模块 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选 官网有详细介绍怎么集成进去的&…...

Spring Bean详解

Spring Bean作用域 默认情况下,所有的 Spring Bean 都是单例的,也就是说在整个 Spring 应用中, Bean 的实例只有一个 如果我们需要创建多个实例的对象,那么应该将 Bean 的 scope 属性定义为 prototype,如果 Spring 需…...

前端根据环境变量配置网页的title和favicon

前端根据环境变量配置网页的title和favicon 前言流程步骤一、设置environment文件二、在入口文件中配置三、删除index.html中的title和 icon link四、使用对应的打包命令进行部署 注意事项一、angular中,需要在angular.json添加favicon.ico额外的构建 前言 有些项目…...

服务器负载均衡

什么是服务器负载 1. 常见理解的平均负载 每次发现系统变慢时,我们通常做的第一件事,就是执行 top 或者 uptime 命令,来了解系统的负载情况。比如下列情况 [rootkube-node1 ~]# uptime09:44:37 up 74 days, 11:53, 1 user, load average:…...

如何设置Excel单元格下拉列表

如何设置Excel单元格下拉列表 在Excel中设置单元格下拉列表可以提高数据输入的准确性和效率。以下是创建下拉列表的步骤: 使用数据验证设置下拉列表: 1. 选择单元格: 选择你想要设置下拉列表的单元格或单元格区域。 2. 打开数据验证&…...

红队内网攻防渗透:内网渗透之Linux内网权限提升技术:LXDDockerRbash限制型bash

红队内网攻防渗透 1. 内网权限提升技术1.1 Linux系统提权-普通用户-LXD容器1.2 Linux系统提权-普通用户-Docker容器1.3 权限在docker里面1.4 Linux系统提权-普通用户-Rbash限制型bash1. 内网权限提升技术 利用参考 https://gtfobins.github.io/LXD、LXC 和 Docker 是三种不同…...

【笔记】复制Edge的网址粘贴后自动变成中文标题超链接

问题 1、从edge复制的网址粘贴直接显示网页内容名称而不是网址url。 2、复制任何网址粘贴到CSDN里面粘贴时直接转换成标题超链接(很讨厌的功能习惯)。 而如上两种问题不是互相影响的,就算设置了Edge的粘贴方式,复制到CSDN的文章…...

HTML5和CSS3总结

HTML5 HTML5是最新的HTML标准,它的主要目标是提供所有内容而不需要任何像flash,silverlight等的额外插件,这些内容来自动画、视频、富GUI等。HTML5是万维网联盟(W3C)和网络超文本应用技术工作组(WHATWG&am…...

探索数据分析无限潜能:vividime Desktop助力企业智能决策

在数字化浪潮席卷全球的今天,数据已经成为企业最宝贵的资产之一。通过对海量数据的深度挖掘和分析,企业能够洞察市场趋势、优化运营流程、提升用户体验,从而在激烈的市场竞争中脱颖而出。永洪科技的vividime Desktop作为一款功能强大、操作简…...

gitee添加别人的仓库后,在该仓库里添加文件夹/文件

一、在指定分支里添加文件夹(如果库主没有创建分支,自己还要先创建分支) eg:以在一个项目里添加视图文件为例,用Echarts分支在usr/views目录下添加Echarts文件夹,usr/views/Echarts目录下添加index.vue 1.切换为本地仓…...

[笔记] CCD相机测距相关的一些基础知识

1.35mm胶片相机等效焦距 https://zhuanlan.zhihu.com/p/419616729 拿到摄像头拍摄的数码照片后,我们会看到这样的信息: 这里显示出了两个焦距:一个是实际焦距:5mm,一个是等效焦距:25mm。 实际焦距很容易…...

【ai】tx2-nx :查看cuda和cudnn

JetSon-nano板卡_从sd卡烧录到tensorRT部署_一条龙 查看 cuda 版本 nvidia@tx2-nx:~$ nvcc -v nvcc fatal : No input files specified; use option --help for more information nvidia@tx2-nx:~$ nvcc -V nvcc: NVIDIA Cuda compiler driver Copyright © 2005-2021 NV…...

webpack 中 require.context() 的用法

一、什么是 require.context It allows you to pass in a directory to search, a flag indicating whether subdirectories should be searched too, and a regular expression to match files against. – webpack 官方说明 一个 webpack 的 api ,通过该函数可以获…...

漫画 | “本世纪最重要的一篇硕士论文诞生了!”

后记:本来想写信息论的,开了一个头以后,不知道怎么就拐到布尔代数那里去了,还好,最终还是和香农扯上了关系。 看过《编码》的同学对中间有一段可能有点熟悉,这一段是改编自《编码》第十章中的内容&#xff…...

贵州做网站/百度广告点击软件源码

extjs panel layoutconfig属性 分类: extjs2012-06-23 23:27 3790人阅读 评论(0) 收藏 举报extjslayouthtmlobjectgo目录(?)[] layoutConfig: Object 这是一个包含指定布局详细属性的对象 (与layout 配置值结合使用)。 对于...这是一个包含指定布局详细属性的对象 …...

wordpress发帖软件/长沙的seo网络公司

import easygui easygui.msgbox("This is a message!", title"simple gui")...

延边app网站开发/全网营销推广方案

舞弊三角理论,企业舞弊的产生是由压力、机会和自我合理化(借口)三要素组成。舞弊要发生,三要素缺一不可。...

怎么给网站做seo优化/百度推广有哪些推广方式

i5 10500H 为 6 核 12 线程,cpu频率2.5GHz动态频 4.5GHz 选i5 10500h还是i5-1135G7 这些点重要 看过你就懂了 http://www.adiannao.cn/dy i5-1135G7 4 核 8 线程,主频 2.4GHz,睿频 4.2GHz,8MB 三级缓存。跑分方面,i5-…...

网站制作公司哪家好/深圳外贸推广公司

什么是协程, 为什么要用协程 协程是用户态的线程,是实现多任务的一种方式, 为什么不用多线程实现多任务而是用协程呢? 因为协程的切换是在代码中逻辑切换的, 协程任务的切换不需要到cpu内核中进行切换, 因…...

网站搭建有分谷歌/百度官网网页版

...