kafka
Apache Kafka 是一个分布式的流数据平台,最初由LinkedIn公司开发,后成为 Apache 基金会的开源项目。Kafka 主要用于解决高吞吐量、低延迟的实时数据传输和处理问题,特别适用于日志收集、流式处理、事件驱动等场景。
特点
kafka有如下特点:
- 高吞吐量:Kafka每秒可以处理数十万条消息的写入和读取。
- 分布式:Kafka采用分布式架构,可以将消息分布在多个节点上进行存储和处理。
- 持久化:Kafka使用磁盘持久化消息,可以将消息持久保存在磁盘上,即使消费者不在线也不会丢失消息。
- 发布-订阅模型:Kafka采用发布-订阅模型,允许生产者将消息发布到一个或多个主题(Topic),而消费者可以订阅一个或多个主题来接收消息。
- 分区和副本:Kafka将每个主题分成多个分区(Partition),每个分区可以在多个节点上进行复制以提供冗余和可靠性。
- 实时处理:Kafka支持实时数据处理,可以与流处理框架(如Apache Flink和Apache Spark)集成。
- 消息保留:Kafka可以根据配置的策略保留消息的时间或大小。
- 可扩展性:Kafka可以水平扩展,通过添加更多的节点来增加处理能力和存储容量,而不会中断现有的消息流。
Partition
在 Kafka 中,分区(Partition)是一种逻辑上的数据划分方式,它将一个主题(Topic)的数据分成多个部分,每个分区都是一个有序、持久化的日志队列。每个分区都可以独立地存储和管理数据,Kafka 使用分区来实现高吞吐量和水平扩展。
分区的特点
- 水平扩展: 分区允许将一个主题的数据划分为多个分区,每个分区可以在不同的 broker 节点上存储。这样可以实现数据的水平扩展,提高了整个系统的吞吐量。
- 顺序性: 在一个分区内,数据的顺序是有保障的,即使在不同分区之间数据的顺序不保证,但在同一分区内的数据会按照写入的顺序存储和读取。
- 容错性: Kafka 使用分区的复制机制来实现数据的冗余备份,保证数据的可靠性。一个分区可以有多个副本(Replica),每个副本位于不同的 broker 节点上,如果某个副本不可用,可以通过其他副本来恢复数据。
- 负载均衡: 通过调整分区的数量和分布,可以实现对消息消费者的负载均衡。消费者可以同时从多个分区中读取数据,从而提高消费的并行度。
副本因子
副本因子(Replication Factor)是指 Kafka 中每个分区的副本数。副本因子是 Kafka 实现高可用性和数据冗余的关键机制之一。通过为每个分区设置多个副本,可以确保分区数据的冗余存储,即使某个 Broker发生故障,也能够从其他拥有该分区副本的 Broker上继续提供服务,保证数据的可用性。
副本因子的设置在创建主题(Topic)时进行,可以根据需要设置不同的副本因子。一般来说,副本因子的设置涉及到可用性、性能、资源开销等方面的权衡。常见的副本因子设置有以下几种情况:
- 副本因子为1:这意味着每个分区只有一个副本,没有冗余。适用于单点故障没有太大影响的场景,或者测试环境等不要求高可用性的情况。
- 副本因子大于1:常见的设置为2或3。设置2个副本时,数据有两个拷贝,一个在主分区(Leader)上,一个在副本分区(Follower)上;设置3个副本时,数据有三个拷贝,一个在主分区上,另外两个在两个副本分区上。这种设置提供了基本的冗余和故障转移能力,能够抵御一台 Broker 节点的故障。
- 更高的副本因子:如果对可用性和数据保护要求较高,可以设置更多的副本。但副本因子越高,数据的冗余和复制开销就越大,需要更多的存储空间和网络带宽。
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 2 --partitions 3 --topic mytopic
上述命令会创建一个名为 "mytopic" 的主题,设置分区数为 3,副本因子为 2,表示每个分区都有两个副本。
需要注意的是,分区数的设置一旦确定后,就不能直接修改。如果需要修改分区数,可以考虑创建一个新的主题,并将数据从旧主题迁移到新主题。
分区数的合理设置需要根据实际的业务需求和数据规模来进行调优,合适的分区数能够充分利用 Kafka 集群的资源,提高消息的并行处理能力。
消息保留策略
在kafka中消费者消费消息后,消息仍然可以在 Kafka中存在一段时间,以便满足后续需求,如重新消费或审计等。Kafka 提供了两种常见的消息保留策略:
- 时间保留策略(Time-based Retention):根据消息的时间戳进行保留。可以配置一个保留时间段,超过该时间的消息将被删除。
- 大小保留策略(Size-based Retention):根据消息的大小进行保留。可以配置一个保留消息总大小的阈值,当消息大小超过该阈值时,较早的消息将被删除。
二次消费
根据kafka的消息保留策略可以看出来,kafka支持重新消费,我们可以通过重置/修改消费者组的偏移量进行重新消费,或者创建新的消费者来重新消费。
消息的有序性
在kafka中,同一个分区内的消息是有序的,但是不同分区的消息之间无法保证顺序,而且消费者组通常不会配置单线程,这就导致topic中的消息不是完全有序消费的。
如果想要实现消息的有序性,可以考虑以下几点:
- 单个分区:首先,确保每个主题只有一个分区。
- 消费者线程:为了保证顺序,每个分区应该只被一个消费者线程消费。
- 消息的生产和分区键:如果消息的顺序非常重要,可以考虑在生产者端使用消息的分区键来确保相关消息被分配到同一个分区。
- 应用层面:在应用层面做额外的处理,例如在消费者端根据消息的时间戳来排序。
什么是分区键
Kafka 的分区键是一个用于指定消息被分配到哪个分区的值。分区键是由生产者在发送消息时指定的,它决定了消息被分配到哪个主题的哪个分区中。一些常见的选择分区键的策略:
- 根据消息的关键属性:根据消息的某个关键属性,例如用户 ID、产品 ID 等,来作为分区键。这样,具有相同属性的消息会被分配到同一个分区,便于保证有序性和数据的聚合。
- 轮询分区:如果希望负载均衡,可以采用轮询分区的策略,让每个生产者按照轮询顺序选择分区,确保消息均匀分布。
- 随机分区:对于一些场景,如果消息的顺序不是特别关键,可以采用随机分区的策略,将消息随机分配到分区中。
ack机制
Kafka 使用了一种 ack(Acknowledgment)机制来确保消息的可靠性传递。有以下几种设置:
- acks = 0:生产者不需要等待任何服务器的确认。这种方式存在最高的风险,因为如果发送的消息在传输过程中出现问题,生产者将无法得知。消息可能会丢失或发送失败。
- acks = 1:生产者会等待消息被主题的 leader 分区成功写入。如果 leader 成功写入消息,生产者将收到一个确认响应。但在这种模式下,仍然有可能出现副本同步失败,因此消息仍然有丢失的风险。
- acks = all:生产者会等待消息被主题的所有副本成功写入才会收到确认响应。这是最安全的模式,确保了消息的高可靠性。但这也会增加一定的延迟,因为需要等待所有副本写入成功。