Kafka应用实践与生态集成

1.前言

Apache Kafka发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员。Apache Kafka社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得Apache Kafka功能越发丰富、性能越发稳定,截止本篇博客Apache Kafka发布了V2.2.0版本。

那么,今天就来聊一聊Kafka应用实践与生态集成的相关内容。

2.如何知道Kafka是否适合你?

项目立项时,会做技术调研,那么如何知道你选择的Kafka技术是否能够满足你?据Confluent公司调研报告可知,Apache Kafka在过去几年中在功能和覆盖范围方面取得了很大成就。它被财富500强中的三分之一用于生产,包括全球十大银行中的七家,十大保险公司中的八家,以及美国十大电信公司中的九家。接下来,为大家介绍Kafka示例来帮助大家了解常见的使用模式。并且希望大家能找到与自己的工作流程有交集的地方,这样大家就可以开始利用Kafka的强大功能了。

下面让先来看看Kafka提供的两个核心功能:

2.1 消息系统

消息系统常见的两种模式:

  • 队列:队列消费者充当了工作组的角色,每条消息记录只传递给一个工作进程,从而有效的划分工作流程;
  • 发布与订阅:订阅者通常是彼此独立的,每个订阅者都可以获得每条消息的副本。

这两种模式都是有效和实用的,通过队列将工作内容分开,用于容错和扩展;发布与订阅能够允许多租户,来使系统解耦。而Apache Kafka的有点之一在于它将队列、发布与订阅结合到了一个强大的消息系统中。

2.2 流处理

Apache Kafka拥有强大,可扩展的消息系统,只需要一种简单的方法来处理消息流。而在Kafka中,Stream API提供这一功能,它是一个Java客户端类库,提供比Producer和Consumer更高级别的抽象API。

这使得它使用起来非常的方便:

  • 无状态操作,例如过滤和转换流消息;
  • 有状态操作,例如时间窗口上的连接和聚合。

Stream API处理消息的序列化与反序列化,同时维护有状态操作所需要的状态。

2.3 典型的Kafka案例

  • 旅游行业:例如,在一个旅游网站,酒店和航班的价格是一直在变化的,系统的一些组件(价格告警、分析等)需要了解这些变化。你在Kafka的Topic上发布更改,并且需要通知的每个组件都充当一个消费者。每个消费者应用所组成的节点形成一个消费者组。给消费者组所消费的Topic的发送消息动态记录,这样每个消费者均可获取消息记录,同时每个消费者内能够有效的划分工作内容。
  • 用户分析:页面查看、搜索、用户行为分析等,这些实际上是Kafka在LinkedIn设计的原始初衷。用户点击网站活动内容,每个活动类型均有一个Topic,可以实时的反馈,以便深入了解用户参与度、下载量、页面流量等。
  • GPS:例如,能够实时获取智能手机设备的位置数据,并且希望能够实时处理这些数据来显示车辆路径、行驶距离等。传入数据到Kafka的Topic中,并使用Stream API来进行处理。当需要在特定时间段内提取和处理给定用户的所有位置数据时,使用窗口进行状态处理会有不错的效果。

3.Kafka的内部存储工作原理是什么?

如何你确定了Kafka技术适合你当前的项目,满足你的业务需求。你可能会很好奇,Kafka的内部存储工作原理是什么呢?接下来,将给大家分析Kafka是如何存储其数据的。

3.1 Kafka存储单元是分区

Topic中的分区是有序写入的,且不可变的消息序列。分区不能跨多个Broker或者多个磁盘来进行分割。

3.2 保留策略来管理Topic中消息

在你创建的Topic中,你可以指定保留多少数据或者保留多长时间的数据,然后Kafka会按照顺序来清除这些消息(不管消息是否有被使用)。

3.3 分区片段

Kafka需要定期查找磁盘上待清除的数据,对于分区消息单个非常长的文件,该操作会很慢并且容易出错。为了解决这个问题,Kafka实行了分区分片策略。当Kafka将消息写入分区时,它会写入到一个片段,如果该片段到达阀值,则会新开一个新的片段来写入。片段以偏移量来命名,片段的偏移量是大于前一个片段的偏移量且小于或者等于当前片段中的偏移量。

3.4 片段日志是存储消息的位置

每条消息都包含值、偏移量、时间戳、主键(KEY)、消息大小、压缩编解码器、校验、以及消息格式的版本。磁盘上的数据格式与Broker通过网络从Producer端接收的格式完全相同,然后由Consumer去获取数据,这使得Kafka能够通过零拷贝技术有效的传输数据。

