抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Kafka入门

什么是Kafka

Kafka 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用与大数据实时处理领域。

消息队列

Kafka 本质上是一个 MQ(Message Queue),使用消息队列的好处?

  • 解耦:允许我们独立的扩展或修改队列两边的处理过程。
  • 可恢复性:即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
  • 缓冲:有助于解决生产消息和消费消息的处理速度不一致的情况。
  • 灵活性&峰值处理能力:不会因为突发的超负荷的请求而完全崩溃,消息队列能够使关键组件顶住突发的访问压力。
  • 异步通信:消息队列允许用户把消息放入队列但不立即处理它

概述

​ Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。

​ Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

简介

​ Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目,该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。

​ Kafka是一个分布式消息队列:生产者、消费者的功能。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。

​ Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性

举个例子

​ 家里有只鸡,每天下10个蛋,主人每天只能吃5个,多了 下不下,那么鸡蛋会丢失。
​ 这时候如果你有个篮子,那么多余的鸡蛋便可放进去。 kafka 就是那个篮子

Kafka 整体架构以及解析

Kafka数据处理步骤

  1. Producer产生消息,发送到Broker中
  2. Leader状态的Broker接收消息,写入到相应topic中
  3. Leader状态的Broker接收完毕以后,传给Follow状态的Broker作为副本备份
  4. Consumer消费Broker中的消息

Kafka 核心组件

  • Producer:消息生产者,产生的消息将会被发送到某个topic

  • Consumer:消息消费者,消费的消息内容来自某个topic

  • Topic:消息根据topic进行归类,topic其本质是一个目录,即将同一主题消息归类到同一个目录

  • Broker:每一个kafka实例(或者说每台kafka服务器节点)就是一个broker,一个broker可以有多个topic

  • Zookeeper:zookeeper集群不属于kafka内的组件,但kafka依赖zookeeper集群保存meta信息,所以在此做声明其重要性。

broker和集群

​ 一个独立的Kafka服务器称为broker,broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker为消费者提供服务,对读取分区的请求作出相应,返回已经提交到磁盘上的消息。根据特定的硬件及其性能特征,单个broker可以轻松处理数千个分区以及每秒百万级的消息量。

​ broker是集群的组成部分。每个集群都有一个broker同时充当了集群控制器的角色(自动从集群的活跃成员中选举出来)。控制器负责管理工作,包括将分区分配给broker和监控broker。在集群中,一个分区从属于一个broker,该broker被称为分区的首领。一个分区可以分配多个broker,这个时候会发生分区复制。这种复制机制为分区提供了消息冗余,如果一个broker失效,其他broker可以接管领导权。不过,相关的消费者和生产者都要重新连接到新的首领。

Consumer与topic关系

kafka只支持Topic

  • 每个group中可以有多个consumer,每个consumer属于一个consumer group;通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高”故障容错”性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。

  • 对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个”订阅”者。

  • 在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
    一个Topic中的每个partions,只会被一个”订阅者”中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。

  • kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。

kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。

Kafka消息的分发

  • Producer客户端负责消息的分发

  • kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含*”集群中存活的servers列表”“partitions leader列表”*等信息;

  • 当producer获取到metadata信息之后, producer将会和Topic下所有partition leader保持socket连接;

  • 消息由producer直接通过socket发送到broker,中间不会经过任何”路由层”。事实上,消息被路由到哪个partition上由producer客户端决定,比如可以采用”random””key-hash””轮询”等。

  • 如果一个topic中有多个partitions,那么在producer端实现”消息均衡分发”是必要的。

  • 在producer端的配置文件中,开发者可以指定partition路由的方式。

  • Producer消息发送的应答机制

    设置发送数据是否需要服务端的反馈,有三个值0,1,-1

    • 0: producer不会等待broker发送ack

    • 1: 当leader接收到消息之后发送ack

    • -1: 当所有的follower都同步消息成功后发送ack

    request.required.acks=0

Consumer的负载均衡

当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提升topic的并发消费能力,步骤如下:

  1. 假如topic1,具有如下partitions: P0,P1,P2,P3

  2. 加入group A 中,有如下consumer: C0,C1

  3. 首先根据partition索引号对partitions排序: P0,P1,P2,P3

  4. 根据consumer.id排序: C0,C1

  5. 计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)

  6. 然后依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]

