阅读时间: 6 分钟
在较早的博客中,我们介绍了Kafka的基本术语,并进一步深入了Zookeeper。现在,让我们详细讨论主题分区和副本。
主题分区
主题(Topic)或称消息队列,是您在Kafka中数据的存放位置。主题的数据进一步分为多个分区(Partition)。每个分区都是有序的,不可变的记录序列,这些记录连续地附加到结构化的提交日志中。
当发布带有密钥的消息(带密钥的消息)时,Kafka根据密钥的哈希确定性地将消息映射到分区。这样可以保证具有相同密钥的消息始终被路由到同一分区。对于没有密钥的消息,Kafka会将其随机映射到任何分区中。
偏移量
分区中的每个消息都有一个称为其偏移量(offset)的标识符 。它是消息队列的不可被生产者或消费者更改的序号,由Kafka系统维护。消费者可以从特定的偏移量开始读取消息,并可以从他们选择的任何偏移量点进行读取,从而允许消费者在他们认为合适的任何时间点加入集群。
分区越多,吞吐量越高
主题分区是Kafka中并行性的单位。在使用者角度来看,Kafka始终将单个分区的数据提供给一个使用者线程。因此,使用者(在使用者组内)的并行度受要使用的分区数限制。因此,通常,Kafka群集中的分区越多,可以实现的吞吐量就越高。
更多分区的陷阱
- 需要更多文件处理程序
每个分区都映射到代理中文件系统中的目录。在该日志目录中,每个日志段将有两个文件(一个用于索引,另一个用于实际数据)。对于每个日志段,每个代理都打开包含索引文件和数据文件的文件句柄。
如果存在大量分区,则打开文件的总数可能非常庞大。虽然这可以通过调整配置来解决。
我们可以使用以下命令查看打开的文件数:lsof | wc -l
使用以下命令可以解决此问题:ulimit -n <noOfFiles>
- **端到端延迟
**从生产者发布的消息到消费者读取的消息之间的时间称为延迟。Kafka仅在提交消息后(即,将消息复制到所有同步副本时)才将消息公开给使用者。因此,提交消息的时间可能是端到端延迟的重要部分。鉴于默认情况下,对于在两个代理之间共享副本的所有分区,默认情况下,Kafka代理仅使用一个线程从另一个代理复制数据。
例如,假定一个代理上有1000个分区领导者,并且它是两个具有复制因子为2的代理的Kafka集群。第二个代理需要从第一个代理中获取500个分区。一个线程负责将这些分区从代理1提取到代理2。这将花费足够的时间。但是,在大型群集的情况下,这一点不会引起问题,因为每个代理只需负担少量复本。
在Kafka中复制
复制(Replication)意思是在集群上保留数据的副本,以便在任何应用程序中提升可用性功能。Kafka中的复制处于分区级别。每个分区在群集上具有0个或多个副本。
上例中,我们在代理(Broker)1和2中具有分区0,在代理1和4中具有分区1,在代理3和4中具有分区2。在这些副本中,其中一个分区将充当领导者(主分区),而其他分区将作为跟随者(从分区)。
领导者负责发送和接收该分区的数据。
因此,当我们说一个主题的复制因子为2时,这意味着其每个分区拥有两个副本。当同步副本集(In-Sync Replica set, 简称ISR)中的所有副本均已确认已将记录写入磁盘时,Kafka认为记录已提交。
Kafak 确认机制
生产者可以选择使用 “acks” 设置来接收对写入分区的数据的确认。
ack-value是Apache Kafka中的生产者配置参数,它定义仅应从同步副本中等待的确认数。可以将其设置为以下值:
ACK=0 [NONE]
当ack值设置为0时,生产者将永远不会等待来自代理的确认。无法保证代理已收到消息。生产者不会尝试再次发送记录,因为生产者从不知道记录丢失了。此设置提供了较低的延迟和较高的吞吐量,但以更高的消息丢失风险为代价。
ACK=1 [LEADER]
将ack值设置为1时,生产者将在领导者收到记录后得到ack。领导者会将记录写入其日志,但会在不等待所有关注者的完全确认的情况下做出响应。仅当领导者在确认记录之后但在追随者复制它之前立即失败时,该消息才会丢失。此设置是延迟,吞吐量和持久性的中间依据。它比acks = 0慢,但更耐用。
ACK= -1 [ALL]
将ack值设置为all意味着当所有同步副本都收到记录时,生产者将获得ack。领导者将等待全套同步副本确认记录。这意味着发送带有所有ack值的消息要花费更长的时间,但是它提供了最强的消息持久性。
什么是ISR?
同步副本是与其领导者(即与领导者具有相同消息/或同步信息的跟随者)同步的复制分区ISR数并不强制性要求等于副本数。
“同步”的定义取决于主题配置,但是默认情况下,这意味着副本在最近10秒钟内已经或已经完全与领导者同步。此时间段的设置为:replica.lag.time.max.ms,并具有服务器默认值,可以按每个主题覆盖该服务器默认值。
追随者通过定期发送获取请求(默认情况下每500毫秒发送一次)来将数据从领导者复制到自己。
如果追随者失败,则它将停止发送获取请求,并且在默认值10秒钟之后,将从ISR中删除。同样,如果追随者速度变慢,可能是与网络有关的问题或服务器资源受限,那么一旦它落后于领导者超过10秒钟,就会将其从ISR中删除。
min.insync.replicas
值指定了必须全部确认写入后才能视为写入成功的最小副本数,因此,它对负责写入的生产方具有影响。此配置参数对消费方没有任何直接影响,这就是为什么它不影响消费者的原因,即使有效经纪人的数量小于的值 min.insync.replicas
。
当生产者将acks设置为“ all”(或“ -1”)时,min.insync.replicas指定必须确认写入才能使写入成功的最小副本数。如果不能满足此最小值,则生产者将引发异常(NotEnoughReplicas或NotEnoughReplicasAfterAppend)。
一起使用时,min.insync.replicas 和 acks 可使您实施更大的可用性保证。典型的情况是创建一个复制因子为3的主题,将min.insync.replicas 设置为 2,并设产生者确认为 “all”。如果未收到大多数副本写入,这将确保生产者引发异常。
有什么好处?
如果任何一个代理崩溃或由于网络问题而无法访问,其中一个副本将成为领导者。
只有属于同步副本列表的一部分的副本才有资格成为领导者,并且无论何时对其进行任何更改,同步副本的列表都会保留给zookeeper。同样,只有在至少有一个同步副本时,Kafka才会保证不会丢失数据。
如果没有此类副本,则此保证不适用。
这就是主题分区,复制和ISR的全部内容。我将在进一步的博客中介绍有关Kafka的更多信息。编码愉快!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。