3.1 数据库与中间件服务


3.1 数据库与中间件服务

本节摘要:数据库和中间件是应用架构的核心组件,腾讯云提供多种托管服务。数据库按数据模型分:关系型 TDSQL(MySQL 协议)适合结构化数据和事务;Redis 缓存适合高速读写;文档型数据库适合灵活结构;时序数据库适合监控 IoT 这类带时间戳的数据。中间件里,CKafka 消息队列解耦异步通信,API 网关统一管理 API 入口。本节讲这些产品的定位和选型,重点是怎么根据数据特征选对数据库,以及托管相比自建省了什么、失去什么。

学习目标

阅读完本节,你应当能够:

  1. 根据数据特征(结构化/半结构化、读写模式、事务需求)选对数据库类型
  2. 说清托管数据库相比自建省了什么、失去了什么
  3. 解释 Redis 缓存在架构里的角色和典型用法
  4. 说清消息队列解决什么解耦问题
  5. 理解 API 网关统一管理 API 入口的价值

问题与直觉

几乎每个应用都要存数据,而"用什么存"是个容易选错的决策。最直觉的选择是 MySQL——它通用、熟悉、能处理大多数场景。但 MySQL 不是万能的:高并发的计数器(点赞数)用 MySQL 扛不住,该用 Redis;海量的监控指标(每秒上万个时间戳)用 MySQL 查不动,该用时序数据库;灵活结构的商品属性(不同商品属性不同)用关系型要建很多表,文档型更合适。

选错数据库的代价很大。把高并发计数塞进 MySQL,要么频繁锁表、要么加缓存层层补丁;把结构化的事务数据塞进文档数据库,复杂查询性能差且没有事务保证。所以理解各类数据库的数据模型和适用边界,是架构设计的基本功。

另一个决策是托管还是自建。自建 MySQL 你要管安装、备份、主从同步、故障切换、版本升级——任何一环出错都可能丢数据或宕机。托管 TDSQL 把这些全包了,但要付溢价。多数团队,尤其是没有专职 DBA 的,托管是更稳的选择。

核心原理

2.1 数据库选型矩阵

各类数据库的定位:

数据库类型 数据模型 擅长 不擅长 典型用途
关系型 TDSQL 表 关系 结构化数据、事务、复杂查询 超高并发、灵活结构 用户、订单、账户
Redis 缓存 键值 极高并发读写、低延迟 持久化、复杂查询 缓存、计数器、会话
文档型 文档 JSON 灵活结构、嵌套数据 强事务 商品属性、内容管理
时序型 时间序列 时间戳数据、聚合降采样 单条随机读写 监控、IoT、日志
列式/数仓 列存 海量数据分析、聚合 单条事务 报表、BI、大数据分析

选型的核心是匹配"数据特征 + 访问模式"。结构化且要事务(转账、下单)用关系型;高速读写且能容忍丢失(缓存)用 Redis;结构灵活(商品属性各不相同)用文档型;按时间排序的指标(监控)用时序型;海量数据分析用列式数仓。

💡 关键直觉:别用一种数据库解决所有问题。一个典型应用常常是"关系型存核心业务数据 + Redis 做缓存 + 时序库存监控"的多数据库组合。每种数据库做自己擅长的事,通过应用层把它们粘合起来。强行用一种数据库通吃,要么性能差要么开发痛苦。

2.2 关系型数据库 TDSQL

TDSQL 是腾讯云的托管关系型数据库,兼容 MySQL 协议(也有 PostgreSQL 等版本)。它把数据库运维的几个麻烦事外包了:

高可用:自动主从复制和故障切换。主库挂了,从库自动顶上,你不用半夜爬起来手动切。这是托管数据库最大的价值之一——自建主从切换是 DBA 的噩梦。

备份恢复:自动定期备份,支持按时间点恢复("恢复到昨天下午 3 点的状态")。自建要自己写备份脚本、验证可恢复性,很多人备份了但从没验证过能不能恢复,真出事才发现备份是坏的。

扩缩容:升级实例规格(加 CPU、加内存)通常是无感操作,厂商帮你迁。读压力大可以加只读实例。

代价是:你受限于厂商支持的版本和配置。想用一个特殊的 MySQL 插件、改个内核参数,可能不支持。对于绝大多数标准用法这不是问题,但有些深度定制需求的场景会被限制。

2.3 Redis 缓存的角色

Redis 是内存键值存储,因为数据在内存里,读写极快(微秒级)。它在架构里通常扮演"缓存"角色——把热点数据从慢存储(磁盘上的数据库)搬到快存储(内存),减少对慢存储的压力。

典型用法:

数据缓存:把数据库查询结果缓存到 Redis,下次同样的查询直接从 Redis 取,不用再查数据库。这是最经典的用法,能大幅降低数据库压力。

会话存储:用户登录会话存 Redis,多台服务器共享(用户请求可能落到任何一台)。比存数据库快,比存每台服务器本地又能共享。

计数器/排行榜:高并发的计数(点赞数、播放量)用 Redis 的原子操作扛得住,MySQL 这种场景会锁表。

限流:用 Redis 记录请求频率做限流("每用户每分钟最多 100 次"),比在应用内存里限流更准(多台服务器共享计数)。

用法 Redis 角色 解决问题
数据缓存 热点数据镜像 降低数据库压力
会话存储 共享会话 多机一致
计数器 原子计数 高并发写
限流 频率记录 多机一致限流

