机缘巧合之下,我以前接触到了一个从头开始的数据库中间件的项目;有一些小的感想,现在想静下心来把那个阶段的想法记录整理下来。从如何选型,如何权衡利弊,到后面的技术调研,难点分析,以及整体设计,代码设计。
当时观察到的现象
单库,主从:
- CPU负载高
- 响应时间变慢
- Master一段时间会挂掉,导致网站服务中断
分析问题
- 数据库压力较大
- 连接数过多
- 数据量单库不能满足高并发下存储,查询需求
现状分析
- 客户端业务很多,高达上千个应用
- 异构语言非常多,包括java,python,go,C#,C++等
- 业务正在爆发式增长,没有时间进行业务的技术升级改造
分析各种方案的优势劣势
NoSQL和中间件都有其各自的应用价值,需要根据实际情况来选择
开源解决方案的现状
结论分析
- 选择开源方案,技术不可控,对于后续架构升级不利
- 开源没有完全满足需求的方案,需要改造,改造需要耗费太大的精力,并且也不一定能够完成达成需求
- 自研如果使用客户端方案,需要比较大的改造,而且升级的话,依赖度耦合性非常高,业务方众多,并且业务爆炸式增长,没有时间和精力进行技术改造,业务方的诉求是无感知
- 自研使用Proxy方案,存在单点故障,一旦Proxy挂了,业务就挂了;技术实现难度大,需要解析mysql协议,单点需要应对超高并发,
经过分析,第4种方案,虽然难度较大,但是能够培养技术人才,并且能够技术自主,为后续架构升级打下坚实的基础
技术规划
- 一期(3个月),需求:降低高峰时期的数据库负载
主要实现:框架搭建,协议解析,信号量处理,转发请求 - 二期(2个月),需求:连接数降低
实现:连接池实现,模拟Mysql与客户端通过协议通信,数据源管理 - 三期(4个月),需求:分库分表
实现:sql解析,sql合并,路由转发,分库分表,配置管理 - 长期
- 主备切换
- 拦截
- 监控
- 分库分表多种分片方式
- 支持多种Nosql数据库
- session自动切换(目的:无损发布,故障转移;难点:事务)
- 自动扩容缩容方案
- …
限制
- 避免join
- 避免子查询
- 分页不要取太大的值,避免直接分页查询
- 避免跨库事务
- Group By,Order By,Having等条件,尽量带上分片主键
- insert语句必须带有拆分字段列名
- update语句不能更新拆分字段的值