说,我有一个应用程序,它从KAFKA读取一批数据,它使用传入消息的密钥并向HBase进行查询(从HBase读取这些密钥的当前数据),进行一些计算并写入数据返回HBase以获取相同的密钥集。例如。
{K1,V1},{K2,V2},{K3,V3}(来自KAFKA的传入消息)->我的应用程序(从HBase读取K1,K2和K3的当前值,使用传入值V1 ,V2和V3进行一些计算,并在处理完成后将K1(V1 + x),K2(V2 + y)和K3(V3 + z)的新值写回到HBase。
现在,假设我有一个用于KAFKA主题的分区,一个消费者。我的应用程序有一个处理数据的使用者线程。
问题在于HBase出现故障,这时我的应用程序停止了处理消息的过程,而KAFKA却陷入了巨大的滞后。即使我有能力增加分区的数量并相应地增加使用方,但是由于HBase中的RACE条件,我不能增加任何一个。 HBase不支持行级别锁定,因此,如果现在我增加分区的数量,则相同的密钥可以转到两个不同的分区,并且对应于两个不同的使用者,这些使用者最终可能处于RACE状态,最后写入的人就是赢家。在增加分区数量之前,我将不得不等待所有消息处理完毕。
例如
HBase崩溃->最初,我为该主题分配了一个分区,并且在分区0中存在未处理的消息-> {K3,V3}->现在,我增加了分区数量,并且密钥为K3的消息现在现在,假设在分区0和1中->然后,从分区0消耗的使用者和从分区1消耗的另一个使用者将最终竞争写入HBase。
有解决问题的方法吗?当然,由于消费者正在处理消息,因此锁定密钥K3并不是解决方案,因为我们正在处理大数据。
答案 0 :(得分:1)
一条消息将仅出现在一个kafka分区中。它在消息上使用哈希函数以分区数为模。我相信这项保证可以解决您的问题。
但是请记住,如果更改分区数,则可以将同一消息密钥分配给其他分区。如果您只关心每个分区只能保证的消息顺序,那可能会很重要。如果您不关心邮件的排序,则不能选择重新分区(例如增加分区数)。
答案 1 :(得分:1)
增加分区数量时,只有新消息会出现在新添加的分区中。 Kafka负责一次只处理一条消息
答案 2 :(得分:0)
正如Vassilis所说,Kafka保证单个密钥只能在一个分区中。
有here种如何在分区上分配密钥的方法。
当您增加分区数或更改分区策略时,可能会发生重新平衡过程,这可能会影响正常工作的使用者。如果停止使用者一段时间,可以避免两个使用者处理相同密钥的可能性。