⚠️ 常见坑:把 Redis 当主存储。Redis 是内存数据库,虽然能持久化但本质上是为了速度而非可靠。把只能存不能丢的业务数据(用户余额、订单)放 Redis 而不落数据库,一旦内存故障或持久化没做好,数据就丢了。Redis 是缓存层,数据库是持久层,别搞反。

2.4 消息队列 CKafka

CKafka 是腾讯云的托管 Kafka(消息队列产品)。消息队列解决的核心问题是解耦和异步

设想订单系统:用户下单后,要扣库存、发短信、记积分、推数据分析。如果订单系统同步调这四个服务,任何一个慢了或挂了,下单就失败或超时。用消息队列解耦:订单系统把"新订单"消息扔进队列就返回成功,库存、短信、积分各自从队列消费消息慢慢处理。订单系统不用等它们,它们之间也不互相依赖。

消息队列的几个价值:解耦(生产者不关心消费者是谁、几个)、异步(慢操作不阻塞主流程)、削峰(流量高峰时消息排队,消费者按自己节奏处理,不被压垮)、广播(一条消息多个消费者各自处理)。

托管 CKafka 相比自建 Kafka 省了集群运维(Kafka 集群的搭建、监控、扩容是出了名的麻烦),代价同样是受限于厂商版本和配置。

工程实践要点

3.1 API 网关的价值

API 网关是放在所有后端服务前面的统一入口。它把"API 管理"这件事集中处理:

统一鉴权:所有 API 请求先过网关做身份验证,后端服务不用各自实现鉴权逻辑。

限流熔断:在网关层做限流(防止恶意刷接口)和熔断(后端服务挂了快速失败不拖垮整条链)。

协议转换:外部用 HTTP,内部服务用 gRPC,网关做转换。

监控统计:所有 API 调用的流量、延迟、错误率在网关统一统计,不用每个服务自己埋点。

灰度发布:在网关层按比例分流(10% 流量到新版本,90% 到旧版本),做灰度上线。

对于微服务架构(很多个后端服务),API 网关几乎是标配。没有它,每个服务都要重复实现鉴权、限流、监控,且没有统一视图。

3.2 数据库的连接池和读写分离

用托管数据库时,两个常见优化:

连接池:应用和数据库之间的连接是昂贵的资源(建立 TCP 连接、认证)。如果每个请求都新建连接,开销大。用连接池(维护一批常驻连接,请求复用)能大幅提升性能。多数数据库驱动和 ORM 都内置连接池,配置好就行。

读写分离:写操作走主库(保证数据一致),读操作走只读实例(分担主库压力)。因为多数应用读多写少(看商品的多、下单的少),加只读实例能显著提升读性能。托管数据库通常支持配置只读实例,且读写分离的路由可以在数据库代理层自动做。

# 概念性:读写分离的路由逻辑 class ReadWriteRouter: def get_db(self, query_type): if query_type == "write": return self.master_conn # 写走主库 else: return self._pick_replica() # 读轮询只读实例 def _pick_replica(self): # 简单轮询 或按延迟选最近的只读实例 return self.replicas[self.counter % len(self.replicas)]

3.3 托管数据库的迁移策略

从自建数据库迁到托管,或者从别的云迁过来,要注意:

数据迁移:先全量迁移历史数据,再用 CDC(变更数据捕获)同步增量。切换时短暂停服或做双写过渡。

兼容性验证:托管版本的 SQL 兼容性、字符集、排序规则要和原来一致,否则查询结果可能微妙不同。迁移前在测试环境完整跑一遍。

连接信息更新:应用连数据库的地址、端口、账号要改成托管的。建议这些配置走配置中心或环境变量,切换时改配置而非改代码。

💡 关键直觉:数据库迁移是最容易出事的操作,务必在低峰期做、务必先在测试环境演练、务必有回滚方案。见过太多团队迁移时主从不同步就切流量,导致数据丢失或不一致。宁可慢,不可错。

本节要点回顾

  • 按数据特征选数据库:结构化事务用关系型、高速读写用 Redis、灵活结构用文档型、时间序列用时序、海量分析用列式。
  • 别用一种数据库通吃:典型应用是多数据库组合,每种做自己擅长的。
  • 托管数据库外包运维:高可用、备份恢复、扩缩容都省了,代价是受限于厂商版本和配置。
  • Redis 是缓存层不是主存储:只能丢的数据要落数据库,Redis 挂了数据没了。
  • 消息队列解决解耦和异步:生产者发消息就走,消费者各自处理,还能削峰和广播。
  • API 网关统一管 API 入口:鉴权、限流、监控、灰度集中处理,微服务架构标配。
  • 读写分离分担读压力:写走主库、读走只读实例,多数读多写少场景有效。
  • 数据库迁移要谨慎:低峰期、先演练、有回滚,宁可慢不可错。

下一节讲应用部署的两种更高层方式——容器服务和 Serverless,以及它们的运行模型差异。

补一段常见疑问的集中回答,作为本节收尾。问:缓存一致性问题托管 Redis 能解决吗?答:不能,这是应用层问题——先更新库再删缓存(而非更新缓存)是通用起点,强一致要求高的场景绕开缓存直读主库。问:消息队列选 CKafka 还是轻量队列?答:吞吐百万级、需要回放和流式生态选 Kafka 系;只是任务解耦、日百万条以内,轻量队列(如 CMQ)运维和成本都更轻,别用牛刀杀鸡。问:API 网关和负载均衡啥区别?答:CLB 工作在四层/七层转发流量,网关理解 API 语义(路由到具体接口、按调用方限流、做鉴权),网关之下通常还有一层 CLB——两者是叠加不是替代。这三问答不上时回到正文对应段落,都是生产设计评审的高频题。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U