本文的思路来源于https://queue.acm.org/detail.cfm?id=3321612
随着产品复杂度的提升和微服务架构的流行,一个业务系统背后的数据存储系统也越来越复杂。
以微信公众号为例:
除此以外
在业务系统拥有这么多数据存储系统的情况下,更改其中一个数据存储系统的记录,都需要保证其它的数据存储系统的记录也同时发生更改。任意一个数据存储系统得更改都影响到其它的数据存储系统,业务系统背后要是有五个服务,那意味着要更改五次,还得保证每一次更改都能解决可能出现任何的问题:
等等。随着业务增长,这个系统得复杂到什么程度。
长久以来,传统的关系型数据库都是事务来解决操作数据时可能出现的任何问题,概括的来讲就是所谓的ACID:原子性 (Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
因此在一个庞大的业务系统中,也需要事务去保证对业务系统其中任何一个数据存储系统的更改都会如实的反映在业务系统其它的数据存储系统之上,即分布式事务。业界有两种主流的分布式事务解决方案:
有一个简单办法解决这个问题:
当一个数据存储系统发生变更时,先发送一条event到update log,然后其余的数据存储系统再去解析这个update log。因为log是有序的,所以类似于下图中的搜索引擎和数据库只要按照log上event的顺序,以相同的顺序更改本地的数据记录,就可以保证所有的数据存储系统上的数据记录是一致的。
基于event-log的架构保证了
这个架构被称为Online Event Processing,缩写为OLEP。
在OLEP中,最核心部分的莫过于Log。那么这个Log应该具有什么样的特征,或者说这个Log背后的系统应该要满足什么样的特性?
除此以外,作为OLEP系统的订阅者,还应该需要:
满足这些特性的系统,开源的有Apache Kafka、Pulser等等,具体不再详述。
OLEP并不能说全无缺点。OLEP相比于传统的关系型数据库,它把关系型数据库内部的Log具象到了外部,因此相比于关系型数据对事务实现的完整性,只能说OLEP是一个最终一致性的系统。
在OLEP系统中,如果有使用者同时读取两个不同的数据存储系统,有可能会出现读数据不一致的情况,即隔离性(Isolation)是没有实现的。
在一个拥有庞大的数据存储系统的业务中,要保证它们的数据一致性是一件很痛苦的事,OLEP提供了一种相对高效和简洁的方式去维护各个系统之间的数据一致性。
相比于关系型数据库使用Log在内部实现事务,OLEP将Log提到了应用级别去处理系统之间的事务。通过Log这个中间媒介,OLEP系统拥有接近线性的可扩展性,减低了数据存储系统之间的复杂度,也保持了不错的性能。
因此,在一个拥有许多个数据存储系统的业务系统中,值得尝试OLEP的处理方式。