Stream Processing (1-2) - Acknowledgments & Partitioned Logs

Day 28

Acknowledgments and redelivery

老样子,消费者任何时间都有可能故障,有可能发生 讯息代理 (message broker) 传递讯息给消费者後,它却没有处理或只处理到一半,为了确保讯息不遗失,broker 使用 acknowledgments:当消费者在处理完讯息後,必须明确的通知 broker,如此 broker 就可以将讯息从 queue 中删除。

消费者因故障消失时,broker 会将未 acknowledgments 的讯息传递给其他消费者,此时若你的传递策略是 load balance 时,会发生如下图 11-2 的影响:讯息 m3 和 m4 传递的顺序跟事件发生顺序不同。

Consumer 2 在处理 m3 到一半时故障,同时 Consumer 1 正在处理 m4, 非 ack 的讯息 m3 会再传递给 Consumer 1,其消费讯息的顺序为 m4, m3, m5,与发生顺序不同。

如果讯息彼此间有因果关系,避免此问题的方法就是为每个消费者使用单独的 queue(例如不要用 load balance 传递策略。)

Partitioned Logs

如果你是使用 AMQP/JMS 风格的讯息模型,当讯息被 acknowledgments 後会从 broker 中删除,因为它们是以讯息传递的思维来建构,如果你在此系统中注册新增一个消费者,它无法接收注册前的讯息,相较於资料库或档案系统来说就没这问题,因此,一个混合有耐用性储存及低延迟讯息通知系统就诞生了:基於 log 的讯息代理 (log-based message broker)

使用 log 储存讯息

我们在之前讨论过 Log-structured 储存引擎 (2020 Day 8) 和 数据复制 (2020 Day 21),我们可以用相同的架构实作讯息代理:生产者的讯息会附加在 log 中,消费者透过读取 log 来接收讯息,当消费者读完讯息了,就後待新讯息附加至 log 後的通知。这就像 Unix 工具的 tail -f 一样,当档案被写入後你会同步看到内容一样。

这里 log 也能使用 partition (2020 Day 27) 来应付更高的吞吐量,不同分区由不同的节点负责,每一个分区都是独立的读取和写入,一个主题可以被定义为一组分区,这种方法如下图 11-3 所示:

每一个分区,broker 会分配一个逐渐累加的序列号到每一条讯息上,称为 offset,就是下图方框内的数字,因为 log 只能附加上去,所以每一个分区的讯息皆是完全排序,但不同分区的顺序无法保证。

Apache KafkaAmazon Kinesis StreamsTwitter DistributedLog 皆是基於 log 的讯息代理。

消费者 offset

offset 让消费讯息的追踪更简单了,比较一下各讯息的 offset 跟消费者当前的 offset 大小就好,也因此 broker 就不用在花费力气追踪各讯息的 acknowledgments 了,它只要定期记录消费者的 offset 就好,进而提高讯息代理的吞吐量。


<<:  【Day 14】- 实战爬取 Ubuntu ISO 映像档下载网址

>>:  当心已死前,来看看这篇吧!

[Day 37] 关於web.php的迷失

这几天在改Laravel, 遇到一个很奇怪的问题, 我只要点击後台要到/admin/user/, 每...

【XCode 使用技巧】官方工具 x 你所不知道的开发功能

XCode 使用技巧 XCode x Swift x SwiftUI 目录 前言 : 何时才能愉快的...

Day9 Methods and v-on

今天来介绍这个指令v-on用来绑定HTML DOM,来触发要执行的事件 Method 这时并没有执行...

Day 15 储存宝石:S3 架构 & 版本控管 (Versioning)

今天我们将介绍 AWS S3 的架构及其版本控管(Versioning)的概念。 Bucket 的...

#Day20--那些年,我们一起犯的傻

这篇会是一个中场休息,但主要会分享的是,我在踏入实作的那一瞬间,对於写程序所产生的不良习惯,希望可以...