Kafka中的基本概念

下面给出 Kafka 一些重要概念,让大家对 Kafka 有个整体的认识和感知,后面还会详细的解析每一个概念的作用以及更深入的原理

  • Producer:消息生产者,向 Kafka Broker 发消息的客户端。
  • Consumer:消息消费者,从 Kafka Broker 取消息的客户端。
  • Consumer Group:消费者组(CG),消费者组内每个消费者负责消费不同分区的数据,提高消费能力。一个分区只能由组内一个消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
  • Broker:一台 Kafka 机器就是一个 Broker。一个集群由多个 Broker 组成。一个 Broker 可以容纳多个 Topic。
  • Topic:可以理解为一个队列,Topic 将消息分类,生产者和消费者面向的是同一个 Topic。
  • Partition:为了实现扩展性,提高并发能力,一个非常大的 Topic 可以分布到多个 Broker (即服务器)上,一个 Topic 可以分为多个 Partition,每个 Partition 是一个 有序的队列。
  • Replica:副本,为实现备份的功能,保证集群中的某个节点发生故障时,该节点上的 Partition 数据不丢失,且 Kafka 仍然能够继续工作,Kafka 提供了副本机制,一个 Topic 的每个分区都有若干个副本,一个 Leader 和若干个 Follower。
  • Leader:每个分区多个副本的“主”副本,生产者发送数据的对象,以及消费者消费数据的对象,都是 Leader。
  • Follower:每个分区多个副本的“从”副本,实时从 Leader 中同步数据,保持和 Leader 数据的同步。Leader 发生故障时,某个 Follower 还会成为新的 Leader。
  • Offset:消费者消费的位置信息,监控数据消费到什么位置,当消费者挂掉再重新恢复的时候,可以从消费位置继续消费。
  • ZooKeeper:Kafka 集群能够正常工作,需要依赖于 ZooKeeper,ZooKeeper 帮助 Kafka 存储和管理集群信息。

消息和批次

​ Kafka中的数据单元称为消息(message)。如果你从数据库背景接近Kafka,您可以将其视为与行或记录类似。就Kafka而言,消息只是一个字节数组,因此其中包含的数据对Kafka没有特定的格式或含义。消息可以具有可选的元数据位,其被称为key。key也是一个字节数组,与消息一样,对Kafka没有特定含义。当消息以更受控制的方式写入分区时,使用key。最简单的方案是生成key的一致哈希,然后通过获取哈希模的结果(主题中的分区总数)来选择该消息的分区号。这可确保具有相同key的消息始终写入同一分区。

​ 为了提高效率,将消息分批写入Kafka。批处理只是一组消息,所有消息都生成到同一主题和分区。每条消息通过网络进行单独的往返会导致过度的开销,并且将消息一起收集到一个批处理中会减少这种情况。当然,这是延迟和吞吐量之间的权衡:批次越大,每单位时间可以处理的消息越多,但单个消息传播所需的时间越长。批次通常也是压缩的,以一些处理能力为代价提供更有效的数据传输和存储。

消息

​ 是Kafka中的最小数据单元,类比与“数据库”中的一条记录;消息由字节数组组成,Kafka没有具体的格式和定义,但是客户端提供的消息定义中有一组可选的数据单元:

1
2
3
4
5
6
public final class ProducerRecord<K, V> {
private final String topic; //消息主题
private final Integer partition; //消息分区
private final K key; //消息的键
private final V value; // 消息值
}

再以上的字段中,只有消息主题是必须的,标识这个消息的分类。
在分区中会具体讲一下消息的键的作用。

批次

​ 同我们常说的分批处理思想中的批次概念是一致的;从根本上来讲都是为了减少消耗,提升效率。
​ 如果每一个产生一条消息,我们就写到网络中,会带来大量的开销,所以将消息分批次来传递;当然分批会带来延迟,这样就需要在延迟和吞吐量之间做一个权衡,Kafka提供参数来给开发者优化这种平衡。
​ 单个批次消息越多,延迟越大,同时消息会被压缩,来提升数据的传输和存储能力,当然压缩更消耗CPU。
批次里面的消息都是属于同一个主题中的同一个分区,这样可以保证一次发送一批消息时的网络开销最小。

模式(Schemas)

