如何为Kafka集群选择合适的Topic/Partitions数量

2023-11-15

这是许多kafka使用者经常会问到的一个问题。本文的目的是介绍与本问题相关的一些重要决策因素,并提供一些简单的计算公式。

越多的分区可以提供更高的吞吐量

首先我们需要明白以下事实:在kafka中,单个patitionkafka并行操作的最小单元。在producerbroker端,向每一个分区写入数据是可以完全并行化的,此时,可以通过加大硬件资源的利用率来提升系统的吞吐量,例如对数据进行压缩。在consumer段,kafka只允许单个partition的数据被一个consumer线程消费。因此,在consumer端,每一个Consumer Group内部的consumer并行度完全依赖于被消费的分区数量。综上所述,通常情况下,在一个Kafka集群中,partition的数量越多,意味着可以到达的吞吐量越大。

我们可以粗略地通过吞吐量来计算kafka集群的分区数量。假设对于单个partitionproducer端的可达吞吐量为pConsumer端的可达吞吐量为c,期望的目标吞吐量为t,那么集群所需要的partition数量至少为max(t/p,t/c)。在producer端,单个分区的吞吐量大小会受到批量大小、数据压缩方法、 确认类型(同步/异步)、复制因子等配置参数的影响。经过测试,在producer端,单个partition的吞吐量通常是在10MB/s左右。在consumer端,单个partition的吞吐量依赖于consumer端每个消息的应用逻辑处理速度。因此,我们需要对consumer端的吞吐量进行测量。

虽然随着时间的推移,我们能够对分区的数量进行添加,但是对于基于Key来生成的这一类消息需要我们重点关注。当producer向kafka写入基于key的消息时,kafka通过keyhash值来确定消息需要写入哪个具体的分区。通过这样的方案,kafka能够确保相同key值的数据可以写入同一个partition。kafka的这一能力对于一部分应用是极为重要的,例如对于同一个key的所有消息,consumer需要按消息的顺序进行有序消费。如果partition的数量发生改变,那么上面的有序性保证将不复存在。为了避免上述情况发生,通常的解决办法是多分配一些分区,以满足未来的需求。通常情况下,我们需要根据未来1到2年的目标吞吐量来设计kafka的分区数量。

一开始,我们可以基于当前的业务吞吐量为kafka集群分配较小的broker数量,随着时间的推移,我们可以向集群中增加更多的broker,然后在线方式将适当比例的partition转移到新增加的broker中去。通过这样的方法,我们可以在满足各种应用场景(包括基于key消息的场景)的情况下,保持业务吞吐量的扩展性。

在设计分区数时,除了吞吐量,还有一些其他因素值得考虑。正如我们后面即将看到的,对于一些应用场景,集群拥有过的分区将会带来负面的影响。

越多的分区需要打开更多地文件句柄

kafkabroker中,每个分区都会对照着文件系统的一个目录。在kafka的数据日志文件目录中,每个日志数据段都会分配两个文件,一个索引文件和一个数据文件。当前版本的kafka,每个broker会为每个日志段文件打开一个index文件句柄和一个数据文件句柄。因此,随着partition的增多,需要底层操作系统配置更高的文件句柄数量限制。这更多的是一个配置问题。我们曾经见到过,在生产环境Kafka集群中,每个broker打开的文件句柄数量超过30,000

更多地分区会导致更高的不可用性

Kafka通过多副本复制技术,实现kafka集群的高可用和稳定性。每个partition都会有多个数据副本,每个副本分别存在于不同的broker。所有的数据副本中,有一个数据副本为Leader,其他的数据副本为follower。在kafka集群内部,所有的数据副本皆采用自动化的方式进行管理,并且确保所有的数据副本的数据皆保持同步状态。不论是producer端还是consumer端发往partition的请求,皆通过leader数据副本所在的broker进行处理。当broker发生故障时,对于leader数据副本在该broker的所有partition将会变得暂时不可用。Kafka将会自动在其他数据副本中选择出一个leader,用于接收客户端的请求。这个过程由kafka controller节点broker自动完成,主要是从Zookeeper读取和修改受影响partition的一些元数据信息。在当前的kafka版本实现中,对于zookeeper的所有操作都是由kafka controller来完成的(serially的方式)。

