数据库分库分表中间件,尽可能兼容 ShardingSphere 的 golang 实现, 基于小米 Gaea 魔改,但是路由算法支持 ShardingSphere 的 inline 表达式风格,而不是 Mycat/kingshard 这类晦涩而又不灵活的配置,移除多租户功能(配置太复杂了,部署多套即可)
已经决定全部重写,小米的代码仅参考逻辑!!!
最新的开发进度和代码看这里
尝试了 ShardingSphere Proxy, 其有着糟糕的 insert 性能和 CPU 100% 问题,官方 issue 里 CPU 问题给出的回复是让升级到一个 5.0 alpha 版本试试,注意,是试试, 这样的处理实在无法让人接受,我们有大量 insert 性能操作,使用 ShardingSphere Proxy 后造成数十倍的性能下降,注意,是数十倍,而且 CPU 100%,通过 jprofiler 观察 其 Command 部分占用了所有的 CPU , 尤其是 SqlParser, 核心组件的严重性能问题除了官方更新,自己基本是无法解决的。
-
Netty 工作线程池中使用 Jdbc 这种同步客户端可能是其底层设计上的最大问题,ShardingSphere 并没有用 Netty 客户端自己实现一个简易的 Mysql 客户端,而是偷懒用了 jdbc hikaricp, 这种重重叠叠的线程池造成 CPU 居高不下, 至少从 CPU 角度看是不应该用 JDBC 的。
-
直接 JDBC 的问题还在于从 MYSQL 请求到的二进制数据被 JDBC 解析一次,合并回去又要自己封装一次,相当于一份数据多次序列化反序列化,对于 Proxy 来说简直是噩梦, 多的不是,CPU 和字节拷贝的内存占用已经无形中多了很多,内存池化只能缓解,底层设计的邋遢上层基本无力优化,自己解析数据的好处在于处理合并时候可以直接操作二进制包,较少系统开销。
-
ShardingSphere 代码中并没有对列数据值的逻辑运算的优化编排,造成改写时候逻辑复杂,也就是缺少执行计划概念,这个问题最好的参考是 youtube 的 Vitess 项目。
总之,同样的场景,换用 Gaea 测试后性能恢复正常,但是其固化的分片方式又不太满足我们的需求,因此决定基于它造一个轮子。
小米的代码搬运了 kingshard、Vitess、tidb 等开源项目大量代码,查询计划部分通过表数组索引保存数据到装饰器造成代码难于阅读, Router 接口强绑定表索引分片方式,使得自己实现特殊分片逻辑成为不可能的任务,好在其解析 SQL 经过生产历练补漏了很多细节,具参考价值
- 移除小米自己的 logger, 使用 uber zap
- 支持 Mysql 8 登录认证(jdbc 测试通过)
- 支持 Mysql Workbench 连接
- 移除粘贴过来的的 SqlParser 代码, 使用 go module 直接引用 tidb 项目,方便升级
- 逻辑表呈现(使用管理工具时合并分片表为逻辑表)
- 重构路由和查询计划,支持 ShardingSphere 配置风格
- inline 表达式支持(进行中...)
- range 路由支持 (进行中...)
- 分片计划查看特定 SQL 支持
- 支持分布式事务
- 其他优化
Main 分支保证可用性,已支持 Mysql 8.0.X 登录协议,dev 分支实现新特性,个人临时工作保存,可能长期无法正常编译