​ 虽然消息是Kafka本身的不透明字节数组,但建议在消息内容上加上额外的结构或模式,以便易于理解。消息架构有许多选项,具体取决于您的应用程序的个性化需求。简单系统,例如Javascript Object Notation(JSON)和可扩展标记语言(XML),易于使用且易于阅读。但是,它们缺乏强大的类型处理和模式版本之间的兼容性等功能。许多Kafka开发人员都赞成使用Apache Avro,这是一个最初为Hadoop开发的序列化框架。 Avro提供紧凑的序列化格式;与消息有效负载分离的模式,不需要在更改时生成代码;强大的数据类型和模式演变,兼具向后和向前兼容性。
​ 一致的数据格式在Kafka中很重要,因为它允许写入和读取消息分离。当这些任务紧密耦合时,必须更新订阅消息的应用程序以处理新数据格式,与旧格式并行。只有这样才能更新发布消息的应用程序以使用新格式。通过使用定义良好的模式并将它们存储在一个通用的存储库中,可以无需协调地理解Kafka中的消息。

主题和分区

Kafka 里的消息用主题进行分类(主题好比数据库中的表) , 主题下有可以被分为若干个分区(分表技术) 。 分区本质上是个提交日志文件, 有新消息, 这个消息就会以追加的方式写入分区(写文件的形式) , 然后用先入先出的顺序读取。

主题是消息的分类标识,类似与文件系统中的文件夹

分区是一个主题的队列,同一个主题会包含若干分区,每一个分区都是一个提交记录,消息会被追加到分区中,在一个分区中保证顺序,已先入先出的顺序被消费。

​ Kafka为每个分区中维护着一个偏移量,偏移量记录着当前分区的消费记录,偏移量保存在分布式协同服务器ZooKeeper上。

​ 分区在Kafka中有着重要的意义,Kafka通过分区来实现数据冗余和主题的横向扩展;多个分区可以分布在不同的kafka服务端机器上,这使主题也可以横跨多个服务器存在,保证了分布式的能力;

​ 在消息中讲到了消息的键,在消息没有配置键的时候,生产者会把消息均衡的写入到各个分区。当我们需要把特定的消息写入到固定的分区时,可以通过消息的键和分区器来实现,分区器会将键生成成散列值,并映射到各个分区上。

​ 为了大量的消息能负载分散,要求主题的分区数要大于当前Kafka的broker服务器数量,这样才能保证所有每个broker能分担到消息的压力。在实际生产中,我们可以增加分区来给主题扩容,但是不能减少分区。

选定分区数量是一个需要经验的事情,需要考虑多个因素:

  1. 主题需要多大的吞吐
  2. 单个分区的最大吞吐量多少
  3. 每个broker上拥有的分区数量,这需要考量磁盘和网络带宽
  4. 单个分区上拥有的分区也不能太多,毕竟分区越多内存也越大,重新选举的时间也越长

需要注意的是,如果使用了消息的键来控制消息写入分区,那么增加主题时就需要慎重了,因为这会带来rehash的问题。

生产者和消费者

Kafka客户端是系统用户,有两种基本类型:生产者和消费者。还有高级客户端API - 用于数据集成的Kafka Connect API和用于流处理的Kafka Streams。高级客户端使用生产者和消费者作为构建块,并在顶部提供更高级别的功能。

生产者

​ 生产者创造新的信息。在其他发布/订阅系统中,这些可以称为发布者或编写者。通常,将为特定主题生成消息。默认情况下,生产者不关心特定消息写入的分区,并将均衡地平衡主题的所有分区上的消息。在某些情况下,生产者会将消息定向到特定分区。这通常使用消息key和分区程序来完成,该分区程序将生成key的散列并将其映射到特定分区。这确保了使用给定key生成的所有消息都将写入同一分区。生产者还可以使用遵循其他业务规则的自定义分区程序将消息映射到分区。

消费者

​ 消费者阅读消息。 在其他发布/订阅系统中,这些客户端可以被称为订阅者或读者。 消费者订阅一个或多个主题,并按消息的生成顺序读取消息。 消费者通过跟踪消息的偏移来跟踪它已经消耗了哪些消息。 偏移量(Offset)是元数据 - 一个不断增加的整数值 - Kafka在生成时添加到每个消息中。 给定分区中的每条消息都有唯一的偏移量。 通过在Zookeeper或Kafka本身中存储每个分区的最后消耗消息的偏移量,消费者可以停止并重新启动而不会丢失其位置。

