DDD 与 CQRS 才是黄金组合( 三 )

DDD 与 CQRS 才是黄金组合

文章插图
仓库拆分具有以下特点:
  • View 不再需要 Converter 组件完成数据转换
  • View 的数据来自于自己的 Repository,可以根据展示需求进行灵活定制
  • Command 和 Query 仍旧使用同一套数据库、同一套数据表
六、数据层冲突与拆分
数据层拆分是最重要的拆分,提到分离第一反应也是“数据库主从分离” 。
数据层拆分的本质是:各种数据存储引擎的最佳应用场景相差巨大 , 读 和 写 优化往往存在矛盾 。
仍旧以最常见的数据库为例:
  • 提升查询性能,建议为各种查询维度建立索引
  • 提升写入性能,需要让表上的索引越来越少
  • 为了加速更新性能,建议使用三范式设计表结构 , 减少冗余信息
  • 为了加速查询性能,建议使用反范式设计,尽量冗余数据,避免数据表间的 Join 操作
鱼和熊掌不可兼得,在数据库层展示得淋漓尽致!
数据层拆分后架构如下:
DDD 与 CQRS 才是黄金组合

文章插图
该模型具有以下特点:
  • 数据存储进行了彻底拆分;Command 和 Query 都可以灵活的选择最合适的存储引擎;
  • Command 与 Query 需要引入一套同步机制以完成两者的数据同步,常见的同步机制有:
  • 工作在应用层基于领域事件的数据同步,如图所示
  • 工作在数据层基于log的数据同步,如 MySQL 的主从同步、Canal2XX 等
数据层拆分是大型系统最终的归宿,仍旧以订单系统为例:
  • 订单作为一致性要求极高的系统,Command 侧首选仍旧为具有 ACID 的关系型数据库,哪怕是分库分表底层存储仍旧不变;
  • 为了满足高性能查询需求,需要在 Query 侧引入 Redis 作为分布式缓存对访问进行加速;
  • 为了满足后台复杂且多维度的业务查询,需要在 Query 侧引入 ES 为全文检索进行加速;
  • 为了满足各种实时报表需求 , 需要在 Query 侧引入 TiDB 以满足海量数据的实时检索;
这就是我们面临的现状:“数据密集型系统”越来越多的应用程序有着各种严格而广泛的要求,单个工具不足以满足所有的数据处理和存储需求 。取而代之的是,总体工作被拆分成一系列能被单个工具高效完成的任务,并通过应用代码将它们缝合起来,通过 API 的方式,对外提供服务,屏蔽内部的复杂性 。
七、小结
“拆分”是“分离关注点”的重要手段之一 。拆分的目的是将问题进行归类,然后采取有针对性的手段更好解决问题 。
CQRS 作为一种架构,将业务系统不同部分进行归类,接下来需要为 Command 和 Query 寻找最优解决方案:
Command , 以 DDD 作为理论基础将战术模型中最佳实战进行落地 , 包括:
  • 聚合设计
  • 仓库设计
  • LazyLoad + Context 模式
  • 业务验证
  • 领域事件
Query,以数据检索和组装作为核心能力,设计留给开发人员,实现留给框架 , 包括:
  • QueryObject 查询对象模式
  • 内存 Join 模式
  • 宽表&冗余表模式
作者丨geekhalo
来源丨公众号:geekhalo(ID:geekhalo)

【DDD 与 CQRS 才是黄金组合】


推荐阅读