数据库读写分离
【实现原理】
1. 数据库服务器搭建主从集群,一主一从、一主多从都可以。
2. 数据库主机负责读写操作,从机只负责读操作。
3. 数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。
4. 业务服务器将读写操作发给数据库主机,将读操作发给数据库从机。
【如何判断要读写分离】
1. 业务量持续增长。
数据库读写分离 – 复杂度分析
1. 复制延迟;2. 任务分解。
数据库读写分离 – 复制延迟应对方法
【应对方法1 – 读写绑定】
写操作后的读操作指定发给数据库主服务器。
【缺点】
业务侵入很大,容易留坑。
【应对方法2 – 二次读取】
读从机失败后再读一次主机。
【缺点】
如果有很多二次读取,将大大增加主机的读操作压力。
【应对方法3 – 业务分级】
关键业务读写操作全部指向主机,非关键业务采用读写分离。
【缺点】
编码人员容易全部采用读写主机。
数据库读写分离 – 任务分解实现方式
程序代码封装模式
1. 实现简单,基于 JDBC 封装。
2. 维护简单,无部署,无需考虑高性能、高可用。
3. 每个语言都要实现一遍。
中间件封装模式
1. 实现复杂,独立服务器,需要实现连接管理。
2. 维护复杂,需要独立部署,并且要考虑集群部署支持高性能高可用。
3. 跨语言。
数据库分库
1. Join 问题
原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 Join 查询。
【解法】
1. 小表冗余
将一些小表在每个库中冗余一份,例如字典表。
2. 代码 Join
在代码里面实现 Join 功能。
3. 字段冗余
例如订单表直接记录商品类型。
2. 事务问题
表分散到不同的数据库中,无法通过事务统一修改。
【解法】
分布式事务。
【案例】
先扣商品库存,扣成功后生成订单,如果因为订单数据库异常导致生成订单失败,业务程序又需要将商品库存加上。而如果因为业务程序自己异常导致生成订单失败,则商品库存就无法恢复了,需要人工通过日志等方式来手工修复库存异常。
数据分表
1. 垂直拆分
按列拆分,优化单机处理性能,常见于2B领域超多列的表拆分。
2. 水平拆分
按行拆分,提升系统处理性能,常见于2C领域超多行的表拆分。
多大的表需要拆分?
1. B+Tree 的层数:3层大约是2000万条;
2. Innodb buffer pool:2000万数据,每条数据100字节,单表就2G了;
3. 数据量持续增长的表。
水平分表复杂度和应对方法
水平分表伸缩瓶颈
1. 每个应用都需要连接所有的分片,当应用数量增多后,数据库连接会逐渐成为瓶颈。以 MySQL 为例,默认100连接,实测50~100连接性能最高,超过200后会显著下降。
2. 单个Sharding-JDBC的聚合操作会有性能瓶颈。
分布式事务算法 – 2PC
阶段1:单个参与者故障会导致整体事务失败。
阶段2:事务协调者故障会导致整体状态不一致,参与者一直等待事务协调者指令,可能需要人工修复。
分布式事务算法 – 3PC
1. Yes 丢了会导致协调者取消事务。
2. 部分 preCommit 丢了会导致部分参与者超时取消事务,其它参与者收到了 preCommit 消息,然后超时提交事务,因此造成脑裂。
3. Ack 丢了会导致参与者超时提交事务。
4. doCommit 丢失会导致参与者超时提交事务。
原文始发于微信公众号(二进制跳动):存储架构模式之数据库存储架构:读写分离、分库分表、分布式事务等等
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/167115.html