​ 消费者作为消费者群组的一部分工作,消费者群组是一起工作以消费主题的一个或多个消费者。 该小组确保每个分区仅由一名成员消灭。 在下图中,单个组中有三个消费者使用主题。 其中两个消费者分别在一个分区工作,而第三个消费者在两个分区工作。 消费者对分区的映射通常称为消费者对分区的所有权。

​ 不同的消费者群组可以读取同一个主题,但对于同一个群组中不同消费者不能读取相同分区

通过这种方式,消费者可以横向扩展以消费具有大量消息的主题。 此外,如果单个使用者失败,则该组的其余成员将重新平衡正在使用的分区以接管缺少的成员。

保留消息

保留消息是Kafka的一个重要特性。Kafka broker默认的消息保留策略有两种。

  1. 保留一段固定的时间。比如7天
  2. 保留到消息达到一定大小的字节数,如1GB 当达到上限后,旧的消息会被过期删除。所以在任何时刻,可用消息的总量不会超过配置参数所指定的大小。

多集群

随着Kafka部署的增长,拥有多个集群通常是有利的。 有几个原因可以解决这个问题:

  • 分离数据类型
  • 为安全要求隔离
  • 多个数据中心(灾难恢复)

​ 特别是在处理多个数据中心时,通常需要在它们之间复制消息。 通过这种方式,在线应用程序可以访问两个站点的用户活动。 例如,如果用户更改其配置文件中的公共信息,则无论显示搜索结果的数据中心如何,都需要显示该更改。 或者,可以将监控数据从许多站点收集到分析和警报系统所在的单个中心位置。 Kafka集群中的复制机制仅设计用于单个集群,而不是多个集群之间。

​ Kafka项目包括一个名为MirrorMaker的工具,用于此目的。 MirrorMaker的核心是Kafka消费者和生产者,与队列链接在一起。 消息从一个Kafka集群中消耗并为另一个集群生成。下图显示了使用MirrorMaker的架构示例,该架构将来自两个本地群集的消息聚合到聚合群集中,然后将该群集复制到其他数据中心。 应用程序的简单特性掩盖了它在创建复杂数据管道方面的能力。

Kafka的优势

  1. 多个生产者:可以无缝地支持多个生产者,不管客户端在使用单个主题还是多个主题。
  2. 多个消费者:支持多个消费者从一个单独的消息流上读取数据,而且消费者之间互不影响。
  3. 基于磁盘的数据存储:支持消费者非实时地读取消息,由于消息被提交到磁盘,根据设置的规则进行保存。当消费者发生异常时候,意外离线,由于有持久化的数据保证,可以实现联机后从上次中断的地方继续处理消息。
  4. 伸缩性:用户在开发阶段可以先试用单个broker,再扩展到包含3个broker的小型开发集群,然后随着数据量不断增长,部署到生产环境的集群可能包含上百个broker。
  5. 高性能:Kafka可以轻松处理巨大的消息流,在处理大量数据的同事,它还能保证亚秒级的消息延迟。

常见使用场景

消息

​ kafka更好的替换传统的消息系统,消息系统被用于各种场景(解耦数据生产者,缓存未处理的消息,等),与大多数消息系统比较,kafka有更好的吞吐量,内置分区,副本和故障转移,这有利于处理大规模的消息。

​ 根据我们的经验,消息往往用于较低的吞吐量,但需要低的端到端延迟,并需要提供强大的耐用性的保证。

​ 在这一领域的kafka比得上传统的消息系统,如的ActiveMQ或RabbitMQ的。

网站活动追踪

​ kafka原本的使用场景:用户的活动追踪,网站的活动(网页游览,搜索或其他用户的操作信息)发布到不同的话题中心,这些消息可实时处理,实时监测,也可加载到Hadoop或离线处理数据仓库。

​ 每个用户页面视图都会产生非常高的量。

指标

​ kafka也常常用于监测数据。分布式应用程序生成的统计数据集中聚合。

日志聚合

​ 许多人使用Kafka作为日志聚合解决方案的替代品。日志聚合通常从服务器中收集物理日志文件,并将它们放在中央位置(可能是文件服务器或HDFS)进行处理。Kafka抽象出文件的细节,并将日志或事件数据更清晰地抽象为消息流。这允许更低延迟的处理并更容易支持多个数据源和分布式数据消费。

