数据库中间件基础
当单机数据库压力变大,常见的有两种处理方式,一是读写分离,类似于集群,一是分库,分表,即分布式。
读写分离的问题和对策
- 数据复制问题
- 应用对于数据源选择问题
主从数据同步,必然会在某一刻,数据的不一致,如果业务允许短时间的不一致,那只要保证最终一致即可。当然也可以采取强制读主库的方式。
对于读写多数据源,有两种形式,一种是通过 proxy 的形式,将 应用层 sql 发送给 proxy 机器,有 proxy 来判断给主库还是从库执行。另一种是在应用内配置两种数据源,根据 sql 的类型(读/写)来调用对应的数据库服务器。
单机到分布式的问题和对策
应用服务化后,每个微服务一个对应一个数据库,能很好的减轻数据库的压力,这也是垂直拆分,将较为内聚的业务拆到一个库中。
垂直拆分的问题:
- 单机的 acid 无法保证
- join 操作无法执行
对于分布式事务,强一致性会极大影响分布式系统的性能,因此提出 cap(一致性,可用性,分区容忍性) 理论,一般牺牲一致性来换取系统的可用性和分区容错性。不过牺牲一致性并不是完全放弃数据一致性,而是牺牲强一致性换取弱一致性,即 base 理论,Basic Available,Soft State,Eventual Consisstency。
分布式 join 的问题,一是将原有的 sql,分割为两条,在服务之间调用,二是分库建表时,冗余一些必要字段。
当然,除了垂直方向的分库,还有水平方向的分表,比如订单表,遇到活动,订单数激增,表迅速增大,此时就通过增加一张字段一样的表,来分摊单表的压力。
水平拆分新增的问题:
- 主键问题
- SQL 路由问题
- 分页查询问题
主键问题:有两个要素,唯一性和连续性,这里推荐 Twitter 的 Snowflake 算法,该算法生成的是 64 位唯一 Id(由 41 位的 timestamp+ 10 位自定义的机器码 + 13 位累加计数器组成)
SQL 路由问题:数据分片的时候按照指定的 key,路由存储到不到的表中。
分页查询问题:
- 不需要排序,可按等步长或等比例从多张表中取数据
- 需要排序,每张表都需获取足够查询页数的数据,在应用内合并排序,当页数过大时,负担越重,尽量避免。
数据库中间件的设计
- SQL 解析
- 对官方 SQL 的支持范围
- 规则处理
- 根据某个字段按照一定规则确定一组库,比如 id % 2 = 0 为 group db 1,id % 2 = 1 为 group db 2.
- SQL 改写
- 比如改写表名。水平拆分的表在同一个库中,表名不同,就需要在执行 SQL 时动态更换表名
- 数据源选择
- 确定一组数据源中的具体的某一个数据源
- SQL 执行
- 结果集返回,合并处理
开源的数据库中间件
Title: 数据库中间件基础
Author: mjd507
Date: 2019-06-02
Last Update: 2024-01-27
Blog Link: https://mjd507.github.io/2019/06/02/middle-ware-db/
Copyright Declaration: This station is mainly used to sort out incomprehensible knowledge. I have not fully mastered most of the content. Please refer carefully.