Kafka 2024-10

4 阅读8分钟

kafka 键的生成和意义

Apache Kafka 是一个分布式流处理平台,它允许发布和订阅记录流,同时提供了高吞吐量、高扩展性和持久性。在Kafka中,消息是以键值对的形式发送的,其中键(Key)和值(value)都是字节数组。键的使用是可选的,但是某些场景下,使用键可以为消息传递提供更多的控制和灵活性。

kafka 中键的作用:

1. 分区选择

当生产者发送消息到一个主题时,如果没有指定键,则默认下,消息会被轮询分配到该主题的所有分区中,来确定消息应该发送到哪个分区。这里通常基于键的hash值来决定,因此具有相同键的消息将会被发送到同一个分区。

2. 数据路由

使用键可以帮助实现更细粒度的数据路由,例如:如果应用程序需要确保所有关于某个用户的活动记录被存储在一起,那么可以使用用户的唯一标识来作为键

3. 消费端处理

消费者可以根据键来过滤或者聚合消息。如:在处理事件驱动的应用程序时,消费者可能会根据键来决定是否处理特定的消息

如何生成键

键的生成取决于你的业务需求,通常,键的选择应该遵循以下原则:

  • 唯一性:如果键用于标识唯一的实体或事件,则键应该唯一
  • 一致性:如果键用于确保相关消息被分发到相同的分区,则键应该在逻辑上保持一致
  • 简洁性:键通常上应该尽可能的短小,因为较长会增加存储开销

键可以由应用程序生成,也可以由kafka的生产者客户端自动设置。如果应用程序本身没有生成键的需求,那么可以依赖Kafka生产者的默认行为。如果需要自定义键,则可以在发送消息时明确指定。

kafka 键这个概念中,提到的Hash(或者叫做散列)这种技术

是一种将任意长度的数据映射为固定长度值的技术。这个映射过程使用一种被称为散列函数的算法来实现。

输入(Message):可以接收任意长度的数据作为输入

输出(digest):散列函数产生固定长度的数据作为输出

不可逆性:理想情况下,散列函数是单向的

抗碰撞性:好的算法,当使用不同的输入时产生不同的散列值,即时存在碰撞(相同的值),这种情况也是十分罕见的

散列的应用:

  • 密码存储(将明文密码进行散列运算,存储和校验)
  • 数据完整性检查(文件传输过程中,使用散列值来校验数据的完整性)
  • 数字签名(使用散列值来代替原始数据)
  • 数据结构(哈希表,使用hash值快速索引出值)

算法特性

  • 确定性:相同输入,必定输出相同输出
  • 高效性:散列函数的计算是高效的
  • 均匀分布:好的散列函数产生的散列值是均匀分布的

常见算法

  • MD5:高效,不够安全
  • SHA系列:安全(SHA-1、SHA-256、SHA-512)
  • CRC32:常用于检测数据传输错误,但不是加密散列函数

由Kafka 吞吐量,思路软件系统中的吞吐量和时延性

在软件系统设计和优化过程中,吞吐量和时延是两个非常关键的性能指标。但是这两者之间往往存在权衡关系,提升其中一个指标肯能会牺牲另一个指标的表现。找到软件系统中最佳的平衡是我们构建优秀系统的关键。

吞吐量:单位时间内能够处理的请求数量,吞吐量高,表示单位时间内处理的请求数越多。(TPS)

时延:请求发出到系统响应之间的时间,时延越是低,表示系统的响应越快,用户体验越好

平衡策略

  • 资源管理

    • 负载均衡:使用负载均衡来分散请求到多个服务器上,可以提高吞吐量,同时减少单个节点的负载,从而降低时延
      
    • 动态调度资源:根据实时负载情况动态调整资源分配,比如:弹性伸缩机制来应对流量变化
      
  • 缓存策略:

    利用缓存可以显著减少后端服务的压力,提高吞度量。同时合理设计缓存机制可以减少不必要的计算,降低时延

  • 异步处理

    让系统在等待耗时操作(I/O、外部请求调用等)的同时继续处理其他请求,提高吞吐量。使用消息队列 、事件驱动架构等方式可以有效降低时延

  • 并发控制

    适当的增加并发处理能力可以提高吞吐量,当过多的并发可能导致资源争用,反而增加时延。合理设置线程池大小或其他并发机制参数,可以优化性能

  • 数据存储优化

    对数据查询进行优化(索引管理、查询优化等),减少数据检索的时间,从而降低时延;

    使用NoSQL数据库或内存数据库,可以提供更快的读写速度,有助于提高吞吐量和降低时延

  • 网络优化

    优化网络通信协议,减少数据包大小,使用压缩技术等可以减少网络延时。

    使用CDN可以缩短用户与服务器之间的距离,降低网路延时

  • 监控和分析

    实施全面的性能监控和分析,及时发现瓶颈,并针对性的进行优化调整

Kafka 消息数据格式

消息的组成,是Key和Value,此外消息还包含一些元数据:主题名称、分区编号、时间戳等

值: 主要的负载部分,包含实际传输的数据,值可以是任意类型的数据,通常是序列化或结构化后的数据:JSON、XML、Protobuf等格式

根据具体应用需求,选择合适数据格式

  • 性能要求:高性能应用,应选择体积小、解析快的格式,如:protobuf、avro
  • 可读性:对于需要人阅读的和编辑的数据应选择:JSON或XML
  • 兼容性:如果需要和现有系统集成,要保持的数据格式一致
  • 扩展性:如果数据格式可能发生变化,可以考虑Avro或者Thrit,他们支持模式演进

Kafka的消息有序性是怎么保证的

消息的有序性是一个很重要的话题,特别是某些重要的场景中,消息的顺序可能直接影响处理结果的正确性。Kafka默认保证同一分区内的消息顺序是一致的。跨分区的消息是不一致的。因为同一分区的消息,写入Broker是按照追加写入的方式。消费者消费消息也是按照顺序消费的。

网络对kafka的消息的影响

  • 消息延迟:如果网络延迟较大,生产者发送的消息可能会被预期的晚到达Broker
  • 消息丢失:如果网络中断,将导致消息丢失,生产者通常会重试发送消息
  • 消息重复:如果网络问题导致消息确认失败,消费者可能会重新消费已经处理过的消息

应对网络问题

  • 重试机制:生产者配置重试机制,确保消息成功发送到broker
  • 确认机制:生产者可以启用确认机制,确保消息发送成功,如果失败了,可以进行重试
  • 健康检查:定期对网络连接进行健康检查,确保网络连接的稳定性
  • 日志记录:记录网络问题发生的相关信息,以使后续诊断和解决问题

生产者数量大于分区数,会造成生产者无法发送消息?

不会,当生产者的数量大于分区数时,会造成某些生产者竞争同一分区的写权限。会造成生产效率问题。解决的方法是:

  1. 增加分区数
  2. 负载均衡策略:使用消息的键来控制消息的分配,或者自定义分区器来实现更细粒度的控制
  3. 生产者配置:增加生产者批量发送的大小、减少请求超时时间

消费者重启会重新选择分区么?

如果有3个分区,只有一个消费者,那么是否有消息无法被消费

Kafka的缺点

如何解决单个分区过高的吞吐量导致的性能问题