知识卡片

三种流连接类型及其时间依赖性带来的不确定性

结构图卡

内容

流处理里的连接按参与连接的两侧是”活动流”还是”变更日志表”分三种。流流连接(窗口连接)两侧都是活动事件流(如把搜索事件与随后的点击事件按会话ID关联,计算搜索结果点击率),因为点击可能永远不发生、也可能因网络延迟先于对应搜索到达,流处理器必须维护状态(按会话ID索引最近一段时间的事件)并选定一个连接窗口。流表连接(流扩充)一侧是活动事件流、另一侧是数据库的变更日志(比[[排序合并连接把相关数据放在一起的核心思想]]的批处理版连接多了”数据库内容随时间变化”这一变量),实现上把数据库本地副本用[[Map侧连接的三种变体广播散列分区散列与合并连接]]类似的散列连接技术缓存在流处理器里、靠CDC持续保持更新,本质上仍是两个流之间的连接(活动事件流+档案更新流),窗口概念上是从时间起点延伸到当下的无限窗口。表表连接(维护物化视图)两侧都是变更日志(如推文流与关注关系流连接维护每个用户的时间线缓存),等价于持续维护一个SQL连接查询的物化视图,每当任一底层表变化都触发更新。三者共性是流处理器都要为连接一侧维护某种状态,而事件到达顺序在这里性命攸关:如果跨流事件顺序未定(不同流本没有跨流的顺序保证),连接结果就会变得不确定——同样输入重跑一次可能得到不同结果,这一问题在数据仓库领域被称为”缓慢变化的维度”,通常靠给每个版本记录唯一标识符来让连接重新变得确定(代价是日志压缩无法丢弃旧版本)。

结构图

flowchart TD
    A[流连接类型] --> B[流流连接: 两侧均为活动事件流,需窗口+维护状态]
    A --> C[流表连接: 一侧活动流,一侧CDC变更日志,窗口概念上无限]
    A --> D[表表连接: 两侧均为变更日志,维护物化视图]
    B --> E{跨流事件顺序是否确定?}
    C --> E
    D --> E
    E -->|否| F[连接结果不确定,重跑可能得到不同结果]
    E -->|是,如缓慢变化维度加版本标识| G[连接结果确定,但日志压缩需保留全部版本]

参考来源

- 位置:《数据密集型应用系统设计》第十一章《流处理》"流连接""流流连接(窗口连接)""流表连接(流扩充)""表表连接(维护物化视图)""连接的时间依赖性"(源文件:_epub-src/ch11_split_002.html) - 结论依据:原文分别举搜索点击、用户档案扩充、推特时间线三个例子说明流流/流表/表表三种连接的实现方式,并说明跨流事件顺序未定会使连接结果不确定,数据仓库用"缓慢变化的维度"配版本标识符解决这一问题,直接支撑本卡片的结构图与解释。 - 原始内容:为了实现这种类型的连接,流处理器需要维护状态……流表连接实际上非常类似于流流连接……如果跨越流的事件顺序是未定的,则连接会变为不确定性的……在数据仓库中,这个问题被称为缓慢变化的维度。