3.5 片段索引将消息偏移量映射到它们在日志中的位置

索引文件是内存映射的,偏移量查找时使用二进制搜索来查找小于或等于最近的目标偏移量。索引文件由8个字节组成,4个字节用于存储基本偏移量,另外4个字节来存储位置。

3.6 Kafka将压缩的消息包装在一起

发送压缩消息的Producer端会将压缩批处理,并将其作为包装消息的有效负载发送。和之前一样,磁盘上的数据与Broker通过网络从Producer端接收并发送给其Consumer的数据完全相同。 

3.7 Kafka内部存储工作原理小结

  • Kafka的存储单元是分区;
  • 分区通过片段来进行分割;
  • 片段包含两个文件:索引和日志文件;
  • 索引将每个偏移量映射到它们所在日志中的消息位置,用于查找消息;
  • 压缩消息批处理作为包装消息的有效负载;
  • 存储在磁盘上的数据与Broker通过网络从Producer端接收并发给Consumer的数据相同。

4.Kafka API之间的选择与竞争

Kafka的核心尽管在一段时间内保持相对的稳定,但是Kafka生态圈然后在快速的发展。最初的Kafka,包含Producer和Consumer,很容易理解。现在Kafka处理Producer和Consumer,还有Kafka Connect、Kafka Streams、以及KSQL。 

4.1 如何正确的选择Kafka API

  • Kafka Producer API:应用直接生成数据,例如移动设备、PC、其他硬件等。
  • Kafka Connect Source API:应用程序桥接在我们无法控制的数据存储介质,例如MongoDB、ElasticSearch、RESTAPI等。
  • Kafka Streams API/KSQL:如果希望像SQL一样操作实时流数据,可以通过KSQL来完成;如果需要编写复杂的业务逻辑,可以使用Kafka Streams API来完成。
  • Kafka Consumer API:直接读取流数据,并对其执行实时操作,例如推送商品促销活动、发送邮件、获取游戏行为等。
  • Kafka Connect Sink API:读取实时流并将其存储到目标介质中,例如Kafka到S3、Kafka到HDFS、Kafka到HBase等。

选择不同的API来实现不同的业务需求,例如,如果希望为实现的需求编写大量的自定义代码,Kafka Consumer API和Kafka Connect Sink API完全是可以互换的。总而言之,上述API可以帮助你在实际的业务中以最少的代码量来实现最有效的工作流程。

4.2 各个API的优势和局限

4.2.1 Kafka Producer API

  • 优势: Kafka Producer API使用起来非常的简单,异步发送数据,获取回调结果。非常适合直接发送数据流的应用程序,例如日志、点击流、物联网等。
  • 局限:可以扩展和构建Kafka Producer API以便执行更多的操作,但是这需要开发人员编写更多的附加逻辑。例如,试图使用Kafka Producer API在数据库和Kafka之间执行ETL操作时,如何跟踪偏移量(即当Producer端停止后,如何正确恢复你的Producer应用程序)?、如何在若干个Producer之间分配ETL的负载?这种情况,我们使用Kafka Connect Source API会更好一些。

4.2.2 Kafka Connect Source API

  • 优势:Kafka Connect Source API是一个构建在Kafka Producer API之上的完整框架。它的构建是为了让开发人员能够获得更好的API,以便为并行处理生成并分配任务。另外,可以使用各种各样的连接器,利用这些连接器来处理大多数数据介质,且无需编写任何代码。
  • 局限:适配的数据源连接器均是专属的,如果你当前的数据源在已有的连接器中不包含,需要自行编写连接器来进行适配。

4.2.3 Kafka Consumer API

  • 优势:Kafka Consumer API非常简单,可以使用Consumer Groups,因此可以并行使用Topic。新版本的Kafka(V2.2.0)对于偏移量的管理和提交、Balance、幂等性等无需开发者关心。
  • 局限:在ETL场景中,Kafka Connect Sink更加合适,因为它们会避免针对外部数据源编写复杂的逻辑。

4.2.4 Kafka Connect Sink API

  • 优势:与Kafka Connect Source API类似,Kafka Connect Sink API允许利用现有的Kafka连接器的生态系统来执行流式ETL,且无需编写任何代码。Kafka Connect Sink API建立在Kafka Consumer API的基础之上,但是与它有所不同。
  • 局限:如果写入的数据源没有可用的适配器,那么需要自行编写Kafka Connect连接器,并且调试过程会有些复杂。

