参考架构:三层 OLTP 应用
传统业务应用(订单、支付、库存)运行大量简短、单行、对一致性要求严格的事务(OLTP)。这棵决策树从识别负载画像开始,逐步说明何时引入主关系型数据库、连接池、只读副本、缓存层、备份 + PITR 和监控。目标不是“一开始就加上所有组件”,而是在每个瓶颈得到证实时加入合适的组件。
你的负载画像是什么:事务组合和一致性要求?
OLTP 架构的第一个决策是负载是否真的是事务型的(简短、需要 ACID 的读写混合)。数据天然是关系型的且一致性至关重要(资金、库存、订单),负载以读为主,还是负载仍然很低?
- 短事务、强一致性(资金/库存/订单)
- 读取占绝对主导,写入很少,流量在增长
- 负载很低;最简单的配置就够了吗?
你是否已选定主数据库引擎?是否担心扩展问题?
关系型引擎是事务核心的正确基础(PostgreSQL、MySQL/InnoDB、Oracle、SQL Server)。引擎选定后,下一个问题是扩展:单实例目前是否足够,还是连接数和读负载正在增加?
- 引擎已确定;单实例目前足够
- 连接数激增,资源即将耗尽
- 读负载在增长,正在给主写入实例带来压力
如何扩展读取:副本还是缓存?
如果读负载正在给主实例带来压力,有两个互补的选项。可以容忍数据略有延迟的读取(如报表/列表)可以路由到只读副本;如果同样的“热”数据被反复请求,微秒级延迟的缓存(Redis)可以减轻数据库压力。
- 大量报表/列表读取;可以接受轻微延迟
- 同样的热门数据被反复读取
建议:从单主库 + 连接池 + 备份开始
早期保持架构简单:一个关系型主实例、前面的一个连接池和定期备份就足够了。只有在经过测量的瓶颈迫使时才增加复杂性。
建议:添加连接池
在 OLTP 中,当每个应用实例都打开自己的连接时,主数据库在数千个连接下会被内存和调度开销拖垮。在中间部署连接池,可以让大量应用请求共享少量真实的数据库连接。
建议:添加只读副本
写入保留在主库上,只读流量(报表、列表、搜索)路由到由主库供给的一个或多个异步副本。这样主库可以专注于写入和对一致性要求严格的读取。
建议:添加缓存层(Redis)
如果相同的热门数据(会话、目录、档案、页面片段)被反复读取,在数据库前面部署内存缓存,使大多数读取根本无需访问数据库。延迟下降,主数据库得到减负。