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

高性能架构设计-数据库(读写分离)

一、高性能数据库简介

1.高性能数据库方式

读写分离:将访问压力分散到集群中的多个节点,没有分散存储压力

分库分表:既可以分散访问压力,又可以分散存储压力


 

2.为啥不用表分区

  • 如果SQL不走分区键,很容易出现全表锁;
  • 在分区表实施关联查询,就是一个灾难;
  • 分库分表,自己掌控业务场景与访问模式,可控;分区表,工程师写了一个SQL,自己无法确定MySQL是怎么玩的,不可控;


 

二、读写分离——提升数据库读性能

可以缓解订单系统、账户系统、购物车系统等等功能mysql的并发压力

读写分离的基本原理是将数据库的读写操作分散到不同的节点

1.读写分离的基本实现

数据库服务器搭建主从集群,一主一从、或者一主多从,数据库主机负责读写操作,从机只负责读操作。数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。业务服务器将写操作发给数据库主机,将读操作发给数据库从机。

需要注意的是,这里用的是“主从集群”,而不是“主备集群”。“从机”的“从”可以理解为“仆从”,仆从是要帮主人干活的,“从机”是需要提供读数据的功能的;而“备机”一般被认为仅仅提供备份功能,不提供访问功能。


 

2.读写分离引起的复杂性

(1)复制延迟

一般会把从库落后的时间作为一个重点的数据库指标做监控和报警,正常的时间是在毫秒级别,一旦落后的时间达到了秒级别就需要告警了。

以 MySQL 为例,主从复制延迟可能达到 1 秒,如果有大量数据同步,延迟 1 分钟也是有可能的。主从复制延迟会带来一个问题:如果业务服务器将数据写入到数据库主服务器后立刻(1 秒内)进行读取,此时读操作访问的是从机,主机还没有将数据复制过来,到从机读取数据是读不到最新数据的,业务上就可能出现问题。解决主从复制延迟有几种常见的方法:

  • 写操作后的读操作指定发给数据库主服务器(缓存标记法)。例如,注册账号完成后,登录时读取账号的读操作也发给数据库主服务器。这种方式和业务强绑定,对业务的侵入和影响较大,如果哪个新来的程序员不知道这样写代码,就会导致一个 bug。可以利用一个缓存记录必须读主的数据。当写请求发生时:
    • 写主库
    • 将哪个库,哪个表,哪个主键三个信息拼装一个key设置到cache里,这条记录的超时时间,设置为“主从同步时延”
    • 查询时:
       
      • cache里有这个key,说明1s内刚发生过写请求,数据库主从同步可能还没有完成,此时就应该去主库查询
      • cache里没有这个key,说明最近没有发生过写请求,此时就可以去从库查询


 

  • 读从机失败后再读一次主机。这就是通常所说的“二次读取”,二次读取和业务无绑定,只需要对底层数据库访问的 API 进行封装即可,实现代价较小,不足之处在于如果有很多二次读取,将大大增加主机的读操作压力。
  • 关键业务读写操作全部指向主机,非关键业务采用读写分离。例如,对于一个用户管理系统来说,注册 + 登录的业务读写操作全部访问主机,用户的介绍、爱好、等级等业务,可以采用读写分离,因为即使用户改了自己的自我介绍,在查询时却看到了自我介绍还是旧的,业务影响与不能登录相比就小很多,还可以忍受。
  • 写操作完成后,跳转到无关页面,类似订单支付的“支付完成”页面,其实这个页面没有任何有效的信息,就是告诉你支付成功,然后再放一些广告什么的。你如果想再看刚刚支付完成的订单,需要手动点一下,这样就很好地规避了主从同步延迟的问题。
     
(2)分配机制

将读写操作区分开来,然后访问不同的数据库服务器,一般有两种方式:程序代码封装和中间件封装。由于数据库中间件的复杂度要比程序代码封装高出一个数量级,一般情况下建议采用程序语言封装的方式,或者使用成熟的开源数据库中间件。

  • 程序代码封装。程序代码封装指在代码中抽象一个数据访问层,实现读写操作分离和数据库服务器连接的管理。
  • 中间件封装。中间件封装指的是独立一套系统出来,实现读写操作分离和数据库服务器连接的管理。对于业务服务器来说,访问中间件和访问数据库没有区别。中间件需要支持多种编程语言,因为数据库中间件对业务服务器提供的是标准 SQL 接口。数据库中间件要支持完整的 SQL 语法和数据库服务器的协议(例如,MySQL 客户端和服务器的连接协议),实现比较复杂,细节特别多,很容易出现 bug,需要较长的时间才能稳定。数据库中间件自己不执行真正的读写操作,但所有的数据库操作请求都要经过中间件,中间件的性能要求也很高。


 

(3)区分连接池
  • 数据库连接池需要区分:读连接池,写连接池
  • 如果要保证读高可用,读连接池要实现故障自动转移


 

3.从库的数量

是不是无限制地增加从库的数量就可以抵抗大量的并发呢?实际上并不是的。因为随着从库数量增加,从库连接上来的 IO 线程比较多,主库也需要创建同样多的 log dump 线程来处理复制的请求,对于主库资源消耗比较高,同时受限于主库的网络带 宽,所以在实际使用中,一般一个主库最多挂 3~5 个从库。

http://www.xdnf.cn/news/3311.html

相关文章:

  • OpenHarmony - 小型系统内核(LiteOS-A)(十七)标准库
  • 加速LLM大模型推理,KV缓存技术详解与PyTorch实现
  • java: 警告: 源发行版 21 需要目标发行版 21
  • PostgreSQL的COALESCE 函数用法
  • 慧星云支持 Qwen3:开启智算新生态,共筑高效 AI 未来
  • WebGL图形编程实战【5】:层次构建 × Shader初始化深度剖析
  • 基于ssm的校园旧书交易交换平台(源码+文档)
  • Microsoft Entra ID 详解:现代身份与访问管理的核心
  • 三分钟了解自动拆箱封箱操作
  • Pillow 移除或更改了 FreeTypeFont.getsize() 方法
  • mac下载homebrew 安装和使用git
  • SimFlow: 基于OpenFOAM的CFD求解器
  • 积木报表的 API 数据集 (附Demo图文)
  • JavaAPI — 日期与集合
  • Spring MVC @RequestParam 注解怎么用?如何处理可选参数和默认值?
  • 温补晶振(TCXO)稳定性优化:从实验室到量产的关键技术
  • 【爬虫】deepseek谈爬虫工具
  • Java 多线程进阶:什么是线程安全?
  • 如何在 Linux 环境下使用 Certbot 自动生成 SSL 证书并部署到 Nginx 服务中
  • 【论文阅读】APMSA: Adversarial Perturbation Against Model Stealing Attacks
  • 7.软考高项(信息系统项目管理师)-资源管理
  • C++初阶-string类2
  • [PRO_A7] SZ501 FPGA开发板简介
  • Roboflow标注数据集
  • crashpad 编译
  • 时态--00--总述
  • 1254. 【动态规划】单词的划分
  • KUKA机器人不同的用户权限详细介绍
  • vue+django农产品价格预测和推荐可视化系统[带知识图谱]
  • 0901context_useReducer_状态管理-react-仿低代码平台项目