Kafka使用前准备(二)

本文为博主自学笔记整理,内容来源于互联网,如有侵权,请联系删除。

个人笔记:https://github.com/dbses/TechNotes

01 | 我应该选择哪种Kafka?

整个 Kafka 生态圈如下图所示。

image-20210424231049846

Kafka Connect 通过一个个具体的连接器(Connector),串联起上下游的外部系统。

由于存在多个组织或公司发布不同的 Kafka,目前市面上主要有以下三种:

Apache Kafka

Apache Kafka 是最“正宗”的 Kafka,自 Kafka 开源伊始,它便在 Apache 基金会孵化并最终毕业成为顶级项目,它也被称为社区版 Kafka。

Apache Kafka 的劣势在于它仅仅提供最最基础的组件,特别是对于前面提到的 Kafka Connect 而言,社区版 Kafka 只提供一种连接器,即读写磁盘文件的连接器,而没有与其他外部系统交互的连接器,在实际使用过程中需要自行编写代码实现,这是它的一个劣势。另外 Apache Kafka 没有提供任何监控框架或工具。显然在线上环境不加监控肯定是不可行的,你必然需要借助第三方的监控框架实现对 Kafka 的监控。好消息是目前有一些开源的监控框架可以帮助用于监控 Kafka(比如 Kafka manager)。

如果你仅仅需要一个消息引擎系统亦或是简单的流处理应用场景,同时需要对系统有较大把控度,那么推荐使用 Apache Kafka。

Confluent Kafka

2014 年,Kafka 的 3 个创始人 Jay Kreps、Naha Narkhede 和饶军离开 LinkedIn 创办了 Confluent 公司,专注于提供基于 Kafka 的企业级流处理解决方案。Confluent 公司主要从事商业化 Kafka 工具开发,并在此基础上发布了 Confluent Kafka。Confluent Kafka 提供了一些 Apache Kafka 没有的高级特性,比如跨数据中心备份、Schema 注册中心以及集群监控工具等。

Confluent Kafka 目前分为免费版和企业版两种。前者和 Apache Kafka 非常相像,除了常规的组件之外,免费版还包含 Schema 注册中心和 REST proxy 两大功能。前者是帮助你集中管理 Kafka 消息格式以实现数据前向 / 后向兼容;后者用开放 HTTP 接口的方式允许你通过网络访问 Kafka 的各种功能,这两个都是 Apache Kafka 所没有的。

如果你需要用到 Kafka 的一些高级特性,那么推荐你使用 Confluent Kafka。

Cloudera/Hortonworks Kafka

Cloudera 提供的 CDH 和 Hortonworks 提供的 HDP 是非常著名的大数据平台,里面集成了目前主流的大数据框架,能够帮助用户实现从分布式存储、集群调度、流处理到机器学习、实时数据库等全方位的数据处理。

CDH/HDP Kafka 天然集成了 Apache Kafka,通过便捷化的界面操作将 Kafka 的安装、运维、管理、监控全部统一在控制台中。如果你是这些平台的用户一定觉得非常方便,因为所有的操作都可以在前端 UI 界面上完成,而不必去执行复杂的 Kafka 命令。另外这些平台提供的监控界面也非常友好,你通常不需要进行任何配置就能有效地监控 Kafka。

如果你需要快速地搭建消息引擎系统,或者你需要搭建的是多框架构成的数据平台且 Kafka 只是其中一个组件,那么我推荐你使用这些大数据云公司提供的 Kafka。

02 | Kafka的版本号

Kafka 版本命名

对于 kafka-2.11-2.1.1 的提法, 2.11 是 Scala 编译器版本,真正的 Kafka 版本号实际上是 2.1.1。

前面的 2 表示大版本号,即 Major Version;中间的 1 表示小版本号或次版本号,即 Minor Version;最后的 1 表示修订版本号,也就是 Patch 号。Kafka 社区在发布 1.0.0 版本后特意写过一篇文章,宣布 Kafka 版本命名规则正式从 4 位演进到 3 位,比如 0.11.0.0 版本就是 4 位版本号。

Kafka 版本演进

Kafka 目前总共演进了 7 个大版本,分别是 0.7、0.8、0.9、0.10、0.11、1.0 和 2.0。

我们先从 0.7 版本说起,这是最早开源时的“上古”版本了。这个版本只提供了最基础的消息队列功能,甚至连副本机制都没有,不推荐这个版本。

