跳转到主要内容
Chinese, Simplified

Kafka是一个分布式、可扩展、弹性和容错的事件流平台,使您能够实时处理大量数据。Kafka Streams是一个库,通过构建Kafka生产者和消费者库,并利用Kafka的本地功能提供数据并行性、分布式协调、容错性和操作简单性,简化了应用程序开发。


架构

Kafka体系结构由两个主要层组成:

  • 存储层:负责存储和复制应用程序生成和使用的事件。存储层基于分布式提交日志的抽象,分布式提交日志是一种以持久和容错的方式存储记录序列的数据结构。Kafka中的记录是一个键值对,它还包含时间戳和可选的头。记录可以代表任何类型的事件,如客户订单、付款、点击网站或传感器读数
  • 计算层:负责在事件到达或离开系统时处理和转换事件。计算层由四个核心组件组成:生产者API、消费者API、流API和连接器API。这些组件允许您与存储层交互,并对事件执行各种操作

Kafka主题是共享一个共同主题或类别的记录流的逻辑名称。例如,您可以有一个名为“/orders”的主题,其中包含与系统中的订单相关的所有事件。一个主题可以划分为多个分区,这些分区是Kafka中并行性和可扩展性的单位。每个分区都是一个有序且不可变的记录序列,这些记录被分配给集群中的一个或多个代理(服务器)。一个分区可以有一个引导代理和零个或多个从引导代理复制数据以实现容错。

 

生产者API允许您将事件写入Kafka中的一个或多个主题。您可以指定各种参数,如键、值、分区、时间戳、标头、压缩类型和每个事件的确认级别。生产者API还处理事件的批处理、缓冲、序列化、错误处理和负载平衡。

 

消费者API允许您读取Kafka中一个或多个主题的事件。您可以指定各种参数,如组ID、偏移量、分区分配策略、反序列化类型、轮询间隔和每个使用者的提交行为。使用者API还处理事件的重新平衡、偏移管理、错误处理和并发控制。

 

流API允许您对Kafka中的事件执行有状态流处理。您可以使用构建在生产者和消费者API之上的Java库来定义复杂的转换、聚合、联接、窗口、状态存储和对事件的交互式查询。流API还处理流处理应用程序的可扩展性、容错性、一次性语义和应用程序重置。

 

连接器API允许您将Kafka与数据库、云服务或遗留系统等外部系统集成。您可以使用源连接器将外部系统中的数据摄取到Kafka主题中,也可以使用接收器连接器将Kafka话题中的数据导出到外部系统中。连接器API还处理配置管理。

Kafka Streams是对生产者和消费者的抽象,它使您能够专注于处理您的Kafka数据,而不必担心低级细节。您可以用Java或Scala编写代码,创建一个JAR文件,然后启动独立的应用程序,将记录流式传输到Kafka主题。

Kafka Streams为处理数据提供了两个主要的抽象:KStream和KTableKStream表示一个无限制的记录流,可以使用无状态操作(如映射、过滤、连接和聚合)对其进行转换。KTable表示记录的变更日志流,可以按键查询这些记录,并通过计数、分组、窗口化和联接等有状态操作进行更新。

 

Kafka Streams还支持交互式查询,允许您从外部客户端或服务查询应用程序的状态。您可以使用交互式查询来公开KTables的最新值或状态存储的内容。

 

设计可扩展kafka体系结构的最佳实践

需要考虑的主要方面

  • 分区:分区是实现Kafka中可扩展性和并行性的关键。一个主题被划分为一个或多个分区,这些分区分布在多个代理中。每个分区都有一个引导程序和零个或多个跟随程序,它们复制数据以实现容错。生产者根据记录键或自定义分区器将记录写入分区。使用者通过形成使用者组并将分区分配给组成员,并行地从分区中读取记录
  • 复制:复制是Kafka中确保数据可用性和持久性的机制。每个分区都可以有一个复制因子,该因子指定在不同的代理上维护多少个数据副本。分区的引导者处理所有的读写请求,而跟随者被动地复制来自引导者的数据。如果领导者失败,其中一名追随者将自动当选为新的领导者
  • 序列化:序列化是将数据从一种格式转换为另一种格式以进行传输或存储的过程。Kafka使用字节数组作为记录的数据类型,因此您需要在将数据发送到Kafka之前对其进行序列化,并在从Kafka收到数据后对其进行反序列化。Kafka为字符串、整数、字节等常见数据类型提供了内置的序列化器和反序列化器。您还可以为JSON、Avro、Protobuf等复杂数据类型使用自定义序列化器和反串行器。
  • 压缩:压缩是通过消除冗余或使用编码方案来减小数据大小的技术。压缩可以通过减少网络带宽使用、磁盘空间使用和CPU使用来提高Kafka的性能和效率。Kafka支持多种压缩编解码器,如gzip、snappy、lz4、zstd等。您可以在生产者级别或主题级别配置压缩
  • 保留:保留是决定数据在被删除或压缩之前在Kafka中保留多长时间的策略。保留可以基于时间或大小限制。基于时间的保留会删除超过指定持续时间的记录。当分区的总大小超过指定的限制时,基于大小的保留将删除记录。您还可以使用日志压缩只保留每个记录键的最新值

