数据访问层是一个链式的处理过程,并且多数组件都是提供对外提供JDBC的实现,提供服务的方式有三:
1) 提供专有API,通用性差
2) 通用性强的方式,如JDBC
3) 基于ORM的方式,可以在ORM框架上再包一层,对外暴露的还是原有框架的接口。
在合并查询时,JDBC优势明显。
数据访问层设计的基本步骤:SQL解析,规则处理,SQL改写,数据源选择,SQL执行和结果集返回合并处理。
1)在进行SQL解析时,解析的缓存可以提升解析速度。一个重要的事情是根据执行的SQL得到被操作的表,根据参数及规则来确定目标数据源的连接数。
2)规则处理时,可以采用固定hash,根据某个字段取模,然后分散到不同的库和表中,通常将周期性数据放在一起;也可以采用一致性hash,把节点对应的hash值变为了一个范围,不再是离散的;还可以通过在一个物理节点上对应多个虚拟节点且虚拟节点均匀分布的方式来解决增加或减少节点时负载不均衡的问题。映射表是根据分库分表字段的值的查表法来确定数据源的方法,一般用于热点数据的特殊处理,或者对不完全符合规律的的规则进行补充。
3)SQL修改一般用于表名,索引,以及跨库计算。
4)规则处理是确定一组数据源,数据源选择是确定具体某个数据源。
5)SQL执行和结果处理部分需要注意异常的判断和处理。
从工程上看,可以把spring中的driverClassName,username和password抽取出来做成一个公共配置,但最好在配置管理中心中进行。GroupDataSource解决了具体访问数据库的选择问题,具体选择策略是groupDataSource完成的重点包括根据事务,读写等特性选择主备,不同库间的选择等。GroupDataSource意味着分组数量的绑定,虽然不能整体缩放,但可以进行组内缩放、主备切换等。数据源分组后,通过对数据源进行功能切分,可以构建原子数据源,原子数据源仅管理一个具体的数据库。
数据访问层的部署也可以分为jar包和Proxy两种方式,与服务框架类似,使用Proxy时,协议同样可以使用数据库协议和私有协议,最好直接使用数据库协议。
数据库读写分离最好基于数据库的日志来进行数据的复制。数据变更场景包括:复制数据库,索引构建,缓存失效等,一般引入数据抽取器把数据源变更的信息加入到数据分发平台,数据采用器把这些变更应用到相应的目标上,数据分发平台是由多个管道组成的。不同的数据变更来源需要不同的抽取器来进行解析和变更进入分发平台的工作。在进行数据迁移时,记录增量的日志,迁移后,再对增量的变化处理。