将数据组织为事件流这种思想在许多领域中都已得到应用,但不幸的是,人们有时会用不同的术语来表达这一思想,例如流处理(Stream Processing)、事件溯源(Event Sourcing)或复杂事件处理(Complex Event Processing - CEP)。 Martin Kleppmann 为读者解释了这一思想中的 基本概念 。
Kleppmann是即将出版的 《设计数据密集型应用》 (Designing Data-Intensive Applications)一书的作者,他表示这些基本的思想概念中有许多是十分简单的,并且值得深入学习。这些思想能够帮助我们设计出具有更高的伸缩性、可靠性和可维护性的应用程序。
Kleppmann以 Google Analytics 这一工具作为使用事件的一个示例,这个工具能够按照访问者对网站的页面访问次数进行跟踪。在这个工具中,每一次页面访问都会产生一个事件,其中包含的内容有页面的URL、时间戳,以及客户端IP地址等等,这对于用户量庞大的流行网站来说可能会造成数量巨大的事件产生。从这些事件中收集该网站的使用情况有两种选择,这两种选择都具有实用性,但各自适应于不同的场合:
事件溯源也是一种类似的思想,它是由 领域驱动设计 (DDD)社区所提出的。这方面的一个常见例子就是电子商务网站中的购物车。这种思想是不对当前的购物车状态进行改变和保存,而是将每个改变了购物车状态的事件保存下来。这种事件可以是 ItemAdded 和 ItemQuantityChanged 。通过对事件进行重演、或是将它们进行聚合,可以重现购物车的当前状态。Kleppmann表示,这一思想与Google Analytics的示例非常相似。
对于Kleppmann来说,事件是保存数据的一种理想的方式,所有的信息都作为一个单独的blog,通过添加的方式进行保存,这就避免了对多个表进行更新的需求。他也认为,对于从数据存储系统中读取数据来说,对数据进行聚合是一种理想的方式,因为用户感兴趣的通常都是当前的状态。以用户界面举例,用户对某个按钮的单击行为对应着一个事件,而对页面的请求则表现为通过某个聚合展现当前的状态。Kleppmann在他的示例中还衍生出一个模式:原始的输入事件是不可变的事实,它易于保存,并且具有真实性。聚合就是源自于这些原始事件的,并且在新的事件到来后会进行缓存和更新。在必要的时候,可以将所有事件进行重演,以重建所有的聚合。
转而使用类似于事件溯源一类的方式,就意味着要远离传统的由数据库保存当前状态的方式。Kleppmann仍然坚持采用这种方式的原因包括以下方面:
各种Actor框架,例如 Akka 、 Orleans 和 Erlang OTP 等等都是构建在不可变事件流的基础上的,但Kleppmann指出,设计这些框架的主要目的是作为一种处理并行任务的机制,而不是用于数据管理的。
查看英文原文: Making Sense of Event Stream Processing