流处理

​ kafka中消息处理一般包含多个阶段。其中原始输入数据是从kafka主题消费的,然后汇总,丰富,或者以其他的方式处理转化为新主题,例如,一个推荐新闻文章,文章内容可能从“articles”主题获取;然后进一步处理内容,得到一个处理后的新内容,最后推荐给用户。这种处理是基于单个主题的实时数据流。从0.10.0.0开始,轻量,但功能强大的流处理,就可以这样进行数据处理了。

​ 除了Kafka Streams,还有Apache Storm和Apache Samza可选择。

事件采集

​ 事件采集是一种应用程序的设计风格,其中状态的变化根据时间的顺序记录下来,kafka支持这种非常大的存储日志数据的场景。

提交日志

​ kafka可以作为一种分布式的外部日志,可帮助节点之间复制数据,并作为失败的节点来恢复数据重新同步,kafka的日志压缩功能很好的支持这种用法,这种用法类似于Apacha BookKeeper项目。

Broker配置

常规配置

broker.id

​ 在单机时无需修改,但在集群下部署时往往需要修改。它是个每一个 broker 在集群中的唯一表示,要求是正数。 当该服务器的 IP 地址发生改变时,
​ broker.id 没有变化,则不会影响 consumers 的消息情况

listeners

​ 监听列表(以逗号分隔 不同的协议(如 plaintext,trace,ssl、 不同的 IP 和端口)),hostname 如果设置为 0.0.0.0 则绑定所有的网卡地址; 如果 hostname 为空
​ 则绑定默认的网卡。 如果没有配置则默认为 java.net.InetAddress.getCanonicalHostName()。

​ 如: PLAINTEXT://myhost:9092,TRACE://:9091 或 PLAINTEXT://0.0.0.0:9092,

zookeeper.connect

​ zookeeper 集群的地址, 可以是多个, 多个之间用逗号分割。 (一组 hostname:port/path 列表,hostname 是 zk 的机器名或 IP、 port 是 zk 的端口、 /path是可选 zk 的路径, 如果不指定, 默认使用根路径)

log.dirs

​ Kafka 把所有的消息都保存在磁盘上, 存放这些数据的目录通过 log.dirs 指定。 可以使用多路径, 使用逗号分隔。 如果是多路径, Kafka 会根据“最少使用” 原则, 把同一个分区的日志片段保存到同一路径下。 会往拥有最少数据分区的路径新增分区。

num.recovery.threads.per.data.dir

​ 每数据目录用于日志恢复启动和关闭时的线程数量。 因为这些线程只是服务器启动(正常启动和崩溃后重启) 和关闭时会用到。 所以完全可以设置大量的线程来达到并行操作的目的。 注意, 这个参数指的是每个日志目录的线程数, 比如本参数设置为 8, 而 log.dirs 设置为了三个路径, 则总共会启动24 个线程

auto.create.topics.enable

​ 是否允许自动创建主题。 如果设为 true, 那么 produce(生产者往主题写消息) , consume(消费者从主题读消息) 或者 fetch metadata(任意客户端向主题发送元数据请求时) 一个不存在的主题时, 就会自动创建。 缺省为 true。

主题配置

新建主题的默认参数

num.partitions

​ 每个新建主题的分区个数(分区个数只能增加, 不能减少 ) 。 这个参数一般要评估, 比如, 每秒钟要写入和读取 1000M 数据, 如果现在每个消费者每秒钟可以处理 50MB 的数据, 那么需要 20 个分区, 这样就可以让 20 个消费者同时读取这些分区, 从而达到设计目标。 (一般经验, 把分区大小限制在25G 之内比较理想)

log.retention.hours

​ 日志保存时间, 默认为 7 天(168 小时) 。 超过这个时间会清理数据。 bytes 和 minutes 无论哪个先达到都会触发。 与此类似还有 log.retention.minutes和 log.retention.ms, 都设置的话, 优先使用具有最小值的那个。 (提示: 时间保留数据是通过检查磁盘上日志片段文件的最后修改时间来实现的。也就是最后修改时间是指日志片段的关闭时间,也就是文件里最后一个消息的时间戳)

log.retention.bytes

