消息系统端到端Exactly

  • 时间:
  • 浏览:9
  • 来源:uu快3和值_uu快3app_计划师

在Broker Failover的已经 ,都要将Broker内存中各个Producer当前写入的SequenceID完全恢复出来,不可以 保证数据exactly-once写入。在持久化的数据中,有每条消息的ProducerID和SequenceID信息,可不都要通过扫描持久化信息进行恢复,共同为了加快恢复速度单位,可不都要定期将Broker内存中的HashMap作为snapshot保存下来,在恢复的已经 ,首先恢复snapshot,因此 只都要读取极少量的信息完成ProducerID和SequenceID映射重建。

上图是常见的消息系统(如Kafka/Plusar/sls loghub等)的架构,消息(message)由生产者(Producer)发送至消息系统的接收者(Broker),Broker将Message持久化到特定分区(Partition)后,供消费者(Consumer)进行消费。在这俩 过程中,任意阶段都肯能出错。

在完成exactly-once写入后,为了支持端到端的exactly-once补救, 同样都要消费端的配合,这里主要处于消费端failover时,如可确保每条消息只被补救一次。 觉得不少消息系统提供ack机制,消费者只需关系数据的补救即可,如Plusar提供的consumer会自动拉注销息供应用消费,应用只都要关心消息的补救,在补救完毕后,对消息进行ack即可。

因此 ,为了支持exactly-once消费,都要将消息补救的结果(通常使用具体具体情况示)和消息的ID持久化到一些内控 系统中,以确保failover能恢复到某个完全精确的具体情况继续消费,如flink使用的checkpoint机制,将flink内控 某时刻具体情况以及消费的位置信息进行持久化。

在分布式场景下,做全局全量数据的原子排他性操作,成本无法接受的。那退而求其次,在一定限定条件下,则可不都要更高效达到exactly-once的效果。可不都要从以下两方面进行限定:

即使没办法 ,肯能在消费过程中,会额外产生结果并写入一些下游系统时,肯能那些系统不支持幂等操作,没办法 在failover时,consumer重复消费数据时,下游系统还肯能看完at-least-once的结果(如消费信息进行短信报警的场景)。

当Producer Failover的已经 ,对于次要数据源和SequenceID可映射的场景,可不都要根据ProducerID从Broker中获取最新的SequenceID,根据该ID对数据源进行重置(如Producer的数据源是文件,SequenceID 和文件行号能进行映射),Producer可不都要从上次最后写入成功的位置继续写入。

通过以上有一一1个繁复,在Partition级的exactly-once的写入操作,只都要额外一次HashMap的查询即可,而持久化的数据,也只会增加极极少量的字段(ProducerID, Sequence ID)。

从上边的错误场景可不都要看完,错误在任意阶段都肯能处于,要做到任意具体情况下完全的exactly-once写入代价极其昂贵,在线上大规模生产系统中,先要承受:

因此 ,这俩 简单的消费模式,无法支持exactly-once,核心在于消息的补救和ack是非原子操作。当消息补救完毕尚未进行ack时,consumer肯能crash,重启后,这条消息将被重复消费(broker尚未收到这条消息的ack信息)。

在消息系统中,消息的生成和消费通常支持有一种模式: at-most-once,at-least-once 和 exactly-once。 这几种模式的区别主要在于当系统处于错误的已经 ,系统表现何种行为。前有一种模式,非常容易理解,出错后不补救肯能不停重试直到成功为止,对于exactly-once的模式,系统在出错的已经 ,则都要进行特殊补救来保证第四根消息只被补救一次。

以上是对于消息系统的端对端支持exactly-once的简单探讨,通过一定的条件限定,写入端支持相对容易,而消费端除了较繁复的checkpoint机制外,还依赖消费产出下游系统的支持。