Kafka 到 0.8 之后正式引入了副本机制,至此 Kafka 成为了一个真正意义上完备的分布式高可靠消息队列解决方案。有了副本备份机制,Kafka 就能够比较好地做到消息无丢失。那时候生产和消费消息使用的还是老版本的客户端 API,你需要指定 ZooKeeper 的地址而非 Broker 的地址。

2015 年 11 月,社区正式发布了 0.9.0.0 版本。这是一个重量级的大版本更迭,0.9 大版本增加了基础的安全认证 / 权限功能,同时使用 Java 重写了新版本消费者 API,另外还引入了 Kafka Connect 组件用于实现高性能的数据抽取。新版本 Producer API 在这个版本中算比较稳定了。但是 Consumer API Bug 超多。因此千万别用 0.9 的新版本 Consumer API。

0.10.0.0 是里程碑式的大版本,因为该版本引入了 Kafka Streams。如果你把 Kafka 用作消息引擎,实际上该版本并没有太多的功能提升。不过新版本 Consumer API 算是比较稳定了,强烈建议你至少升级到 0.10.2.2 然后使用新版本 Consumer API。

在 2017 年 6 月,社区发布了 0.11.0.0 版本,引入了两个重量级的功能变更:一个是提供幂等性 Producer API 以及事务(Transaction) API;另一个是对 Kafka 消息格式做了重构。幂等以及事务 API 主要是为 Kafka Streams 应用服务的,因为 Kafka Streams 在做流处理时需要保证结果的正确性。第二个重磅改进是消息格式的变化,消息格式转换可能会导致性能问题。

1.0 和 2.0 这两个大版本主要还是 Kafka Streams 的各种改进,在消息引擎方面并未引入太多的重大功能特性。Kafka Streams 的确在这两个版本有着非常大的变化,也必须承认 Kafka Streams 目前依然还在积极地发展着。如果你是 Kafka Streams 的用户,至少选择 2.0.0 版本吧。

最后还有个建议,不论你用的是哪个版本,都请尽量保持服务器端版本和客户端版本一致,否则你将损失很多 Kafka 为你提供的性能优化收益。

03 | Kafka线上集群部署方案怎么做?

下面我们分别从操作系统、磁盘、磁盘容量和带宽等方面来讨论一下。

操作系统

建议部署在 Linux 上,主要考虑以下三个方面:

  • I/O 模型的使用

    主流的 I/O 模型通常有 5 种类型:阻塞式 I/O、非阻塞式 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。

    Kafka 客户端底层使用了 Java 的 selector,selector 在 Linux 上的实现机制是 epoll,而在 Windows 平台上的实现机制是 select。

    因此在这一点上将 Kafka 部署在 Linux 上是有优势的,因为 epoll 比 select 更高级,能够获得更高效的 I/O 性能。

  • 数据网络传输效率

    Kafka 生产和消费的消息都是通过网络传输的,然后保存在硬盘。故 Kafka 需要在磁盘和网络间进行大量数据传输。

    在 Linux 部署 Kafka 能够享受到零拷贝技术所带来的快速数据传输特性。

  • 社区支持度

    社区目前对 Windows 平台上发现的 Kafka Bug 不做任何承诺。因此,Windows 平台上部署 Kafka 只适合于个人测试或用于功能验证。

磁盘

机械硬盘成本低且容量大,但易损坏;固态硬盘性能优势大,不过单价高。

Kafka 使用磁盘的方式多是顺序读写操作,一定程度上规避了机械磁盘随机读写操作慢的劣势。从这一点上来说,使用 SSD 似乎并没有太大的性能优势,毕竟从性价比上来说,机械磁盘物美价廉,而它因易损坏而造成的可靠性差等缺陷,又由 Kafka 在软件层面提供机制来保证,故使用普通机械磁盘更划算。

那有必要使用磁盘阵列(RAID)吗?它的主要优势主要有两个:

  • 提供冗余的磁盘存储空间
  • 提供负载均衡

就 Kafka 而言,一方面 Kafka 自己实现了冗余机制来提供高可靠性;另一方面通过分区的概念,Kafka 也能在软件层面自行实现负载均衡。

如此说来 RAID 的优势就没有那么明显了,因此使用机械磁盘就可以了。

