标签:存在 传统 数据操作 数据 lib lines 库存 handle 技术分享
Event-Sourcing模式使用仅附加存储来记录或描写叙述域中数据所採取的动作,从而记录完整的一系列系列事件,而不是仅存储实体的当前状态。由于存储包括全部的事件,能够用来具体化域对象。
Event-Sourcing模式能够简化复杂的域中的任务,避免了数据模型和业务领域的同步和引发的争用问题;增强性能,扩展性,以及响应;为事物数据提供一致性。保留全部的事件运行历史,能够跟踪和实现回滚之类的补偿操作。
大多数的应用都会涉及到数据的处理,而通常的方法是由应用来保证数据的状态,当用户请求数据的时候。就会更新数据的状态。举个样例。在传统的CRUD模型中,典型的数据处理过程是,从数据仓库读取数据。做出一些改动。使用新的数据更新(通常通过事务来保护数据)当前数据的状态。CRUD的方式会有例如以下的一些限制:
想要更深入的了解CRUD架构的一些限制,能够參考微软的CRUD, Only When You Can Afford It一文。
Event-Sourcing模式定义了一种处理由一系列事件来驱动的数据操作的方法。每一事件都记录在一个仅能追加的存储中。应用将生成一系列事件来描写叙述每一个动作,每一个事件相应存储数据发生的变更,然后将这些事件持久化。每一个事件都表示一组数据的变化(比方在订单中添加数据项)。
事件能够持久化到事件存储仓库中。事件存储仓库作为对当前数据的状态的数据源或记录系统(数据源或信息的权威数据源)。事件存储一般会公布这些事件,以便能够通知消费者,并在消费者有须要的时候处理它们。比如。消费者能够初始化一些任务将事件中的操作应用于其它系统来运行,或运行完毕该操作所需的不论什么其它相关操作。
注意,生成事件的应用程序代码与订阅事件的系统是解耦的。
通常来说,事件存储所公布的事件是用来在应用程序对实体进行改动的时候,更新实体的Materialized视图,并与外部系统集成。比如,系统能够维护全部客户订单的Materialized视图。这些订单信息用于填充UI的部分。当应用程序加入新的订单,加入或删除项目的顺序,并加入航运信息,消费者将处理描写叙述这些变化的事件,并更Materialized视图。
參考Materialized-View模式来了解很多其它的具体信息。
此外,事件存储能够让应用在不论什么时候读取事件的历史,并通过对事件历史进行有效地“回放”和消耗有关该实体的全部事件来计算实体的当前状态。非常多时候,可能会由于client请求,或通过一个预定的定时任务,来又一次计算实体的当前状态。
当中。定时任务能够将计算的状态生成Materialized视图。并存储起来来提高查询效率。
图1展示了Event-Sourcing模式逻辑的概览图。当中也包括了使用事件流来创建一个Materialized视图,并与其它外部应用和系统集成,以及通过反复事件流来展示某些实体的当前状态。
图1. 关于Event-Sourcing模式的样例和概览
Event-Sourcing模式有非常多的长处,包括:
这一点,能够令结合事务运行过程中不会产生不论什么争用,能够极大地提高应用程序的性能和可扩展性,特别是对于用户界面的展示。
当然,域模型仍然须要设计来保护其自身的一致性。
此外。使用补偿事件取消更改的要求提供了一个逆转状态的历史记录,假设模型仅仅存储当前状态,补偿回滚是无法实现的。事件列表也可用于分析应用程序性能和检測用户的行为趋势。以获得其它实用的业务信息。
Event-Sourcing通常都是配合CQRS模式来运行数据管理任务的。
当在考虑实现Event-Sourcing模式的时候,须要考虑例如以下一些问题:
在此期间,描写叙述实体的新的更新的新事件可能才到达事件存储区。
能够參考Data Consistency Primer来了解终于一致性方面的信息
在每一个事件中都加入一个时间戳,能够帮助避免问题。
还有一个常见的做法是每一个产生的事件都标记一个增量标识符。假设两个操作试图同一时候为同一实体加入事件时。则事件存储能够拒绝与现有实体标识符和事件标识符相匹配的事件。
这样,实体的当前状态能够从快照和重放那个时间点之后发生的不论什么事件中获得。
事件的消费者必须能够处理反复的通知操作。比如,假设一个实体的某一个属性由多个应用实例维护,比方订单总数,那么,当下订单的时候。必须仅仅有一个成功添加订单总数的事件的发生。尽管这不是Event-Sourcing的固有特性,可是通常来说。实现Event-Sourcing都要考虑这一点。
Event-Sourcing模式非常适合下面场景:
比如,对客户实体的更改能够记录为一系列特定的事件,如搬家、关闭账户等。
比如,当任务涉及多个步骤时。您可能须要运行回滚某个更新的操作,然后又一次运行一些步骤,使数据又一次恢复到一致状态。
这样的方式也能够用来改善UI性能,或者将事件分发给其它监听器,如其它应用程序或服务,来进行集成。
Event-Sourcing模式在例如以下的情况下不太适用:
某个会议管理系统须要跟踪完毕预订的会议,该系统能够在某个希望參加会议的人尝试申请參加的时候,检查是否还有空暇座位。该系统能够以至少两种方式来存储预定库存的总数:
能够预订或取消,系统能够适当的添加或降低这个数字。这样的方法在理论上是非常简单,可是假设大量的预定的人在非常多的时间内试图预订的座位的话,可能导致扩展性问题。比如,在预订期结束之前的最后一天内,可能有大量的预定请求。
由于事件的不变性,这样的方法的可扩展性更好。
系统仅仅须要能够从事件存储区读取数据,或将数据加入到事件存储区。关于预订和取消事件的信息不会改动的。
图2显示了怎样使用Event-Sourcing来实现会议管理系统的座席预订子系统。
图2在会议管理系统中使用Event-Sourcing获取座位预订信息
保留两个座位的动作顺序例如以下:
1. 用户界面发出一个命令,为两位与会者预留座位。
该命令由一个单独的命令处理程序处理(一个与用户界面解耦的应用逻辑,负责处理作为命令发送的请求)。
2. 通过请求全部的预定和取消会议的事件,来获取一个包括全部预定信息的数据集合。
这个数据集合叫SeatAvailability
,并支持查询当中的库存信息。
能够使用快照来做一些优化(因此开发人员不须要查询和重放事件的完整列表以获取的
SeatAvailability
的当前状态),并在内存中维护聚合的缓存副本。
3.CommandHandler
调用由域模型的方法来预定或取消。
4.SeatAvailability
记录包括座位库存。下一次计算库存数时,将遍历全部的预订时间来计算还有多少库存。
5. 该系统添加的新事件会存储在事件仓库中。
假设用户希望取消座位,该系统遵循相似的过程,由命令处理程序产生一个取消座位的事件并将其加入到事件存储中。
除了提供了更好的扩展性外,事件仓库为全部的预定和取消操作都保留了操作历史。不管是为了跟踪。或者分析挖掘,都提供了良好的支持。由于事件仓库中记录的事件是真实的唯一来源。系统没有必要持久化其它的状态信息。由于能够非常easy地又一次遍历事件并计算不论什么时间点实体状态。
开发人员能够在Introducing Event Sourcing中更具体的了解这个样例。
当考虑实现Event-Sourcing模式的时候,也能够參考例如以下相关模式:
CQRS模式描写叙述了怎样将操作。读取数据和应用程序的操作,通过使用单独的更新数据的接口来分离职能。
通常提高查询效率的方式,就是每隔一定的时间,依据数据仓库生成预填充的视图来提高查询效率。Materialized-View模式描写叙述了改功能是怎样实现的。
标签:存在 传统 数据操作 数据 lib lines 库存 handle 技术分享
原文地址:http://www.cnblogs.com/jhcelue/p/7287077.html