58数据库中间件分析和架构设计-罗立树-2014221

数据库中间件架构设计文档

目录

数据库中间件架构设计文档 (1)

1 背景 (6)

2 风险评估和解决办法 (7)

2.1 事务支持 (7)

2.2 Sql语句复杂场景风险 (7)

2.3 性能问题 (7)

2.4 框架接入平滑过渡问题 (7)

2.5 分库分表和非分库分表共存场景 (7)

2.6 跨语言场景 (7)

2.7 存储过程支持 (7)

2.8 链接过多问题 (7)

3 总体架构设计及原理解析 (8)

3.1 Configuration组件 (9)

3.2 Exchange组件 (9)

3.2.1 Sqlparser (9)

3.2.2 Router (10)

3.2.3 Executors (10)

3.2.4 JDBCWrapper (10)

3.2.5 ConnectionProvider (10)

3.3 Result组件 (10)

3.3.1 Merger (10)

3.3.2 ResultHandler (10)

3.4 Monitor组件 (10)

4 功能分解及细节描述 (11)

4.1 Sql语句解析 (11)

4.1.1 普通语句 (11)

4.1.2 Limit...offset (11)

4.1.3 Group by (11)

4.1.4 Order by (11)

4.1.5 Having (11)

4.1.6 Join (11)

4.1.7 in (11)

4.1.8 between...and (11)

4.1.9 带函数的语句 (11)

4.1.10 嵌套查询 (11)

4.1.11 Union sql (12)

4.1.12 Union all sql (12)

4.1.13 intersect (12)

4.1.14 intersect all (12)

4.1.15 minus (12)

4.1.16 minus all (12)

4.1.17 except (12)

4.1.18 except all (12)

4.2 分库分表配置规则管理 (12)

4.3 分库路由策略 (12)

4.3.1 单字段路由 (12)

4.3.2 多字段路由 (13)

4.3.3 自定义路由 (13)

4.4 分表路由策略 (13)

4.4.1 单字段路由 (13)

4.4.2 多字段路由 (13)

4.4.3 自定义路由 (13)

4.5 分库分表查询方式 (13)

4.5.1 串行查询 (13)

4.5.2 并行查询 (13)

4.6 分库分表结果处理 (13)

4.6.1 合并普通查询结果 (13)

4.6.2 合并带函数查询结果 (13)

4.6.3 分页结果处理 (13)

4.7 分库分表监控 (13)

4.8 读写分离 (13)

4.9 多主多从 (14)

4.10 支持不同数据库(Oracle,mysql,db2等等) (14)

4.11 负载均衡 (14)

4.12 Failover处理 (14)

4.13 查询超时控制和重试策略 (14)

4.14 序列生成器 (14)

4.15 查询策略分析和展示 (14)

5 代码设计和实现 (15)

5.1 分包方式 (15)

5.2 功能扩展 (15)

5.3 日志输出规范 (15)

6 使用约束 (16)

6.1 Sql语句使用约束 (16)

6.2 事务使用约束 (16)

6.3 分库分表规则约束 (16)

6.4 跨表跨库查询约束 (16)

6.5 存储过程约束 (16)

6.6 跨语言约束 (16)

7 测试方案 (17)

7.1 功能测试 (17)

7.2 性能测试 (17)

7.2.1 测试场景 (17)

7.3 回归测试 (17)

7.3.1 Sql回归单元测试功能 (17)

7.3.2 接入系统回归功能测试 (19)

8 接入指南 (20)

8.1 配置和更新jar包依赖 (20)

8.2 添加配置中心配置 (20)

8.3 管理分库分表配置规则 (20)

9 管理功能 (21)

9.1 分库分表规则管理 (21)

9.2 负载均衡管理 (21)

10 监控功能 (22)

10.1 性能监控 (22)

10.2 慢查询监控 (22)

11 项目进度安排 (23)

11.1 人员分工 (23)

11.2 功能分解和进度安排 (23)

1 背景

随着业务的发展,数据越来越多,各个系统在数据库增长的情况下,单库单表的压力越来越大,58同城目前对于数据库的访问采用的是WF框架作为web开发框架,目前java方向上封装了DAL包,core包,dao包对数据库进行了抽象,统一了对数据库的访问。但是利用DAL,core,dao进行数据库访问,对于一些分库分表的需求来说,复杂度越来越高,开发和维护越来越困难,为此需要有一套通用的分布式的数据库解决方案,来降低开发人员,测试人员,DBA等人员的使用成本。

