旧游无处不堪寻
无寻处,惟有少年心
『数据密集型应用系统设计』读书笔记(十一)

上一章讨论了批处理技术,它是读取一组文件作为输入并生成一组新的输出文件的技术,其中始终存在一个重要的假设即输入是有界的。而本章中,我们将转向流处理,其中输入是无界的。也就是说,作业的输入是永无止境的数据流。

发送事件流


在批处理的世界里,作业的输入和输出是文件。等效的流当输入是文件(字节序列)时,第一个处理步骤通常是将其解析为记录序列。在流处理的上下文中,记录通常被称为事件,每个事件通常包含一个时间戳。
例如,发生的事情可能是用户的某些操作,例如浏览页面或下单购买,也可能源于温度传感器的周期性测量。

事件可以被编码为文本字符串或 JSON 或者某种二进制形式。通过这种编码方式,可以保存事件。比如将其追加到文件、插到关系表或将其写入文档数据库等。

在批处理中,文件被写入一次,然后可能被多个作业读取。类似地,在流处理中,事件由生产者生成一次,然后可能由多个消费者处理。

消息系统

向消费者通知新事件的常见方法是使用消息系统。在这种发布/订阅模式中,不同的系统采取了不同的方法。

许多消息系统将生产者直接连接到消费者,而不通过中间节点,这样会产生很多问题,例如消息丢失等。一种广泛使用的替代方法是通过消息队列发送消息。

生产者将消息写入消息队列,消费者通过从消息队列读取消息。

一些消息队列只将消息保存在内存中,而另一些消息队列将其写入磁盘,以便在消息队列崩溃的情况下不会丢失消息。一些消息队列甚至可以使用 XA 参与两阶段提交协议。

当消费者跟不上生产者时

消费者无法跟上生产者发送消息的速度时有三种选择:

  1. 丢弃消息
  2. 缓冲
  3. 应用背压

流处理


我们已经讨论了流的来源以及是如何传输的,接下来需要讨论的是怎么处理流。

一般来说,有三种选择:

  1. 可以将事件中的数据写人数据库、缓存、搜索索引或者类似的存储系统,然后被其他客户端查询
  2. 可以通过某种方式将事件推送给用户
  3. 可以处理一个或多个输入流以产生一个或多个输出流,最终在输出端结束(选择 1 或 2)