当前位置: 首页 > news >正文

20.LMAX——DDD的极致性能架构

学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid=1940048&ctype=0

文章目录

  • 历史
    • 起源
    • 架构目标
    • 架构要素
  • 时序对比
    • 传统时序
    • 事件溯源时序
    • LMAX时序
  • 单线程非阻塞异步IO(reactor)
    • 多线程
    • 单线程
  • 事件溯源
  • 高可用方案
  • 代价
  • 总结
    • 优点
    • 缺点
    • 适用范围

历史

LMAX是由Martin Fowler 2011年提出,原文地址: https://martinfowler.com/articles/lmax.html

起源

  1. 金融零售平台,要求高性能
  2. 达到单线程600万TPS,一个线程一秒钟能处理600万个交易请求
  3. LMAX架构名称就是以这个交易平台的名字命名的

架构目标

超高TPS。这里的TPS不是指只把数据读出来,是要有写入操作的,有变更的。

架构要素

1. 聚合常驻内存
在领域驱动设计中,不管以什么方式设计,最后要得到的就是“聚合”。在LMAX中,聚合是一直在内存中存在,不像传统的架构,用的时候把聚合从数据库中加载到内存,修改后保存到数据库 ,内存中的聚合就被回收掉了。
2. 事件溯源
需要高可用写入领域事件,宕机重启后可以从领域事件重建聚合。
3. 单线程异步非阻塞IO(串行,无锁)

在这里插入图片描述
外部系统发过来的请求会先写入环形队列Input DisruptorBusiness Logic Processor会串行化地从队列中一个一个取出来请求处理,并将结果写入到OutDisruptor中,这个结果就是领域事件
它没有给客户端直接返回结果,它是完全异步化的过程,客户端发过来请求后不会等待,直接退出。客户端会监听相应的事件,当收到相应的事件,才知道操作是否成功。Disruptor是一个高性能的队列框架,当初就是为了LMAX架构而设计的。

时序对比

传统时序

在这里插入图片描述

事件溯源时序

在这里插入图片描述

LMAX时序

在这里插入图片描述

单线程非阻塞异步IO(reactor)

多线程

- CPU在多线程间切换开销高 (相对于reactor)
- 阻塞
每个请求一线程模式,并发受线程数限制。像传统的tomcat这种方式,一个请求对应一个线程。
- 非阻塞
聚合在内存中只有一个实例,多线程情况下就会出现并发问题,所以就需要对实例加锁,加锁情况下每个聚合实际并发1。

单线程

  • 串行执行,无需加锁,一个CPU执行一个线程。CPU不会频繁在用户态和内核态切换。
  • 阻塞
    如果用阻塞的方式,并发能力1,性能暴跌,所以只能用非阻塞方式。
  • 非阻塞 (超高性能的唯一选择)

事件溯源

为什么要使用事件溯源,主要有两点:

  • 只持久化领域事件,带来高性能写
  • 确保重启服务器时,可以领域事件中,重建聚合。

高可用方案

聚合放在内存中,如果宕机怎么办呢,所以需要设计高可用方案。
所有的高可用方案都是通过冗余来实现的。main(主机器) 会发出所有的事件,follower(从机器) 会不断的重播这些事件,并重建聚合。如果main和follower之间没有高延迟,二者就可以在短时间内保持一致性。supervisor会监测main和follower, 一旦main出现宕机,就会在follower中选择一个作为新的主机器main,并告诉网关,将请求发到新的主机器上去。在这里插入图片描述

代价

1. 无数据库事务
无先操作后回滚,必须严格前置完成所有校验,才能变更聚合内的状态数据,才能发布领域事件。
2. 运行时外部调用变复杂
因为异步的原因,导致它和外边系统交互很复杂。需要写代码处理异步IO,给编写代码带来负担。需要减少主动外部调用: 监听事件提前组装数据 (数据量小)
显式事件驱动方式
3. 受内存大小限制
因为聚合全部在内存中,如果聚合数量太大就需要用多台服务器去做数据分区,架构更复杂。

总结

优点

  1. 极致性能
    全内存化模型设计,更灵活自由,可以大量使用对象和对象之间的引用。不像之前传统设计聚合的时候,是尽量减少聚合和聚合之间的引用。

缺点

  1. 异步编程带来的编程难度
  2. 高可用架构更复杂。传统的架构,只需要将服务复制很多份,服务是无状态的,它们共享同一个数据库。当我们需要高可用的,只需要多部署几台服务器就可以了,不存在主从切换问题、数据不一致问题。

适用范围

聚合数据量适合内存化,需要极致TPS场景,比如:

  1. 某些游戏服务器
    频繁的执行操作,服务端不断的响应。
  2. 火车订票

http://www.mrgr.cn/news/80066.html

相关文章:

  • nuxt2.0性能优化 ant design vue 组件和图标按需引入
  • 【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍
  • 物联网安全-ARMv8-M Trustzone 实操
  • 机器学习详解(4):多层感知机MLP之理论学习
  • 当我们输入网址确认时会发生什么?
  • C# MVVM 牛牛的实现依赖注入和MVVM绑定(DependencyInjection+CommunityToolkit)
  • 前端常用的方法
  • Electron electron-builder.yml 配置 (自定义包名,用户自定义安装目录...)
  • flink sink kafka的事务提交现象猜想
  • avue-crud 同时使用 column 与 group 的问题
  • 2024前端面试题(持续更新)
  • 力扣题目 - 935. 骑士拨号器
  • 【汇编】思考汇编中的两个基本问题
  • STM32F407+LAN8720A +LWIP +FreeRTOS ping通
  • c# 协变与抗变
  • 蓝桥杯我来了
  • 【1211更新】腾讯混元Hunyuan3D-1文/图生3D模型云端镜像一键运行
  • 微服务篇面试题
  • 案例讲解自然语言处理(NLP)
  • 【从零开始入门unity游戏开发之——C#篇03】变量和常量
  • SpringBoot3集成MybatisPlus3和knife4j(swagger3兼容增强版)
  • C语言,有关const
  • Prime2_解法二:openssl解密凭据
  • tcpdump编译
  • uboot移植网络驱动过程,无法ping通mx6ull和ubuntu问题解决方案
  • C++小白实习日记——Pollnet,Efvi,UDP,数据类型转换(下)