关于使用Kafka进行分布式处理(关于分区功能的理论学习)
以下内容针对初学者对Confluent进行了简化描述。
另外,假设读者已经理解以下内容,并使用Kafka术语进行了描述,请注意。
我尝试写了一篇关于Confluent平台魅力的文章。
关于Apache Kafka消息发送和接收(使用REST-PROXY)的内容。
摘要:用于Apache Kafka分布式处理的分区。
有时,仅通过一个程序按顺序处理大量的消息(记录)可能无法处理完。在这种情况下,通过将消息分散并在多个进程或多个服务器上进行分布式处理,以在单位时间内完成处理,我们称之为分区功能,并将其作为标准添加到程序中。本次我们将介绍有关分区的内容。
关于分区功能
在Kafka中,当进行分布式处理时,可以使用分区功能来将主题内的消息分割成多个分区。这就像字面上使用分区来分割队列的内容一样,但是要注意,分区数指的是被分割的容器的数量,而不是分隔符的数量。通过将分割后的每个分区的消息传递给分布式消费者程序(消费者),可以实现分布式处理。
为了识别消费者是相同的还是不同的,可以使用实例名(客户端ID)作为标识符。要识别分区,可以使用从0开始按顺序编号的分区号。1
将消息分散存储的是生产者。
消息分散是由生产者执行的,它将消息发送到各个分区。
将消息放入分区的规则共有三种方式(如果有多种情况符合,则优先选择较小的编号)。
- 在程序中明确指定分区号,在向生产者发送消息时,通过固定输入分区号来将消息注册到任意分区。根据键的值进行自动分配(哈希)。消息有两个字段,键和值,可以自由地放入数据。根据键的值计算哈希值并确定分区号。换句话说,通过使用相同的键可以部分控制将消息放入相同的分区。如果没有指定分区号且没有指定键,将以轮询方式将消息均匀地发送到所有主题。
消费者的分区分配
以前,我在”Apache Kafka消息发送和接收(使用REST-PROXY):消费者群组的作用(消费者的重启)”中简要介绍了消费者群组。通过在此消费者群组内创建实例并将实例与分区关联起来,实现了分布式处理。
中国語中只需要一种选择性地用以下方式转述:
关于连接方法,有两种选择:自动选择分区(Auto)和固定选择静态分区(Static)。除非有特殊原因,建议使用自动选择分区,即使分布式程序由于服务器故障等停止,剩余程序仍然可以继承消息。
※ 在消费者组内部不能混合使用自动选择分区和静态分区。如果尝试混合使用,将在订阅时出现错误。
静态分区分配
通过指定消费者组,可以将消费者与分区关联起来,同时也需要指定消息抽取的分区号。由于分区号是固定分配的,因此需要进行正确的管理,以确保没有漏掉分配分区的情况,并且需要在消费者程序中编写逻辑,以控制其他程序在消费者停止运行时接管消费逻辑等。
自动分配分区。
根据消费者群组内实例的数量进行均匀分配分区。每当实例数量发生变化时,动态调整分配以保持持续的分散形式。
如果实例数等于分区数的情况
如果实例数量和分区数量相同,则它们将一对一地分散。这是一种非常直观的分散方法。
另外,如果有实例数量的整数倍的分区,则它们也会被均匀分配,因此非常容易理解。
如果分区数小于实例数
每个实例的分区数量被尽量均匀分布。
无法均匀分配的分区余下的部分将被分配给一些实例,每个实例分配一个。
<<动作总结>>
被分配了多个分区的实例会按照第一个分区中剩余的数据顺序进行读取。
当所有的消息都被加载到分区中时,下一个分区将开始读取消息,直到剩余的消息数量为0。
如果有多个实例,而不是分区的情况下。
如果实例数量多于分区数量,则将根据分区数量对每个实例进行关联。
“简要动作描述”
在分配时剩余的实例将变为热备用状态,无法分配到分区中。
当关联的实例结束(包括异常结束)时,已结束实例的分区将被分配给新的实例,并继续进行处理。
在中文中,希望有多少个分区合适?
到目前为止,我们已经解释了关于分区操作的内容,现在我们来解释一下在实际使用中如何设计分区数。
※ 这种设计思路不能在所有情况下都适用,仅作为基本指标参考。
首先,让我们考虑实例故障的情况。例如,服务器硬件故障、程序错误等可能导致实例发生故障并停止运行。在这种情况下,可以考虑三种方案,即在退化时保持均等分散、在退化时部分实例接管以及通过热备份进行接管。
※ 也可以考虑根据不同的标准来设计,以便在正常情况下也能考虑到将来的扩展。
如果优先考虑均等化
这是一种被广泛利用的分散方法。它是通过取得实例数的最小公倍数,从通常时的数量到衰退时的数量。
-
- 5台のインスタンスがあり同時故障が1台の縮退時4台の場合
-
- 5,4の最小公倍数の20になります。
-
- 5台稼働中は、1インスタンス当たり4パーティション割り当てられます
-
- 4台に縮退した時は、1インスタンス当たり5パーティション割り当てられます。
-
- 5台のインスタンスがあり同時故障が2台の縮退時3台の場合
-
- 5,4,3の最小公倍数の60になります。
-
- 5台稼働中は、1インスタンス当たり12パーティション割り当てられます。
-
- 4台に縮退した時は、1インスタンス当たり15パーティション割り当てられます。
- 3台に縮小した時は、1インスタンス当たり20パーティション割り当てられます。
可以始终将资源均等地分配,即使在退化时也是如此。
如果要进行缩减并传递给一部分实例的情况下
将实例数与分区数设置为相同的方法。
考虑到故障情况较少发生,并且实例资源充裕的情况下使用。
如果通常运行中的机器数量为5,
当1台发生故障时,剩下的4台中有1台执行2倍于平常的处理任务,另外3台执行与平常相同的处理任务。
当2台发生故障时,剩下的3台中有2台执行2倍于平常的处理任务,剩下的1台执行与平常相同的处理任务。
由于在故障时需要两倍的资源,因此需要在具有故障时资源充裕的服务器上运行。它具有易于理解和管理的运营特点。
通过热备份进行接管的方法
当最大障碍预设数的实例比分区还多运行时,使用热备份方式。
发生障碍时,将由热备份上的实例接管。
在热备机上运行可以保持性能稳定,但需要提前保留一定的空闲资源。
有些情况下,由于程序要求的限制,无法进行分布式处理。
有时,程序可能需要考虑消息的先后关系以及所有值的统计。由于相关消息可能会被加载到不同的进程中,分散处理会变得复杂。
如果每个消息都可以独立处理(按键分组),那么使用Kafka进行分布式处理将发挥最佳效果。
※有关分散的必要性等,应在设计阶段确定,因此在这里不会详细解释。请根据需求考虑使用的方法。请考虑根据需求选择使用方式。
填补
根据程序的内容,可能无法进行分散处理,或者可能是不适当的情况。并非能够涵盖所有情况,因此在程序开发的设计阶段,请您对分散处理的可能性进行评估是可取的。
请查阅参考资料。
只有对哈希算法非常想了解的人。
如果有人关心生产者的哈希算法,他们应该自己指定分区号进行控制。
即使你还对哈希算法感到担忧,我也会提供源代码中相关部分的链接,让你自己阅读源代码。所涉及的部分是`return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;`。
这是指定了默认算法(DefaultPartitioner)的生产者配置ProducerConfig.PARTITIONER_CLASS_CONFIG。
创建主题时需要指定分区数。请注意,一旦指定了分区数,就无法在后续动态更改。
如果希望控制分布规则,请使用(适用于高级用户)。
当键值不同时,消息不一定会分配到不同的分区上,有时也可能分配到同一个分区。
为了实现均匀分配,需要有多种键值类型。
哈希算法可以自定义,但必须对所有生产者使用相同的算法,才能正确进行分布,请注意。
分区号的顺序是随机决定的,但采用的算法会均衡每个分区的消息数量。