​ topic 每个分区的最大文件大小, 一个 topic 的大小限制 = 分区数*log.retention.bytes。 -1 没有大小限制。 log.retention.bytes 和 log.retention.minutes任意一个达到要求, 都会执行删除。 (注意如果是log.retention.bytes 先达到了, 则是删除多出来的部分数据), 一般不推荐使用最大文件删除策略, 而是推荐使用文件过期删除策略。

log.segment.bytes

​ 分区的日志存放在某个目录下诸多文件中, 这些文件将分区的日志切分成一段一段的, 我们称为日志片段。 这个属性就是每个文件的最大尺寸; 当尺寸达到这个数值时, 就会关闭当前文件, 并创建新文件。 被关闭的文件就开始等待过期。 默认为 1G。
​ 如果一个主题每天只接受 100MB 的消息, 那么根据默认设置, 需要 10 天才能填满一个文件。 而且因为日志片段在关闭之前, 消息是不会过期的, 所以如果 log.retention.hours 保持默认值的话, 那么这个日志片段需要 17 天才过期。 因为关闭日志片段需要 10 天, 等待过期又需要 7 天。

log.segment.ms

​ 作用和 log.segment.bytes 类似, 只不过判断依据是时间。 同样的, 两个参数, 以先到的为准。 这个参数默认是不开启的。

message.max.bytes

​ 表示一个服务器能够接收处理的消息的最大字节数, 注意这个值 producer 和 consumer 必须设置一致, 且不要大于 fetch.message.max.bytes 属性的值(消费者能读取的最大消息,这个值应该大于或等于message.max.bytes)。 该值默认是 1000000 字节, 大概 900KB~1MB。 如果启动压缩, 判断压缩后的值。
这个值的大小对性能影响很大, 值越大, 网络和 IO 的时间越长, 还会增加磁盘写入的大小。
​ Kafka 设计的初衷是迅速处理短小的消息, 一般 10K 大小的消息吞吐性能最好(LinkedIn 的 kafka 性能测试)

硬件配置对 Kafka 性能的影响

为 Kafka 选择合适的硬件更像是一门艺术, 就跟它的名字一样, 我们分别从磁盘、 内存、 网络和 CPU 上来分析, 确定了这些关注点, 就可以在预算范围之内选择最优的硬件配置。

磁盘吞吐量/磁盘容量

​ 磁盘吞吐量(IOPS 每秒的读写次数) 会影响生产者的性能。 因为生产者的消息必须被提交到服务器保存, 大多数的客户端都会一直等待,直到至少有一个服务器确认消息已经成功提交为止。也就是说, 磁盘写入速度越快, 生成消息的延迟就越低。(SSD 固态贵单个速度快, HDD 机械偏移可以多买几个,设置多个目录加快速度, 具体情况具体分析)
​ 磁盘容量的大小, 则主要看需要保存的消息数量。 如果每天收到 1TB 的数据, 并保留 7 天, 那么磁盘就需要 7TB 的数据。

内存

​ Kafka 本身并不需要太大内存, 内存则主要是影响消费者性能。 在大多数业务情况下, 消费者消费的数据一般会从内存(页面缓存, 从系统内存中分)中获取, 这比在磁盘上读取肯定要快的多。 一般来说运行 Kafka 的 JVM 不需要太多的内存, 剩余的系统内存可以作为页面缓存, 或者用来缓存正在使用的日志片段, 所以我们一般 Kafka 不会同其他的重要应用系统部署在一台服务器上, 因为他们需要共享页面缓存, 这个会降低 Kafka 消费者的性能。

网络

​ 网络吞吐量决定了 Kafka 能够处理的最大数据流量。 它和磁盘是制约 Kafka 拓展规模的主要因素。 对于生产者、 消费者写入数据和读取数据都要瓜分网络流量。 同时做集群复制也非常消耗网络。

CPU

​ Kafka 对 cpu 的要求不高, 主要是用在对消息解压和压缩上。所以 cpu 的性能不是在使用 Kafka 的首要考虑因素。

总结

​ 我们要为 Kafka 选择合适的硬件时, 优先考虑存储, 包括存储的大小, 然后考虑生产者的性能(也就是磁盘的吞吐量) , 选好存储以后, 再来选择CPU 和内存就容易得多。 网络的选择要根据业务上的情况来定, 也是非常重要的一环。

评论