经过分析,对分库分表透明化可选的解决方案有:

<一>. 基于客户端,改造ORM框架或者数据访问框架(dao,dal,core等)

<二>. 基于jdbc,改造jdbc实现(简单修改dao,dal,core链接获取部分)

优点:性能较高,计算能力分散到各个应用服务器,计算资源得到充分利用,单机故障不会影响其它应用,轻量级,部署成本低,支持事务,数据库升级不受影响,支持单库事务,支持多种数据库

缺点:跨语言支持不足,使用透明性不够完美

<三>. 通过实现mysql C-S协议,编写在协议层完全透明的中间件

优点:几乎和mysql等价的使用成本

缺点:比较重量级,集群成本高,中间代理服务器运算成本压力比较大,一旦proxy服务器出现问题,会影响所有的应用,数据库升级需要考虑兼容问题

各自方案都有优劣吧,方案<二>实现起来比较简单,开发成本低一些,风险较少。方案<三>实现技术难度大一些,从使用的角度来说,方案<三>更好一些

因基于mysql协议开发难度比较大,实施的时候我建议<二>和<三>都采用,第一阶段先将<二>实施,等<三>成熟了再考虑迁移(配置方式一样,通用的路由规则和sql解析,并有一些经验)。

方案原则:采用分阶段,满足现阶段需求,降低风险,平滑过度,持续优化改进的方式进行发展

2 风险评估和解决办法

2.1 事务支持

因为性能问题,目前仅支持单库事务,跨库事务暂时不支持

2.2 Sql语句复杂场景风险

在应用中尽量排查复杂语句,否则在迁移过程中会带来功能错误

2.3 性能问题

性能问题主要是中间件实现的代码质量问题

2.4 框架接入平滑过渡问题

在切换过程中不影响现有业务,先测试环境充分测试,再拿一些影响不大的业务作为试点,拿一两台作为测试

2.5 分库分表和非分库分表共存场景

要求中间件的接入,对现有业务代码不分库的情况下无影响,分库分表功能正常,原有分库分表逻辑实现不受影响

2.6 跨语言场景

跨语言的支持采用SCF的方式,后续如有必要,采用mysql协议方式

2.7 存储过程支持

目前暂时不支持存储过程,需要各个业务方统计一下使用存储过程的例子

2.8 链接过多问题

迁移过程中,由于有些应用实现了分库分表的策略,则导致了两倍的链接增长

Mysql数据库本身是存在链接数限制的,目前

3 总体架构设计及原理解析

图2-1 总体架构图

图2-2 基于客户端的部署方式

图2-3 基于mysql客户端协议的部署方式

3.1 Configuration组件

负责管理配置信息,根据配置来满足分库分表功能

3.1.1 Configuration-core

负责配置的解析,配置文件生成,配置高可用等

3.1.2 Listeners

监听配置中心服务端配置的变更,及时更新配置

3.1.3 Configuration-admin 配置中心管理后台

3.2 Exchange组件

3.2.1 Sqlparser

解析sql语句组件,根据解析结果,来判断路由规则,支持不同数据库的sql解析(mysql,oracle,db2,postgreSQL,sqlserver等等)

3.2.2 Router

路由组件,将sql解析结果路由到不同的资源执行

3.2.3 Executors

执行器,负责执行sql

3.2.4 JDBCWrapper

对jdbc包的封装

3.2.5 ConnectionProvider

链接提供器,可以是datasource或者公司的连接池的封装

3.3 Resource组件

抽象资源组件,对数据库,缓存其他存储介质统一抽象成资源

3.3.1 DatabaseResource

对数据库资源的抽象

3.4 Result组件

3.4.1 Merger

合并sql执行结果

3.4.2 ResultHandler

处理结果集

3.5 Monitor组件

4 功能分解及细节描述

4.1 Sql语句解析

4.1.1 普通语句

普通语句经过sql解析,先判断是否满足分库分表策略,不满足则不需要路由

4.1.2 Limit…offset

当涉及到跨库的情况下,limit规则比较复杂,处理方式是从每个库中的表中查询出所有0,offset+size的数据,排序过程中取top (offset+size)的值,再offset开始截取

