读写分离的思想

要想高性能,需要尽量:避开网络开销(IO),避开海量数据,避开资源争夺。

CQRS(Command Query Responsibility Segration)架构,命令查询职责分享架构。
一个系统,从架构上把它拆分为两部分:命令处理(写请求)+查询处理(读请求)。

C端负责数据存储,Q端负责数据查询,Q端的数据通过C端产生的Event来同步。

在进行大量的读操作时,如果将读取与写入操作进行分离,将能够提高查询的可伸缩能力。

其实对于读取密集型应用环境来说,可以通过另一种途径实现可伸缩性,即主/从复制。数据的修改全部发生在主节点上,数据将同步到一个或多个进行读取的从节点上。

这种方式已经存在很久了,并且在许多数据库机制中都已经得到了完整的支持。也可将它定义为一种CQRS架构,因为它确实做到了读写分离。

另一种用于处理可伸缩性问题的解决方案,即数据分片、或数据库分区。这种方式将某张表中的数据切分到数据库的多个实例中,并通过某个字段在实例之间进行分布,例如客户的名称。这种方式的一大优点在于能够设置多个主节点,因此可以对命令与查询两方面同时进行扩展。而许多数据库技术本身就支持分区能力,只需一些非常简单的代码就可以实现。在使用多个主节点的情况下无法支持跨记录的事务,因此就像对解决方案领域所进行的分区一样,对业务领域也要进行某种程度的划分。

 在某一种场景下是非常适合应用CQRS架构的,即具有高竞争性的业务领域。在这种领域中的负载非常大,而且具有高度的局域性。一旦出现并发异常就可能导致大多数事务操作开始失败、无法释放数据库连接、阻塞用户请求等一系列问题,产生巨大的系统瓶颈。这种测试用例在进行性能测试时经常会被忽略,一般在进行可伸缩性测试时,通常会针对多条记录创建大量的用户请求,而不是让所有的请求都集中于少数几条记录上。即使完美地实现了CQRS架构,这种瓶颈依然会出现在数据查询的场景,由于后台的进程不能快速地完成更新操作,导致查询模型总是无法及时获得最新的数据。

对于这种高竞争性的问题,解决方案是转为使用一种基于事件的模型,其数据模型是非阻塞式的、并且是只增的(append only),这就意味着该模型不会受到竞争性的影响。但这种方案可能会带来一个问题,因为它影响了某些业务规则。打个比方,某条业务规则规定只有在订单中的产品都有足够的库存时才允许接受订单。而这种方案则要求在业务处理上提供更高的灵活性,甚至可能会对需求产生变更。拿这个订单的例子来说,业务流程应当允许在不检查库存的情况下直接接受这个订单。而如果在处理订单时发现其中有某些产品库存不足,需要由业务人员决定如何处理这种情况。

posted @ 2016-03-03 13:53  delphi中间件  阅读(767)  评论(0编辑  收藏  举报