关系型数据库集群性能优化
Feb 3, 2022 20:00 · 952 words · 2 minute read
1. 优化原则
SQL 优化 > 缓存 > 读写分离 > 分库分表
2. 读写分离
将数据库读写操作分散到不同的节点上:
- 数据库服务器使用主从架构(1 主 n 从)
- 主库读写,从库只读
- 通过复制同步主从,每台数据库服务器都存储了所有的业务数据
- 业务服务将写操作发送给主库,读操作发送给从库
引入问题:
- 复制延迟
- 分配机制
2.1 复制延迟
可能因为延迟从库还未同步。
解决复制延迟的几个常见方法:
-
写操作后的读操作指定发送给主库
和业务强绑定
-
读从库失败后再读一次主库
二次读取,增加主库压力
-
关键业务读写指向主库,非关键业务读写分离
注册、登录业务读写都在主库完成,延迟影响较小的业务读写分离
2.2 分配机制
读写操作访问不同的数据库服务器。
-
程序代码封装
在代码中抽象一个数据访问层,实现读写操作分离和数据库服务器连接的管理
- 实现简单
- 每个编程语言都要实现,无法通用
- 故障时主从切换可能要修改配置和重启系统
-
中间件封装
独立一套系统出来,实现读写操作分离和数据库服务器连接的管理 对于业务服务器来说,访问中间件和访问数据库没有区别
- 与编程语言解耦,支持 SQL 接口即可
- 数据库中间件要支持完整的 SQL 语法和数据库服务器的协议,实现复杂,细节多
- 高性能高可用,所有的数据库操作请求都要经过中间件
- 数据库主从切换业务无感知
3. 分库
按照业务模块将数据分散到不同的数据库服务器。
存在的问题:
- JOIN 操作
- 事务
- 服务器成本
小公司初创业务,不建议分库:
- 务存在很大的不确定性,不一定有访问压力
- 增加工作量,拖慢业务节奏
4. 分表
4.1 垂直分表
将一张表结构的多列拆到多张表(拆分不常用且占空间的列)
查询次数翻倍
4.2 水平分表
表的数据量达到千万级别,要考虑
-
路由算法:
-
ID 范围
1 ~ 999999 放到数据库 1 的表中;1000000 ~ 1999999 放到数据库 2 的表中
可以随着数据的增加平滑地扩充新表;但是分布不均匀
-
Hash
选取某个列的值哈希,分散到不同的数据库表中
分布均匀;但是加表数据要重分布
-
配置路由
用一张独立的表来记录路由信息
必须多查询一次,数据量太大路由表本身可能有性能问题
-
-
JOIN
数据分散在多个表中,需要在业务代码或者数据库中间件中进行多次 JOIN 查询,然后将结果合并
-
COUNT()
-
COUNT() 相加
在业务代码或者数据库中间件中对每个表进行 COUNT() 操作,然后将结果相加
实现简单;性能低
-
记录数表
每次插入或者删除子表数据成功后,都更新对应记录数表
性能好;可能数据不一致
-
-
ORDER BY
业务代码或者数据库中间件分别查询每个子表中的数据,然后汇总进行排序