Kafka系列——详细介绍Kafka的 Topic 分区, 复制和 ISR

Topic Partitions

Topic 就是数据主题,一个逻辑概念,可以用来区分业务系统。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。

Topic下的数据会被进一步分配到分区中(partitions),Partition 是最小的存储单元,掌握着一个 Topic 的部分数据。每个 Partition 都是一个单独的 log 文件,每条记录(消息)都以追加的形式写入。

当发布带有key的消息(message with key)时,Kafka 根据key的hash值确定性地将消息映射到分区。保证带有相同key的消息总是存储在相同的分区中。对于没有key的消息,kafka将会随机存储到分区中。

Offset

Partition 中的每条记录有一个唯一的序号,称为 Offset(偏移量)。Offset 是一个递增的、不可变的数字,由 Kafka 自动生成。

当一条记录写入 Partition 的时候,它就被追加到 log 文件的末尾,并被分配一个序号,作为 Offset。

消费者可以从特定的偏移量开始读取消息,并被允许从他们选择的任何偏移点开始读取,从而允许消费者在他们认为合适的任何时间点加入集群(即动态添加消费者)。

分区越多,吞吐量越高?

每个分区都可以独立地被写入和读取,因此在Kafka中topic中一个分区就是一个并发处理单元。在消费者方面,一个分区中的数据kafka只会允许一个消费线程消费(同一Consumer Group下的)。因此消费者(同一Consumer Group下)的并发度受限于被消费的分区数。

因此通常来说,在Kafka集群中,越多的分区意味着更高的吞吐量。

分区过多的影响

  • 需要更多的文件句柄

每个分区映射到文件系统中的一个(log)目录。在该日志目录中,每个日志段将有两个文件(一个用于索引,另一个用于实际数据)。对于每个日志段,都会打开索引文件和数据文件的文件句柄。如果有大量分区,打开文件的总数可能会非常大。

  • 端到端延迟

生产者发布消息到消费者读取消息之间的时间称为Lag(延迟)。

Kafka 仅在消息提交后将消息暴露给消费者,即当消息被复制到所有同步副本时才可以由消费者消费。

因此,提交(commit)消息的时间可能是端到端延迟的重要部分。

举个例子,假设在一个Broker上有 1000 个分区领导者,它是有 2 个Broker,复制因子为 2的 Kafka 集群。第二个Broker需要从第一个Broker获取500个分区。kafka默认使用单个线程将这些分区从 Broker 1 获取到 Broker 2。这将花费相当多的时间。

Kafka中的复制

复制只是意味着在集群上保留数据的副本,以提高任何应用程序中的可用性功能

Kafka 中的复制是在分区级别。每个分区在集群上有 0 个或多个副本。

在上图中,我们在Broker 1 和 2 中有分区 0,在Broker 1 和 4 中有分区 1,在Broker 3 和 4 中有分区 2。

在这些副本中,一个分区将充当领导者(leader),其他分区(在本例中为 1 个副本)充当追随者(followers)。

Leader 负责为该分区发送和接收数据。

因此,当我们说一个主题的复制因子为2时,这意味着我们每个分区将拥有两个副本。

当在同步复制集(ISR)中所有副本都确认他们已经将消息(record)写入磁盘时,Kakfa才认为消息(record)被提交了。

确认机制

生产者可以通过设置“acks”,来接收对写入分区的数据的确认。

ack-value 是 Apache Kafka 中的生产者配置参数,可以设置为以下值:

  • ACK=0 [NONE]

当ack值被设置为0时,生产者不会等待来Broker的ack。不保证Broker是否已经接收到消息。生产者也不会尝试再次发送记录,因为生产者不知道记录是否丢失了。

这种设置带来了更低的延迟和更高的吞吐量,但代价是信息丢失的风险要高得多。

  • ACK=1 [LEADER]

将ack值设置为1时,producer在leader收到record后收到ack。leader会把记录写到它的日志中,并作出回应,而不必等待所有followers的全面确认。

仅当领导者在确认记录后但在追随者复制记录之前立即失败时,消息才会丢失。这个设置是延迟、吞吐量和耐用性的折中。它比acks=0更慢,但更数据持久性更好。

  • ACK= -1 [ALL]

将 ack 值设置为 all 意味着当所有同步副本都收到记录时,生产者将获得 ack。领导者将等待所有副本都确认这个记录(消息)。

这意味着发送一个ack值为all的消息需要更长的时间,但是提供了最强的消息持久性

什么是 ISR?

同步副本(ISR,In-Sync Replicas)是与其领导者保持同步的复制分区,即那些与领导者具有相同消息(或同步)的追随者。不强制要求 ISR 等于副本数;

“同步”的定义取决于Topic的配置,但默认情况下,它表示副本在最近 10 秒内和领导者保持一致,具体的可以由replica.lag.time.max.ms 设置,并且有一个服务器默认值,也可以由每个Topic覆盖。跟随者通过定期发送Fetch请求,将数据从领导者复制到自己身上,默认情况下每500ms一次。

如果跟随者获取数据失败,那么它将停止发送获取请求,并且默认在10s之后,将从 ISR 中被删除。同样,如果跟随者速度变慢,可能是网络相关问题或服务器资源受限,那么一旦它落后于领导者超过 10 秒,它就会从 ISR 中移除

min.insync.replicas 规定了必须确认写入的最小副本数,满足该值才可认为此次写入成功,因此,它对负责写入的生产者端产生影响。这个配置参数对消费者方面没有任何直接影响,这就是为什 即使 alive broker 的数量小于 min.insync.replicas 的值,它不影响消费者的原因。

当生产者将 acks 设置为“all”(或“-1”)时,min.insync.replicas 指定必须确认写入才能被视为成功的最小副本数。如果不能满足这个最小值,那么生产者将引发一个异常(不是NotEnoughReplicas就是NotEnoughReplicasAfterAppend)。

当一起使用时,min.insync.replicas 和 acks 允许你执行更大的持久性保证。一个典型的场景是创建一个复制因子为 3 的Topic,将 min.insync.replicas 设置为 2,并设置ack="all"(或“-1”)。这将确保如果大多数副本没有收到写入,生产者会引发异常。

ISR的好处

如果万一其中一个broker宕机(其上有leader)或由于网络问题无法访问,其中一个副本将成为领导者。

只有在同步复制(ISR)列表中的复制才有资格成为领导者,并且每当同步复制的列表发生任何变化时,都会持久化到zookeeper中。另外,Kafka对数据不丢失的保证只有在至少存在一个同步复制的情况下才适用。

在没有这种副本的情况下,将无法保证数据不丢失。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值