知识卡片

事件溯源与CDC的区别:命令与事件的区分

普通读书笔记卡

内容

事件溯源和[[变更数据捕获的实现方式与日志压缩机制]]都把”所有对状态的变更”存成一份事件日志,但两者作用在不同的抽象层次上:CDC里应用照常以可变方式使用数据库(任意更新删除),变更日志是从数据库底层提取出来的(比如解析复制日志),写数据库的应用完全不知道CDC的存在;事件溯源则把这个想法上移到应用逻辑层——应用逻辑显式地构建在写入事件日志的不可变事件之上,事件存储天生只追加、更新删除被禁止,事件被设计用来反映应用层面”发生了什么”,而不是底层状态如何被机械更新(例如存储”学生取消选课”这个中性表达的事件,而不是直接记录它的副作用”从登记表删除一行、往反馈表加一行”,这样以后要加”把名额让给候补名单下一位”这类新功能时,可以从已有事件里轻松挂出新的副作用逻辑)。事件溯源的哲学还严格区分命令与事件:一个来自用户的请求刚到达时是命令,此时仍可能因为违反某个完整性条件(比如[[容错共识算法的代价与局限]]所属共识问题里讨论过的用户名唯一性检查)而失败,只有验证通过后它才变成持久化、不可变的事实(事件)——这正是[[仅有时间戳排序还不够全序需要知道何时尘埃落定]]里用户名唯一性问题的另一种表述:验证必须在事件生成之前完成,事件流的消费者不允许拒绝已经进入日志的事件。

参考来源

- 位置:《数据密集型应用系统设计》第十一章《流处理》"事件溯源""命令和事件"(源文件:_epub-src/ch11_split_001.html) - 结论依据:原文对比CDC作用于数据库底层(应用不知情)与事件溯源作用于应用逻辑层(事件反映用户意图而非底层状态变更)的区别,并说明命令在验证通过前可失败、成为事件后不可撤销拒绝,直接支撑本卡片结论。 - 原始内容:在变更数据捕获中,应用以可变方式使用数据库……在事件溯源中,应用逻辑显式构建在写入事件日志的不可变事件之上……当来自用户的请求刚到达时,它一开始是一个命令……如果验证成功并且命令被接受,则它变为一个持久化且不可变的事件。