最佳实践

  • 有意义的记录键:记录键对于确定如何在Kafka中对数据进行分区和处理非常重要。您应该使用反映数据语义和处理逻辑的有意义的记录键。例如,如果要计算每个客户的订单数量,则应使用客户ID作为记录密钥。避免使用空键或随机键,因为它们可能会导致数据分布不均匀或不必要的重新分区
  • 避免创建过多或过少的主题:过多的主题会增加管理元数据和代理连接的开销。主题过少会导致数据失真和消费者之间的争论。一个好的经验法则是每个逻辑数据类型或域有一个主题
  • 选择一个平衡吞吐量和延迟的分区大小:更大的分区大小可以通过允许更多记录一起批处理来提高吞吐量。然而,它也会延迟向消费者交付记录,从而增加延迟。较小的分区大小可以通过更快地传递记录来减少延迟。然而,它也可以通过降低批处理效率来降低吞吐量。一个好的经验法则是分区大小在1MB到10MB之间
  • 选择与所需并行级别匹配的分区数:分区数决定了有多少消费者可以并行使用主题中的数据。如果您的分区比使用者多,则某些分区将处于空闲状态。如果你的消费者比分区多,那么一些消费者就会饿死。一个好的经验法则是至少拥有与预期消费者的最大数量一样多的分区
  • 选择一个符合可用性和持久性要求的复制因子:复制因子决定了在不同的代理上维护每个分区的副本数量。更高的复制因子可以在一个复制副本出现故障时允许消费者切换到另一个复制复制副本,从而提高可用性。它还可以通过降低代理崩溃时数据丢失的风险来提高耐用性。但是,更高的复制系数也会增加磁盘空间使用率和网络流量。一个好的经验法则是复制因子在2到4之间。
  • 选择适当的状态存储:状态存储是存储流应用程序状态的本地数据库,如KTables或自定义聚合。Kafka Streams提供两种类型的状态存储:RocksDB和内存。RocksDB是一个持久的键值存储,支持快速高效地访问大量数据。内存中状态存储速度更快,但不那么耐用,而且更占用内存。您应该选择适合您的性能和可靠性要求的状态存储类型
  • 调整您的配置参数:Kafka Streams公开了许多配置参数,允许您自定义流应用程序的行为和性能。您应该根据您的用例和环境来调整这些参数。例如,您可以调整缓冲区大小、批处理大小、提交间隔、缓存大小、轮询超时等,以优化应用程序的吞吐量和延迟。您还可以启用度量和日志记录来监视应用程序并对其进行故障排除
  • 测试和基准测试您的应用程序:测试和基准是确保流媒体应用程序的质量和性能的重要步骤。您应该使用实际的数据和负载场景来测试您的应用程序,并测量关键指标,如吞吐量、延迟、资源利用率、错误率等。您还应该将结果与您的期望和要求进行比较,并确定需要解决的任何瓶颈或问题
  • 保护您的Kafka集群和数据:您应该使用SSL、SASL或Kerberos等机制为您的Kavka集群启用身份验证、授权和加密。您还应该使用ACL、配额、复制和备份等功能来保护您的数据免受未经授权的访问、篡改或丢失

常见问题及解决方案

数据重复

使用Kafka内置的数据冗余和恢复功能,确保数据只存储一次。您还可以使用KafkaConnect将Kafka与其他系统集成,避免数据重复。

数据丢失或群集故障

您可以配置您的Kafka集群进行容错。您可以使用复制来确保您的数据存储在多个代理上。您还可以使用负载均衡器在代理之间分配流量。

数据倾斜

当数据在分区之间分布不均匀时,可能会发生数据偏斜,这会影响Kafka集群的性能。为了解决这个问题,您可以使用分区策略,在分区之间均匀分布数据,例如基于键的分区或循环分区。

缓慢的再平衡时间

您可以利用缓存来减少需要重新平衡的数据量。您还可以监控主题的数据量,以确保Kafka的性能不受影响。

网络拥塞

通过使用高速网络接口优化网络配置,将网络配置为低延迟,并使用压缩来减少传输的数据量。

冗余数据存储

仅将Kafka用于短期存储数据,并根据您的特定需求将数据迁移到关系数据库或非关系数据库。您还可以将Kafka配置为使用HDFS或blob存储以获得额外的永久性。

延迟或无序事件

您可以在Kafka Streams中使用事件时间语义和窗口操作来处理延迟或无序事件。事件时间语义意味着您使用嵌入事件中的时间戳而不是处理时间来确定事件的顺序。通过窗口操作,可以将事件分组为固定或动态时间间隔,并对其应用聚合或联接。您还可以为处理延迟到达或更新的窗口指定宽限期和保留期。

模式演变或数据格式更改

您可以使用模式注册表和序列化框架,如Avro、Protobuf或JSONSchema来处理模式演变或数据格式更改。模式注册表是一种存储和管理数据模式的服务。序列化框架允许您通过架构兼容性检查和转换对数据进行序列化和反序列化。您可以使用自定义序列化程序和反序列化程序将模式注册表和序列化框架与Kafka Streams集成。

安全漏洞

您可以使用加密、身份验证和授权来保护您的Kafka集群。您还可以监视Kafka集群的安全问题,并在必要时采取纠正措施。

监测不足

您可以实施一个全面的监控解决方案,跟踪吞吐量、延迟和错误率等关键指标。您还可以设置警报,以便在出现性能问题时通知您,并在必要时采取纠正措施。

实施不当

它可能导致数据处理效率低下和技术债务。为了避免这种情况,您可以在设计和实现Kafka架构时遵循最佳实践。您还可以监视Kafka集群的性能和可用性问题,并在必要时采取纠正措施。

最后一句话

为高性能流应用程序设计和实现可扩展的Kafka架构需要仔细规划和实现。Kafka事件驱动架构、Kafka Streams和Apache Pulsar分布式消息和流媒体平台是提高Kafka性能的一些解决方案。

原文地址
https://romanglushach.medium.com/how-to-design-and-implement-scalable-kafka-architecture-for-high-performance-streaming-applications-4c529132e795
本文地址
Article

微信

知识星球

微信公众号

视频号