在通常情况下,当一个broker有计划地停止服务时,那么controller会在服务停止之前,将该broker上的所有leader一个个地移走。由于单个leader的移动时间大约只需要花费几毫秒,因此从客户层面看,有计划的服务停机只会导致系统在很小时间窗口中不可用。(注:在有计划地停机时,系统每一个时间窗口只会转移一个leader,其他leader皆处于可用状态。)

然而,当broker非计划地停止服务时(例如,kill -9方式),系统的不可用时间窗口将会与受影响的partition数量有关。假如,一个2节点的kafka集群中存在2000个partition,每个partition拥有2个数据副本。当其中一个broker非计划地宕机,所有1000个partition同时变得不可用。假设每一个partition恢复时间是5ms,那么1000个partition的恢复时间将会花费5秒钟。因此,在这种情况下,用户将会观察到系统存在5秒钟的不可用时间窗口。

更不幸的情况发生在宕机的broker恰好是controller节点时。在这种情况下,新leader节点的选举过程在controller节点恢复到新的broker之前不会启动。Controller节点的错误恢复将会自动地进行,但是新的controller节点需要从zookeeper中读取每一个partition的元数据信息用于初始化数据。例如,假设一个kafka集群存在10,000个partition,从zookeeper中恢复元数据时每个partition大约花费2ms,则controller的恢复将会增加约20秒的不可用时间窗口。

通常情况下,非计划的宕机事件发生的情况是很少的。如果系统可用性无法容忍这些少数情况的场景,我们最好是将每个brokerpartition数量限制在2,000到4,000,每个kafka集群中partition的数量限制在10,000以内。

越多的分区可能增加端对端的延迟

Kafka端对端延迟定义为producer端发布消息到consumer端接收消息所需要的时间。即consumer接收消息的时间减去producer发布消息的时间。Kafka只有在消息提交之后,才会将消息暴露给消费者。例如,消息在所有in-sync副本列表同步复制完成之后才暴露。因此,in-sync副本复制所花时间将是kafka端对端延迟的最主要部分。在默认情况下,每个broker从其他broker节点进行数据副本复制时,该broker节点只会为此工作分配一个线程,该线程需要完成该broker所有partition数据的复制。经验显示,将1000个partition从一个broker到另一个broker所带来的时间延迟约为20ms,这意味着端对端的延迟至少是20ms。这样的延迟对于一些实时应用需求来说显得过长。

注意,上述问题可以通过增大kafka集群来进行缓解。例如,将1000个分区leader放到一个broker节点和放到10个broker节点,他们之间的延迟是存在差异的。在10个broker节点的集群中,每个broker节点平均需要处理100个分区的数据复制。此时,端对端的延迟将会从原来的数十毫秒变为仅仅需要几毫秒。

根据经验,如果你十分关心消息延迟问题,限制每个broker节点的partition数量是一个很好的主意:对于bbroker节点和复制因子为rkafka集群,整个kafka集群的partition数量最好不超过100*b*r个,即单个partitionleader数量不超过100.

越多的partition意味着需要客户端需要更多的内存

在最新发布的0.8.2版本的kafka中,我们开发了一个更加高效的Java producer。新版producer拥有一个比较好的特征,他允许用户为待接入消息存储空间设置内存大小上限。在内部实现层面,producer按照每一个partition来缓存消息。在数据积累到一定大小或者足够的时间时,积累的消息将会从缓存中移除并发往broker节点。

如果partition的数量增加,消息将会在producer端按更多的partition进行积累。众多的partition所消耗的内存汇集起来,有可能会超过设置的内容大小限制。当这种情况发生时,producer必须通过消息堵塞或者丢失一些新消息的方式解决上述问题,但是这两种做法都不理想。为了避免这种情况发生,我们必须重新将produder的内存设置得更大一些。

根据经验,为了达到较好的吞吐量,我们必须在producer端为每个分区分配至少几十KB的内存,并且在分区数量显著增加时调整可以使用的内存数量。

类似的事情对于consumer端依然有效。Consumer端每次从kafka按每个分区取出一批消息进行消费。消费的分区数越多,需要的内存数量越大。尽管如此,上述方式主要运用于非实时的应用场景。