磁盘容量

在规划磁盘容量时需要考虑下面这几个元素:

  • 新增消息数
  • 消息留存时间
  • 平均消息大小
  • 备份数
  • 是否启用压缩

假设你所在公司有个业务每天需要向 Kafka 集群发送 1 亿条消息,每条消息保存两份以防止数据丢失,另外消息默认保存两周时间。现在假设消息的平均大小是 1KB,那么 Kafka 集群需要为这个业务预留多少磁盘空间呢?

每天 1 亿条 1KB 大小的消息,保存 2 份且留存两周的时间,那么 1 天总的空间大小就等于 1 亿 * 1KB * 2 / 1000 / 1000 = 200GB。

一般情况下 Kafka 集群除了消息数据还有其他类型的数据,比如索引数据等,故我们再为这些数据预留出 10% 的磁盘空间,因此总的存储容量就是 220GB。要保存两周,那么整体容量即为 220GB * 14,大约 3TB 左右。

Kafka 支持数据的压缩,假设压缩比是 0.75,那么最后你需要规划的存储空间就是 0.75 * 3 = 2.25TB。

带宽

普通的以太网络带宽主要有两种:1Gbps 的千兆网络和 10Gbps 的万兆网络,特别是千兆网络应该是一般公司网络的标准配置了。

假设你公司的机房环境是千兆网络,即 1Gbps,现在你有个业务,其业务目标是在 1 小时内处理 1TB 的业务数据。那么你需要多少台 Kafka 服务器来完成这个业务呢?

由于带宽是 1Gbps,即每秒处理 1Gb 的数据,假设每台 Kafka 服务器都是安装在专属的机器上(一般真实环境 Kafka 机器上都不会混布其他服务),那么单台 Kafka 服务器最多也就能使用大约 700Mb 的带宽资源。

根据实际使用经验,超过 70% 的阈值就有网络丢包的可能性了,因为总要为其他应用或进程留一些资源。故 70% 的设定是一个比较合理的值。

然而,这只是它能使用的最大带宽资源,你不能让 Kafka 服务器常规性使用这么多资源,故通常要再额外预留出 2/3 的资源,即单台服务器使用带宽 700Mb / 3 ≈ 240Mbps。

需要提示的是,这里的 2/3 其实是相当保守的,你可以结合你自己机器的使用情况酌情减少此值。

有了 240Mbps,我们就可以计算 1 小时内处理 1TB 数据所需的服务器数量了。根据这个目标,我们每秒需要处理 2330Mb 的数据,除以 240,约等于 10 台服务器。如果消息还需要额外复制两份,那么总的服务器台数还要乘以 3,即 30 台。

每秒需要处理数据:
1024 ∗ 1024 M B / ( 60 ∗ 60 ) = 291 M B 1024*1024MB/(60*60)=291MB 10241024MB/(6060)=291MB

291 M B = 291 ∗ 8 M b = 2330 M b 291MB=291*8Mb=2330Mb 291MB=2918Mb=2330Mb

04 重要的集群配置参数

这些配置并不单单指 Kafka 服务器端的配置,其中既有 Broker 端参数,也有 Topic 级别的参数、JVM 端参数和操作系统级别的参数。下面我先从 Broker 端参数说起。

Broker 端参数

  • log.dirs:指定了 Broker 需要使用的若干个文件目录路径。这个参数是没有默认值的,它必须由你亲自指定。例如:/home/kafka1,/home/kafka2,/home/kafka3。
  • log.dir:它表示单个路径,是补充上一个参数用的。

连接 Broker 相关参数

  • listeners:告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务。例如:CONTROLLER: //localhost:9092。
  • listener.security.protocol.map:一旦你自己定义了协议名称,你必须还要指定listener.security.protocol.map参数告诉这个协议底层使用了哪种安全协议,比如指定 CONTROLLER:PLAINTEXT 表示 CONTROLLER 这个自定义协议底层使用明文不加密传输数据。
  • advertised.listeners:Advertised 的含义表示宣称的、公布的,就是说这组监听器是 Broker 用于对外发布的。

