怎么搞定Kafka重复消费?

怎样确保 Kafka 音讯不重复消费?咱们在做开发的时分为了程序的健壮性,在运用 Kafka 的时分一般都会设置重试的次数,可是因为网络的一些原因,设置了重试就有或许导致有些音讯重复发送了(当然导致音讯重复也有或许是其他原因),那么怎样处理音讯重复这个问题呢?关于这个问题,我这儿供给了如下三种处理计划,供咱们参阅。
处理计划
计划一 / 保存并查询
给每个音讯都设置一个绝无仅有的 key,消费的时分把 key 记载下来,然后每次消费新的音讯的时分都查询一下,看当时音讯的这个 key 是否消费过,假如没有消费过才进行消费。(这种办法好想,可是其实完成起来一点也不简略)
怎么搞定Kafka重复消费?
计划二 / 运用幂等
幂等(Idempotence)在数学上是这样界说的,假如一个函数 f(x) 满意:f(f(x)) = f(x),则函数 f(x) 满意幂等性。
这个概念被拓宽到计算机范畴,被用来描绘一个操作、办法或许服务。一个幂等操作的特点是,其恣意屡次履行所发生的影响均与一次履行的影响相同。一个幂等的办法,运用相同的参数,对它进行屡次调用和一次调用,对体系发生的影响是相同的。所以,关于幂等的办法,不必忧虑重复履行会对体系形成任何改动。
咱们举个比方来阐明一下。在不考虑并发的情况下,“将 X 教师的账户余额设置为 100 万元”,履行一次后对体系的影响是,X 教师的账户余额变成了 100 万元。只需供给的参数 100万元不变,那即便再履行多少次,X 教师的账户余额一直都是 100万元,不会改变,这个操作便是一个幂等的操作。
再举一个比方,“将 X 教师的余额加 100 万元”,这个操作它就不是幂等的,每履行一次,账户余额就会添加 100 万元,履行屡次和履行一次对体系的影响(也便是账户的余额)是不相同的。
所以,经过这两个比方,咱们能够想到假如体系消费音讯的事务逻辑具有幂等性,那就不必忧虑音讯重复的问题了,因为同一条音讯,消费一次和消费屡次对体系的影响是彻底相同的。也就能够以为,消费屡次等于消费一次。
那么,怎样完成幂等操作呢?最好的办法便是,从事务逻辑规划上下手,将消费的事务逻辑规划成具有幂等性的操作。可是,不是一切的事务都能规划成天然幂等的,这儿就需求一些办法和技巧来完成幂等。
下面咱们介绍一种常用的办法:运用数据库的仅有束缚完成幂等。
例如,咱们刚刚说到的那个不具有幂等特性的转账的比方:将 X 教师的账户余额加 100 万元。在这个比方中,咱们能够经过改造事务逻辑,让它具有幂等性。
首要,咱们能够束缚,关于每个转账单每个账户只能够履行一次改变操作,在分布式体系中,这个束缚完成的办法十分多,最简略的是咱们在数据库中建一张转账流水表,这个表有三个字段:转账单 ID、账户 ID 和改变金额,然后给转账单 ID 和账户 ID 这两个字段联合起来创立一个仅有束缚,这样关于相同的转账单 ID 和账户 ID,表里至多只能存在一条记载。
这样,咱们消费音讯的逻辑能够变为:“在转账流水表中添加一条转账记载,然后再依据转账记载,异步操作更新用户余额即可。”在转账流水表添加一条转账记载这个操作中,因为咱们在这个表中预先界说了“账户 ID 转账单 ID”的仅有束缚,关于同一个转账单同一个账户只能刺进一条记载,后续重复的刺进操作都会失利,这样就完成了一个幂等的操作。

计划三 / 设置前置条件
为更新的数据设置前置条件别的一种完成幂等的思路是,给数据改变设置一个前置条件,假如满意条件就更新数据,不然回绝更新数据,在更新数据的时分,一起改变前置条件中需求判别的数据。
这样,重复履行这个操作时,因为第一次更新数据的时分现已改变了前置条件中需求判别的数据,不满意前置条件,则不会重复履行更新数据操作。
比方,刚刚咱们说过,“将 X 教师的账户的余额添加 100 万元”这个操作并不满意幂等性,咱们能够把这个操作加上一个前置条件,变为:“假如X教师的账户当时的余额为 500万元,将余额加 100万元”,这个操作就具有了幂等性。
对应到音讯行列中的运用时,能够在发音讯时在音讯体中带上当时的余额,在消费的时分进行判别数据库中,当时余额是否与音讯中的余额持平,只要持平才履行改变操作。
可是,假如咱们要更新的数据不是数值,或许咱们要做一个比较复杂的更新操作怎样办?用什么作为前置判别条件呢?愈加通用的办法是,给你的数据添加一个版本号特点,每次更数据前,比较当时数据的版本号是否和音讯中的版本号共同,假如不共同就回绝更新数据,更新数据的一起将版本号 +1,相同能够完成幂等。

最终
今日给咱们供给的音讯重复的处理计划,也参阅了《音讯行列高手课》里的思路,咱们假如有什么好的处理计划,欢迎评论!