总结

通常情况下,kafka集群中越多的partition会带来越高的吞吐量。但是,我们必须意识到集群的partition总量过大或者单个broker节点partition过多,都会对系统的可用性和消息延迟带来潜在的影响。未来,我们计划对这些限制进行一些改进,让kafka在分区数量方面变得更加可扩展。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为Kafka集群选择合适的Topic/Partitions数量 的相关文章

  • CompletableFuture使用详解

    https blog csdn net admin123404 article details 111168902
  • c++11并发与多线程-王健伟-专题视频课程

    c 11并发与多线程 364人已学习 课程介绍 本课程 讲解的重点定位在c 11新标准中的多线程开发部分 同时 老师还会结合自己的经验把多线程的讲解进一步拓展到一个比较大的范畴 因为无论是c 11多线程开发还是各种其他的多线程开发实现方法
  • 【加载静态资源很慢】解决浏览器加载静态资源阻塞

    开门见山讲方法 增加浏览器的最大并发连接数 避免静态资源的加载请求排队而被其他请求阻塞 仅测试火狐浏览器可用 Chrome据我所知不支持此项配置 IE浏览器需要通过修改组策略 未测试 正文 存在问题 今天调试网页时 网页加载缓慢 一方面主要
  • 谈谈form-data请求格式

    最近一直都比较忙 坚持月月更新博客的计划不得中止了 今天好不容易抽出点时间来说说最近项目中遇到的一个问题 有关request post请求格式中的multipart form data格式 引言 最近在项目过程中遇到一个问题 相信大部分人都
  • 互斥和同步-读者/写者问题

    读者 写者问题 问题定义 存在一个多进程共享的数据区 该数据区可以是 一个文件或者一块内存或者一组寄存器 有些进程reader只读取该数据区中的数据 有些进程writer只往数据区写数据 满足条件 任意数量的读进程可以同时读该文件 一次只有
  • java 限流策略

    概要 在大数据量高并发访问时 经常会出现服务或接口面对暴涨的请求而不可用的情况 甚至引发连锁反映导致整个系统崩溃 此时你需要使用的技术手段之一就是限流 当请求达到一定的并发数或速率 就进行等待 排队 降级 拒绝服务等 在限流时 常见的两种算
  • Redisson分布式锁

    目录 一 分布式锁 1 分布式锁的设计原则 2 分布式锁的实现方案 二 Redisson 三 Redisson分布式锁 1 引入Redisson依赖 2 配置Redis 3 注入RedissonClient 4 使用RLock 总结 一 分
  • 实战Java高并发程序设计(第二版)-chp4锁

    多线程引用 需要维护并行数据结构间的一致性状态 需要为线程的切换和调度花费时间 参考 实战Java高并发程序设计 第二版 Unsafe类详解 java cas算法实现乐观锁 4 1 合理的锁性能 4 1 1 减少锁持有时间 原有的程序 对整
  • Qt基础之三十:百万级任务并发处理

    在实际的开发过程中 经常会遇到要处理大量任务场景 比如说压缩文件夹中的所有文件 对文件夹中的所有文件加密 上传文件夹中的所有文件到ftp等等 这里说百万级并不夸张 理论上文件夹中有任意多个文件都是可以的 本文以压缩文件夹中的100万张jpg
  • PyPy 安装

    目录 前言 1 下载 2 安装 2 1 安装包解压缩 2 2 添加路径至系统变量 3 cmd 调用 4 对比 Python 3 8的界面 总结 前言 提示 这里可以添加本文要记录的大概内容 听说 PyPy 的纯 Python 环境的运行速度
  • Python并发编程之线程池/进程池

    转载 http python jobbole com 87272 引言 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程 多进程代码 但是当项目达到一定的规模 频繁创建 销毁进程或者线程是
  • 合理配置线程池核心线程数(IO密集型和CPU密集型)

    1 代码查看服务器的核心数 要合理配置线程数首先要知道公司服务器是几核的 代码查看服务器核数 System out println Runtime getRuntime availableProcessors 2 合理线程数配置之CPU密集
  • 多线程结合sprongboot事务(完善)

    避坑指南 1 Async Transactional不能在同一个方法上注解使用 原因Spring实现AOP的方法则就是利用了动态代理机制 正因如此 才会导致某些情况下 Async和 Transactional不生效 比如下面的将事务事务控制
  • 【大数据】Flink 详解(二):核心篇 Ⅰ

    本系列包含 大数据 Flink 详解 一 基础篇 大数据 Flink 详解 二 核心篇 大数据 Flink 详解 三 核心篇 大数据 Flink 详解 四 核心篇 大数据 Flink 详解 五 核心篇 大数据 Flink 详解 六 源码篇
  • 处理高并发、高访问之Apache优化

    前言 项目100人同时访问 导致访问速度变慢 作为一个没有遇到过这种情况下的辕 在各种查阅资料后 先用删除日志更改日志输出的方法处理后 处理方法 修改Apache日志输出相关配置方法 暂时好缓 后来又出现变慢 在查阅各种博客后 发现一个处理
  • 【并发编程】CPU cache结构和缓存一致性(MESI协议)

    一 cache cpu cache已经发展到了三级缓存结构 基本上现在买的个人电脑都是L3结构 1 cache的意义 为什么需要CPU cache 因为CPU的频率太快了 快到主存跟不上 这样在处理器时钟周期内 CPU常常需要等待主存 浪费
  • 计算机操作系统-进程篇

    一 进程 进程 progress 是指计算机中已运行的程序 每个进程都有自己的地址空间 内存 寄存器和堆栈等资源 它们与其他进程相互隔离 互不干扰 进程是操作系统中最基本的资源分配单位 也是操作系统中最重要的概念之一 在操作系统中 进程是由
  • 多线程中sleep、yield、join的用法及sleep与wait区别

    Object中的wait notify notifyAll 可以用于线程间的通信 核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁 监视器 上的等待与唤醒 这三个方法是以锁 监视器 为中心的通信方法 除了它们之外
  • 简单的matlab分布式计算

    matlab的分布式计算可以理解为一台机器作为client 主控机 其他的机器分别作为计算的结点 要由client进行控制和操作 如果把单机上的 m文件直接放到client运行 是不会产生分布式计算的效果的 只相当于在主控机进行了计算 而其
  • 万文详解JUC(超详细)

    生命无罪 健康万岁 我是laity 我曾七次鄙视自己的灵魂 第一次 当它本可进取时 却故作谦卑 第二次 当它在空虚时 用爱欲来填充 第三次 在困难和容易之间 它选择了容易 第四次 它犯了错 却借由别人也会犯错来宽慰自己 第五次 它自由软弱

