Apache Kafka 消息键2025 年 1 月 23 日 | 阅读 16 分钟 理解 Kafka 消息键在 Apache Kafka 中,消息键是 Kafka 消息的可选部分,用于确定消息应发送到主题中的哪个分区。每个 Kafka 消息都由键、值以及诸如时间戳和头信息之类的元数据组成。消息键是 Kafka 确保数据高效分发和处理的关键方面。 结构Kafka 消息由以下几部分组成:
目的消息键的主要目的是提供一种对消息进行分组和排序的方法。具有相同键的消息保证会发送到同一个分区,这确保了它们按照发送顺序进行处理。 消息键的作用和重要性
消息键最重要的作用之一就是实现确定性分区。当生产者将消息发送到 Kafka 主题时,分区器(通常是默认分区器)会使用该键来确定分区。这确保了具有相同键的所有消息都发送到同一个分区,从而保留具有相同键的消息的顺序。
Kafka 保证分区内的消息顺序。通过使用键,生产者可以确保具有相同键的消息是有序的。例如,如果您正在发送用户活动日志并使用用户 ID 作为键,那么与特定用户相关的消息都将发送到同一个分区,并按照它们发送的顺序进行处理。
虽然键的主要作用是确保顺序和分组,但它也有助于跨分区的负载分发。当键分布均匀时,分区会保持平衡,这有助于优化性能并确保资源的有效利用。然而,选择不当的键可能导致分区倾斜,即某些分区处理的数据量远大于其他分区。
消息键实现了消息亲和性,即将相关消息分组在一起。这在金融交易等场景中尤其有用,其中特定账户的所有相关消息都必须一起处理以保持一致性。
在使用 Kafka Streams 的流处理应用程序中,消息键对于诸如连接、聚合和窗口化之类的状态化处理操作至关重要。这些操作依赖于消息键来正确关联和聚合数据。
随着 Kafka 对精确一次语义的支持的引入,消息键在确保幂等性和事务保证方面发挥着至关重要的作用。通过使用键,生产者和消费者可以管理偏移量并确保消息被精确处理一次。 消息键在 Kafka 架构中的工作原理Kafka 架构概述Apache Kafka 的架构围绕着一个分布式、分区日志系统构建。关键组件包括:
![]() 分区机制当生产者将消息发送到主题时,分区过程决定将消息发送到哪个分区。此过程涉及:
生产者配置生产者可以配置键和值的序列化方式,然后再将它们发送到 Kafka。常见配置包括:
消费者处理消费者按写入顺序从分区读取消息。他们可以配置反序列化器将字节数组转换回对象。消费者偏移量管理确保每条消息都被正确处理一次且按正确的顺序处理。 用例示例 考虑一个处理客户订单的零售系统。通过使用客户 ID 作为键,来自同一客户的所有订单都发送到同一个分区。这确保了订单以正确的顺序处理,从而保持数据一致性。 Kafka StreamsKafka Streams 大量利用消息键来进行状态化操作。例如,在窗口连接或聚合中,键确保相关记录一起处理。Streams API 提供了按键分组的方法,并执行连接和聚合等操作。 分区重新平衡当主题的分区被重新分配时(例如,由于分区数增加或 Broker 故障),Kafka 会尽可能确保键继续映射到相同分区。这最大限度地减少了对消息顺序和处理逻辑的影响。 挑战与最佳实践
高级主题
Apache Kafka 中的分区和消息键Apache Kafka 是一个分布式流处理平台,专为高吞吐量、容错数据流而设计。使 Kafka 强大且可扩展的关键功能之一是其分区机制。分区允许 Kafka 并行处理数据,水平扩展,并在每个分区内保持有序的消息处理。消息键在数据如何分区、路由和处理方面起着至关重要的作用。本节深入探讨了 Kafka 分区的概念、消息键如何影响分区以及使用键进行确定性消息路由。 ![]() Kafka 主题和分区在 Kafka 中,数据流被组织成主题。主题是记录被发布到的类别或馈送名称。每个主题可以分为多个分区。分区本质上是追加日志,消息在到达时按顺序存储。每个分区都由整数 ID 标识,并且可以驻留在 Kafka 群集的不同 Broker 上,从而实现并行性和可扩展性。 为什么需要分区?分区在 Kafka 中服务于多种目的:
分区如何工作
分区示例考虑一个名为“orders”的 Kafka 主题,其中包含三个分区。该主题可能在三个 Broker 上分布如下:
当生产者将消息发送到“orders”主题时,消息会被分发到这些分区。 消息键如何影响分区消息键的作用消息键是 Kafka 消息的可选属性,它们会影响消息如何在分区之间分发。当提供消息键时,Kafka 会使用该键来确定消息将被发送到的分区。如果未提供键,Kafka 会使用轮询或其他负载均衡策略将消息分发到各个分区。 ![]() 带键的分区逻辑Kafka 带有键的默认分区逻辑如下:
示例 对于一个有三个分区的主题,带键消息的分区逻辑可能如下所示:
确定性路由使用键可确保消息的确定性路由。这意味着具有相同键的所有消息将始终路由到同一个分区。这对于保持相关消息的顺序以及确保消息以一致的方式处理非常重要。 基于键的分区的优点
挑战与注意事项
使用键进行确定性消息路由确定性路由是 Kafka 分区机制的一个基本方面,它确保了消息如何在分区之间分发的_一致性和可预测性_。以下是使用键进行确定性路由的工作原理: 哈希函数Kafka 使用哈希函数来计算给定键的分区。默认的哈希函数是 MurmurHash,它是一种快速高效的非加密哈希函数。然后使用键的哈希值来确定分区。 分区分配分区分配公式为: partition = hash(key) % num_partitions 只要分区数保持不变,此公式就能确保相同的键始终映射到同一个分区。 示例 考虑一个名为“transactions”的 Kafka 主题,其中有四个分区。如果我们有键为“user1”、“user2”和“user3”的消息,则分区分配可能如下所示:
只要分区数保持不变,具有相同键的消息将始终路由到同一个分区。 处理分区重新分配当主题中的分区数发生变化时(例如,如果添加分区来扩展主题),则需要重新计算哈希函数和分区分配。这可能导致重新平衡,其中一些消息可能会被路由到与之前不同的分区。在更改分区数时需要仔细考虑,以最大程度地减少中断。 自定义分区器除了默认分区器之外,Kafka 还允许开发人员实现自定义分区器来控制如何根据键路由消息。自定义分区器可以使用不同的分区逻辑,例如:
实现自定义分区器自定义分区器的使用要使用自定义分区器,请使用自定义分区器类的完全限定名称配置生产者: Kafka 消息序列化器在 Apache Kafka 中,序列化是一个关键过程,它将数据转换为适合在网络上传输和存储的格式。Kafka 消息序列化涉及在将消息的键和值发送到 Kafka Broker 之前将它们转换为字节数组。在接收端,反序列化将字节数组转换回原始数据格式。此过程可确保数据能够高效且准确地传输和存储。 序列化和反序列化对于 Kafka 处理各种数据类型和结构至关重要,使其能够与不同的应用程序和系统无缝集成。让我们更深入地探讨 Kafka 消息序列化器、它们的重要性、常见类型以及如何实现自定义序列化器。 什么是 Kafka 消息序列化器?Kafka 消息序列化器是一种将对象或数据结构转换为字节数组的机制,该字节数组可以在网络上传输并在 Kafka 中存储。相应的反序列化器执行相反的操作,将字节数组转换回原始对象或数据结构。 在 Kafka 中,序列化应用于消息的键和值。Kafka 为常见数据类型提供了内置序列化器,并且还允许开发人员为更复杂或特定数据格式创建自定义序列化器。 ![]() 序列化的重要性
Kafka 中的内置序列化器Kafka 为常见数据类型提供了多种内置序列化器。这些序列化器是 Kafka 客户端库的一部分,可以在 Kafka 生产者和消费者中轻松配置。 1. StringSerializer: 将字符串转换为字节数组。 IntegerSerializer: 将整数转换为字节数组。 3. LongSerializer: 将长整型转换为字节数组。 4. ByteArraySerializer: 直接转换字节数组(当数据已经是字节数组格式时使用)。 5. ByteBufferSerializer: 将 ByteBuffer 转换为字节数组。 实现自定义序列化器对于更复杂或特定的数据格式,开发人员可以实现自定义序列化器。自定义序列化器在处理专有数据格式、复杂对象或与需要特定序列化协议的系统集成时特别有用。 创建自定义序列化器要在 Kafka 中创建自定义序列化器,您需要实现 Kafka 提供的 Serializer 接口。以下是 User 对象的自定义序列化器的示例: 1. 定义 User 类 2. 实现 Serializer 接口 使用自定义序列化器要使用自定义序列化器,请使用序列化器类的完全限定名称配置生产者: 反序列化对于反序列化,Kafka 提供了 Deserializer 接口。与序列化器类似,您可以通过实现此接口来创建自定义反序列化器。 实现自定义反序列化器1. 实现 Deserializer 接口 使用自定义反序列化器要使用自定义反序列化器,请使用反序列化器类的完全限定名称配置消费者: 输出 ![]() Kafka 序列化的最佳实践
Kafka Streams 如何利用消息键Kafka Streams 是 Apache Kafka 中的一个库,它以多种方式利用消息键来实现强大的流处理应用程序。理解 Kafka Streams 如何利用消息键对于设计高效且可扩展的流处理管道至关重要。 1. 状态化流处理Kafka Streams 支持状态化操作,如聚合、连接和窗口化。消息键对于维护状态一致性和实现高效的状态查找和操作至关重要。通过按键对消息进行分组,Kafka Streams 可确保所有相关事件一起处理,从而促进状态化计算。 示例输出 ![]() 2. 分区和并行性Kafka 主题被分区,分区内的消息按其偏移量排序。在处理流时,Kafka Streams 可确保具有相同键的相关事件被路由到相同的流任务,从而保持顺序和一致性。这种分区机制允许 Kafka Streams 应用程序进行水平扩展,并通过并行处理多个实例来实现高吞吐量。 示例输出 ![]() 3. 连接操作Kafka Streams 支持各种连接操作,包括内连接、外连接和窗口连接。消息键用于匹配和连接来自不同流或表的相关事件。通过根据键对消息进行对齐,Kafka Streams 可以实现高效的连接操作,而无需进行昂贵的 shuffle 或数据重组。 示例输出 ![]() 案例研究1. 电子商务平台:订单处理和履行场景: 一个电子商务平台处理来自全球客户的大量订单。为了有效地管理订单处理和履行,该平台为其事件驱动的架构采用了 Apache Kafka。客户生成的每个订单都包含一个唯一的订单 ID,该 ID 用作消息键。 Kafka 消息键的利用
2. 金融服务公司:实时欺诈检测场景: 一家金融服务公司运营一个支付处理平台,该平台每天处理来自数百万客户的交易。为了实时检测和防止欺诈活动,该公司采用 Apache Kafka 作为其欺诈检测系统的骨干。发送进行处理的每笔交易都包含一个唯一的事务 ID 作为消息键。 Kafka 消息键的利用
下一个主题最佳 Apache Kafka 书籍 |
我们请求您订阅我们的新闻通讯以获取最新更新。