4.1.3 Group by

这个涉及到跨库的情况下处理同样复杂,从各个库中获取结果,再合并

4.1.4 Order by

各库获取,重新排序

4.1.5 Having

4.1.6 Join

仅支持相同路由规则的join,跨库join不支持

4.1.7 In

对in中的内容进行拆解,分别路由

4.1.8 between…and…

对区间进行判断,缩小路由范围

4.1.9 带函数的语句

对函数进行处理,常用的函数有:

Min,max,average….

4.1.10 嵌套查询

暂时不支持

4.1.11 Union sql

暂时不支持

4.1.12 Union all sql

暂时不支持

4.1.13 intersect

暂时不支持

4.1.14 intersect all

暂时不支持

4.1.15 minus

暂时不支持

4.1.16 minus all

暂时不支持

4.1.17 except

暂时不支持

4.1.18 except all

暂时不支持

4.2 分库分表配置规则管理4.3 分库路由策略

4.3.1 单字段路由

4.3.2 多字段路由

4.3.3 自定义路由

4.4 分表路由策略

4.4.1 单字段路由

4.4.2 多字段路由

4.4.3 自定义路由

4.5 分库分表查询方式

4.5.1 串行查询

4.5.2 并行查询

4.6 分库分表结果处理

4.6.1 合并普通查询结果

4.6.2 合并带函数查询结果

4.6.3 分页结果处理

4.7 分库分表监控

监控分库分表中是否存在异常,性能等

4.8 读写分离

实现读写分离的透明处理

4.9 多主多从

4.10 支持不同数据库(Oracle,mysql,db2等等)

因为不同厂商开发的数据库产品不一样,各自在sql的标准也不一样,从而导致sql解析起来比较困难,因而需要对常用的数据库sql解析进行定制化开发,假如开发中都是采用标准化的sql,是不存在数据库兼容问题的。目前兼容性上仅考虑mysql

4.11 负载均衡

根据不同的负载配置,采用合适的策略来进行路由分配:

轮询,随机……等等

4.12 Failover处理

根据读写分离配置策略,多主多备的情况下,配置failover的处理,

Failover的处理细节如下:

当slave挂掉一台,自动切换到另外一台,恢复自动检测重新路由

当master挂掉一台,切换到另外一台,自动检测恢复

4.13 查询超时控制和重试策略

可以配置,控制每个查询的超时时间

支持失败重试策略配置,只允许读重试,写入重试不允许

4.14 序列生成器

提供一个全局的序列生成器

4.15 查询策略分析和展示

提供接口可以调试某个sql的路由分析结果,通过log的方式展示

5 代码设计和实现

5.1 分包方式

5.2 功能扩展

5.3 日志输出规范

5.3.1 中间件名称(英文)-Performance.log 性能日志输出

5.3.2 中间件名称(英文)-Debug.log

Debug模式日志输出

5.3.3 中间件名称(英文)-Error.log

错误异常输出

6 使用约束

6.1 Sql语句使用约束

?不支持跨库情况下的join、分页、排序、子查询操作。

?分库分表情况下,insert语句必须包含分库分表相关字段列名。

?分库分表情况下,update语句不能更新分库分表相关字段的值。

6.2 事务使用约束

目前只支持单库事务,尽量不要使用跨库事务

6.3 分库分表规则约束

分库分表条件尽量不要太复杂,在使用的时候先考虑使用场景6.4 跨表跨库查询约束

跨库查询尽量不要查询大量数据,对分页查询尽量不要太大

6.5 存储过程约束

目前不支持存储过程

6.6 跨语言约束

目前不支持跨语言

7 测试方案

7.1 功能测试

测试case(等待测试人员一起完善)

7.2 性能测试

7.2.1 测试场景

7.3 回归测试

7.3.1 Sql回归单元测试功能

不分库分表的sql

普通分库sql

普通分表sql

带limit sql

带order by sql

带group by sql

带having sql

嵌套sql

Join sql

in sql between… and … sql Union sql

Union all sql

intersect

intersect all

minus

minus all

except

except all

各种条件组合测试

7.3.2 接入系统回归功能测试系统接入需要做功能回归测试,确保无功能异常

8 接入指南

8.1 配置和更新jar包依赖8.2 添加配置中心配置8.3 管理分库分表配置规则

相关文档
最新文档