随机推荐

  • css实现表单验证

    在我们的日常业务中 表单验证是个很常见设计需求 像一些登录注册框 问卷调查也都需要用到表单验证 一般我们的实现思路都是JS监听input框的输入内容 判断用户输入内容 从而以此来决定下一步的操作
  • 13.6 Production State Awareness (PSA)

    1 Introduction UFS设备可以利用有关其生产状态的知识 相应地调整内部操作 例如 在设备焊接之前加载到存储设备中的内容可能被破坏 其概率高于regular模式 UFS设备可以在设备焊接前使用 Special 内部操作加载内容
  • qt界面论坛

    http www cnblogs com appsucc archive 2012 03 14 2395657 html
  • JAVA核心知识点--Maven引入org.apache.tools.zip

    可以看出 org apache tools zip 是 ant jar里面的 所以要引入org apache tools zip 直接maven引入ant即可
  • 基于SSM框架的家教中介平台系统的设计与实现(源码免费获取)

    技术架构 Java语言 MySQL数据库 SSM框架 功能简介 1 系统登录 系统登录成为了管理员访问系统的路口 设计了系统登录界面 包括管理员名 密码和验证码 然后对登录进来的管理员判断身份信息 判断其为管理员 还是普通用户 2 管理员管
  • logback 对特殊日志进行过滤

    工作中需要对 logback 的日志进行定制化过滤 此时一般有两种方法 logger 在 logback spring xml 中添加如下配置 可以关闭对应类的日志
  • Intellij安装scala插件详解

    参考博客 1 http wwwlouxuemingcom blog 163 com blog static 20974782201321953144457 2 http blog csdn net stark summer article
  • cvm云服务器的,cvm云服务器如何登录

    cvm 登录到 本地为 Windows 计算机 1 在本地 Windows 机器上 单击开始菜单 运行 输入 mstsc 命令 即可打开远程桌面连接对话框 2 在输入框输入 Windows 服务器的公网 IP 登录 云服务器控制台 可查看云
  • 牛客剑指offer之【JZ12 矩阵中的路径】

    哈喽 这次真的是好久不见呀 我回来啦 接下来的日子我会不断更新牛客上的剑指offer题解 为什么这么做呢 是因为博主刷题总是刷了忘忘了刷 一样的题目换种形式就要做好久 说到底还是对知识点的理解不够透彻 加之算法对一个即将找工作的大学生来说更
  • 【Pytorch with fastai】第 15 章 :深入探讨应用程序架构

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 计算机网络参考模型(OSI讲解)

    计算机网络参考模型 文章目录 计算机网络参考模型 一 什么是七层网络模型 二 每一层的功能与特点 三 osi模型和TCP IP模型的区别 四 数据封装和解封装的过程 1 封装与解封装过程 2 设备与层之间的关系 一 什么是七层网络模型 七层
  • 保护模式的分段

    一 分段的背景 在8086处理器诞生之前 内存寻址方式就是直接访问物理地址 8086处理器为了寻址1M的内存空间 把地址总线扩展到了20位 但是 一个尴尬的问题出现了 ALU的宽度只有16位 也就是说 ALU不能计算20位的地址 为了解决这
  • Less-11-12 【‘、“)】

    目录 第十一 十二关 1 在账号密码输入admin 查看成功效果 2 输入错误的账号密码 查看错误效果 3 找注入点 我们尝试在账户的输入框中加单引号 发现出现报错 4 加注释 查看页面是否恢复正常 可以看到页面成功执行了 证明当前网址存在
  • vscode搭建linux内核开发环境

    vscode在linux下搭建内核驱动开发环境 一 前言 Souce insight是一个阅读 开发linux内核驱动模块的好工具 但是Source insight是收费的软件 而且没有原生linux版本 要是想在纯linux环境下进行li
  • Unity3D RPG实现 3 —— 对话、任务系统

    目录 成果展示 对话系统 对话的存储数据结构 对话的UI面板设置 创建对话 任务的 NPC 实现对话控制器显示主对话窗口的内容 创建对话的选项内容 任务系统 创建任务 UI 面板 任务的存储数据结构 任务管理器与接受任务 任务控制相关脚本
  • Linux内核网络:实现与理论--介绍

    这本书主要涉及了Linux内核网络协议栈的实现和它背后的理论 你会在后续章节发现更深层次和更细节地针对网络子系统的分析和它的结构 我不会讨论和网络没有直接关系的话题内容 比如你在读内核里网络代码的时候会遇到锁 同步 SMP 原子操作等等 关
  • 2023年03月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

    C C 编程 1 8级 全部真题 点这里 第1题 数字字符求和 请编写一个程序实现以下功能 从一个字符串中 提取出所有的数字字符即0 9 并作为数求和 时间限制 1000 内存限制 65536 输入 一行字符串 长度不超过100 字符串中不
  • facebook网络架构学习总结(F4)

    1 简介 1 1 大规模快速演进 Facebook 的生产网络本身就是一个大型分布式系统 针对不同任务划分成不同层次并采 用不同的技术 a large distributed system with specialized tiers an
  • mysql中如何设置时区_如何设置MySQL的时区?

    我认为这可能是有用的 有三个位置可以在MySQL中设置时区 在 mysqld 部分中的 my cnf 文件中default time zone 00 00 global Timezone变量 若要查看它们设置为什么值 请执行以下操作 SEL
  • 如何为Kafka集群选择合适的Topic/Partitions数量

    这是许多kafka使用者经常会问到的一个问题 本文的目的是介绍与本问题相关的一些重要决策因素 并提供一些简单的计算公式 越多的分区可以提供更高的吞吐量 首先我们需要明白以下事实 在kafka中 单个patition是kafka并行操作的最小