数据留存参数

  • log.retention.{hour|minutes|ms}:这是个“三兄弟”,都是控制一条消息数据被保存多长时间。从优先级上来说 ms 设置最高、minutes 次之、hour 最低。

    通常情况下我们还是设置 hour 级别的多一些,比如log.retention.hour=168表示默认保存 7 天的数据。

  • log.retention.bytes:这是指定 Broker 为消息保存的总磁盘容量大小。默认值是 -1,表明你想在这台 Broker 上保存多少数据都可以。

    如果要做一个云上的 Kafka 服务,每个租户只能使用 100GB 的磁盘空间,为了避免有个“恶意”租户使用过多的磁盘空间,设置这个参数就显得至关重要了。

  • message.max.bytes:控制 Broker 能够接收的最大消息大小。默认是 1000012,不到 1MB。

    实际场景中突破 1MB 的消息很常见,所以建议设置在一点。

ZooKeeper 相关的设置

ZooKeeper 负责协调管理并保存 Kafka 集群的所有元数据信息,比如集群都有哪些 Broker 在运行、创建了哪些 Topic,每个 Topic 都有多少分区以及这些分区的 Leader 副本都在哪些机器上等信息。

  • zookeeper.connect:比如指定它的值为zk1:2181,zk2:2181,zk3:2181。如果让多个 Kafka 集群使用同一套 ZooKeeper 集群,可以这样指定:zk1:2181,zk2:2181,zk3:2181/kafka1zk1:2181,zk2:2181,zk3:2181/kafka2

Topic 级别参数

Topic 管理参数

  • auto.create.topics.enable:是否允许自动创建 Topic。建议设置成 false。
  • unclean.leader.election.enable:是否允许 Unclean Leader 选举。即让不让那些落后太多的副本竞选 Leader。建议设置成 false。
  • auto.leader.rebalance.enable:是否允许定期进行 Leader 选举。建议设置成 false。

Topic 级别参数会覆盖全局 Broker 参数的值。

  • retention.ms:规定了该 Topic 消息被保存的时长。默认是 7 天,即该 Topic 只保存最近 7 天的消息。一旦设置了这个值,它会覆盖掉 Broker 端的全局参数值。
  • retention.bytes:规定了要为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 -1,表示可以无限使用磁盘空间。
  • max.message.bytes:Kafka Broker 能够正常接收该 Topic 的最大消息大小。

如何在创建 Topic 时设置这些参数呢?

方法一:

bin/kafka-topics.sh--bootstrap-serverlocalhost:9092--create--topictransaction--partitions1--replication-factor1--configretention.ms=15552000000--configmax.message.bytes=5242880

方法二(推荐):

 bin/kafka-configs.sh--zookeeperlocalhost:2181--entity-typetopics--entity-nametransaction--alter--add-configmax.message.bytes=10485760

JVM 参数

Kafka 自 2.0.0 版本开始,已经正式摒弃对 Java 7 的支持了,所以至少要使用 Java 8。

  • KAFKA_HEAP_OPTS:指定堆大小。建议设置成 6GB,因为 Kafka Broker 在与客户端进行交互时会在 JVM 堆上创建大量的 ByteBuffer 实例,Heap Size 不能太小。
  • KAFKA_JVM_PERFORMANCE_OPTS:指定 GC 参数。如果是 Java 7,且 CPU 资源非常充裕,建议使用 CMS 收集器,否则使用 ParallelGC;如果是 Java 8 则建议使用 G1。

操作系统参数

  • 文件描述符限制:通常情况下将它设置成一个超大的值是合理的做法,比如ulimit -n 1000000

    其实设置这个参数一点都不重要,但不设置的话后果很严重,比如你会经常看到“Too many open files”的错误。

  • 文件系统类型:如 ext3、ext4 或 XFS。根据官网的测试报告,XFS 的性能要强于 ext4,所以生产环境最好还是使用 XFS。

  • swap 调优:可以设置成一个较小的值。如果设置成 0,表示将 swap 完全禁掉以防止 Kafka 进程使用 swap 空间。当物理内存耗尽时,操作系统会触发 OOM killer 这个组件,它会随机挑选一个进程然后 kill 掉,根本不给用户任何的预警。但如果设置成一个比较小的值,当开始使用 swap 空间时,能够观测到 Broker 性能开始出现急剧下降,从而给你进一步调优和诊断问题的时间。

  • 提交时间/Flush 落盘时间:默认是 5 秒,可适当调大,以提高写入性能。

    向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会按照提交时间定期将页缓存上的“脏”数据落盘到物理磁盘上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值