流处理
date
Jan 17, 2022
slug
stream
status
Published
tags
DDIA
summary
DDIA11章学习笔记
type
Post
之前第10章中的批处理的数据是有界的,也就是说已知的有限的大小,所以批处理知道何时读完他们,MapReduce必须先读取整个输入才能开始输出。
实际上很多数据是无界的,而且随着时间的推移而逐渐到达。
“流“是指随着时间的推移而持续可用的数据。
发送事件流
在批处理中,作业的输入输出是文件。
在流处理的上下文中,记录通常被称为事件。
消息系统
生产者和消费者可以直接进行消息传递,比如通过UDP组播或者是消费者在网络上公开服务,然后生产者通过HTTP或者RPC请求将消息进行推送。
消息代理
- AMQP/JMS风格的消息代理:代理将单个消息分配给消费者。消费者在成功处理之后确认每条消息。消息被确认后从代理中删除。这种方法适合作为一种异步RPC,例如在任务队列中,消息处理的确切顺序并不重要,并且不需要在他们处理完后返回并再次读取旧消息。
- 基于日志的消息代理:代理将分区中的所有消息分配给相同的消费者节点,并始终以相同顺序发送消息。通过分区机制来实现并行,消费者通过检查他们处理的最后一条消息的偏移量来跟踪进度。代理将消息保存在磁盘上,因此如果有必要,可以回退并重新读取旧消息。
这样的一个好处就是能更好地支持容错,重新处理信息,比如利用幂等性。
数据库与流
保持系统同步
变更数据捕获(异步,存在复制滞后的问题)
这里有一些比如快照、日志压缩的技术可以帮助重建索引或者恢复。
事件溯源
将用户的行为记录成不可变的事件更有意义,而不是记录这些行为对可变数据库的影响。
区分命令和事件,当来自用户的请求第一次到达时,它最初是一个命令,此时仍然会失败,因为违反了某些完整性条件。如果验证成功并且命令被接受,它将变成一个持久且不可变的事件。
流处理
复杂事件处理(CEP)
在CEP系统中,查询和数据的关系与普通数据库正好相反,通常情况下,数据库会持久存储数据并将查询视为暂时的,但是CEP系统中将查询视为长期存储的,来自输入流的事件不断流过他们以匹配事件模式。
流的时间问题
区分事件时间和处理时间。
用谁的时钟?
- 根据设备的时钟,记录事件发生的时间。
- 根据设备的时钟,记录将事件发送到服务器的时间。
- 根据服务器时钟,记录服务器收到事件的时间。
窗口类型
- 轮转窗口
- 跳跃窗口
- 滑动窗口
- 会话窗口
流式join
- 流和流join
- 流和表join
- 表和表join
表和表join的例子是第一章里面推特时间线的实现。
查看需要更新哪些时间线其实就是维护两个表(推文和关注者)join查询的物化视图
SELECT follows.follower_id AS timeline_id,
array_agg(tweets.* ORDER BY tweets.timestamp DESC)
FROM tweets JOIN follows ON follows.followee_id = tweets.sender_id
GROUP BY follows.follower_id