4.2.5 Kafka Streams API

  • 优势:对于流处理场景,Kafka中附带Kafka Streams API,并且能够编写高级DSL(类似于函数式编程或者Spark类型的程序)或偏底层的API(类似于Storm)。Kafka Streams API完全隐藏了Producer和Consumer的复杂性,让开发者更加专注于流处理的逻辑实现上。同时,它还具有连接、聚合、一次性处理等功能。
  • 局限:使用Kafka Streams API会让编码门槛提高,同时也可能让你业务逻辑变得复杂。

4.2.6 KSQL

  • 优势:KSQL不是Kafka API的直接组成部分,而是Kafka Streams之上的包装器。这里还是值得一说的,虽然Kafka Streams允许编写一些复杂的Topology,但它还是需要一些实质性的编程知识,尤其是新手来说。KSQL希望通过提供与现有的SQL语义类似来抽象出这种复杂性。对于开发者来说,KSQL是非常具有诱惑力的,它使得流处理器变得轻而易举。
  • 局限:对于复杂的业务场景,对数据进行复杂的转换操作,或一些特定的需求,可能还是需要使用Kafka Streams来完成。

5.Kafka与Kubernetes结合是否效率更高?

5.1 介绍

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。Kubernetes旨在运行无状态工作负载,这些工作负载通常采用微服务架构形式,轻量级、水平扩展。而Kafka的本质上是一个分布式的存储介质,这意味着你在使用时必需处理状态,它比微服务更重要。尽管Kubernetes支持有状态的工作负载,但还是需要谨慎使用。

那么,应该在Kubernetes上运行Kafka吗?如何让Kafka和Kubernetes互相补充,以及如何避免可能遇到的“坑”?

5.2 基础指标

  • 进程:Kafka Broker对CPU很友好,TLS的引入可能会产生一些开销。Kafka Client如果使用加密会需要更多的CPU,但是这并不会影响Broker。
  • 内存:Kafka Broker的JVM通常可以设置为4GB-8GB之间,但是由于Kafka大量使用了页面缓存,因此还是需要有足够的系统内存。在Kubernetes中,相应的设置容器资源限制和请求。
  • 存储:容器中的存储是暂时的,重启后数据将会丢失,但是可以对Kafka数据使用空目录卷。因此,需要使用持久化存储,存储必须是非本地的,以便Kubernetes在重启后或重新定位后更加灵活的选择另一个节点。
  • 网络:与大多数分布式系统一样,Kafka性能在很大程度上取决于低网络延迟和高带宽。建议不要把所有的Broker放在同一个节点,因为这样会降低可用性。如果Kubernetes节点出现故障,那么整个Kafka集群都会出现故障。

5.3 性能

安装Kafka之前,做POC测试是非常重要的。这样做的好处是,在遇到有关性能瓶颈问题时,可以提供帮助。而Kafka附带了两个POC测试工具,它们分别是:kafka-producer-perf-test.sh和kafka-consumer-perf-test.sh。

  • 监控:监控Kafka指标是非常有必要的,能够让我们及时的掌握Kafka、Zookeeper集群的健康状态,例如使用Kafka Eagle来监控和管理Kafka Topic(http://www.kafka-eagle.org/)。
  • 日志:日志是一个比较关键的部分,确保Kafka安装中所有的容器都记录到stdout和stderr中,并确保Kubernetes集群日志能集中管理,例如输送到ElasticSearch。
  • 动态更新:StatefulSets支持自动更新,RollingUpdate策略将一次更新一个Kafka Pod,来实现零停机维护,这也是Kubernetes的优势之一。
  • 扩容:Kubernetes可以很容易的将Pod缩放到一定数量的副本,这意味着可以声明性的定义所需数量的Kafka Broker。
  • 备份&还原:Kafka部署在Kubernetes中,这样Kafka的可用性就取决于Kubernetes的可用性,如果Kubernetes集群出现故障,那么Kafka的可用性就会下降,同时,也会出现数据丢失的风险,因此需要做好数据备份策略,例如MirrorMaker,或是S3进行连接备份。

5.4 对于Kubernetes的选择

对于中小型的Kafka集群,将Kafka部署到Kubernetes是一个不错的选择,因为它提供了更大的灵活性、且简化了操作。如果在延迟或吞吐量方面有较高的功能性要求,独立部署的方式可能会更好。

6.总结

本篇博客,介绍了Kafka应用实践与生态集成,通过阅读本篇博客的内容,大家可以参考本篇博客的内容,来做出合理、有效的选择。

7.结束语

这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

另外,博主出书了《Kafka并不难学》和《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。关注下面公众号,根据提示,可免费获取书籍的教学视频。

posted @ 2019-05-26 23:48  哥不是小萝莉  阅读(...)  评论(... 编辑 收藏