发送事件流

消息系统

  1. 生产者速度比消费者快:丢弃消息、将消息缓存在队列、激活背压
  2. 节点崩溃或者暂时历险,是否会有消息丢失?

生产者与消息系统之间的直接消息传递

  • UDP 组播:广泛应用于金融股票
  • 无代理消息库:ZerroMQ 和 nanomsg
  • StatsD 和 Brubeck 使用 UDP 传递消息
  • HTTP、RPC 接口

消息代理

参见:AMQP/JMS 风格的消息代理。 也称消息队列。

  • 消息对比与数据库对比
  • 多个消费者
  • 确认和重传机制

分区日志

参见: 基于日志的消息代理

数据库与流

保持系统同步

变更数据捕获

变更数据捕获(Change Data Capture,CDC)记录了写入数据库的所有更改,并以可复制到其他系统的形式来提取数据。 如果在写入时立即将更改作为一种流来发布,那么 CDC 就更有趣来。

实现变更数据捕获

解析复制日志,并将解析的内容发送到事件流中进行 replay。

初始快照

replay 日志占用空间过大,需要进行截断,截断之前的进行初始快照保存。

日志压缩

参考哈希索引

对变更流的 API 支持

数据库开始支持将变更流作为标准接口。

事件溯源

一种在领域驱动设计社区中开发的技术,与 CDC 最大的区别在于事件溯源在不同抽象层次上应用了将所有对应用程序状态的更改保存为更改事件日志:

  • CDC 中:应用程序以数据可变方式来操纵数据库,从数据库中提取较低级的变更日志,从而确保从数据库提取写入顺序与实际写入顺序相匹配。写入数据库的程序不需要知道 CDC 正在发生。
  • 事件溯源中:应用程序的写入逻辑是基于写入事件日志的不可变事件构建的。事件存储仅支持追加,不鼓励甚至禁止更新或删除操作。事件旨在反映在应用程序级别所发生的事情,而不是低级别的状态改变。

专门的数据库 Event Store 来支持使用事件溯源的应用程序。

从事件中导出当前状态:真正对用户有意义

命令和事件

命令经过校验后转化为事件。

状态,流与不可变性

流处理

  1. 事件中的数据写入数据库、缓存、搜索索引或类似的存储系统,提供给客户端查询。
  2. 通过某种方式将事件推送给用户,如电子邮件、短信等。
  3. 处理一个或多个输入流产生过一个或多个输出流。

流处理适用场景

复杂事件处理

复杂事件处理(Complex Event Processing,CEP)尤其适用需要搜索特定的事件模式。 实现:Esper、IBM Info Sphere Streams、Apama、TIBCO StreamBase 和 SQLstream。

流分析

Apache Storm、Spark Streaming、Flink、Concord、Samza 和 Kafka Streams。

维护物化视图

在流上搜索

消息传递和 RPC

流的时间问题

需记录三个时间:

  • 事件发生时间,设备的时钟
  • 事件发送时间,设备的时钟
  • 事件接收时间,福奇的时钟

窗口类型

  • 轮转窗口:长度固定,相互之间不重叠。
  • 跳跃窗口:长度固定,可以允许相互之间重叠。
  • 滑动窗口:通过保留事件排序的事件缓冲区并且从窗口过期时移除旧事件来实现。
  • 会话窗口:没有固定持续事件,通过将同一用户在时间上紧密相关的所有事件分组在一起。

流式 join

流和流 join(窗口 join)

流和表 join

表和表 join

join 和事件依赖性

流处理容错

微处理和校验点

重新审视原子提交

幂等性

故障后重建状态