技术选型
既然要分库分表那数据库集群是少不了的,那我们的项目怎样和这些集群打交道呢?我调研了大概分为以下几种来完成这个功能(仅仅针对java项目)
中间件 |
例如淘宝开源的cobar,以及后来开源社区根据cobar做二次开发的Mycat(个人建议如果使用中间件的话可以考虑Mycat) |
Jar形式的开源工具 |
例如淘宝的TDDL,以及当当开源出来的,Sharding-JDBC等 |
动态数据源 |
根据自己的业务来指定数据源来完成不同库和表的操作 |
主键生成策略
既然要分库分表那么全局唯一主键也是我们需要考虑的问题,我所知道的和有使用经验的有如下几种技术:
|
问题 |
可行性 |
基于redis |
单点问题,redis重启问题等 |
较高,公司有项目使用 |
给予DB(每次生成多个使用时去取出来) |
单点问题,并发量问题 |
低并发,数据量较小的可以使用 |
UUID |
暂用存储空间比较大,非可排序的,体现不出增长的趋势 |
较高 |
twitter snowflake |
Xx年以后可能存在重复问题,需要配置生产参数 |
高,分布式的没单点故障问题,时间上是递增的。推荐 |
基于DB步长的方式 |
不是所有数据库都支持 |
低 |
分库分表后能解决我们的性能问题,但是也带来了很多其他的问题:
1.分完之后只能直接按分片键查询,为了避免扫所有分片,如果按非分片键查询,在OLTP环境中得走搜索引擎。数据库和搜索引擎同步数据靠binlog
2.按不同维度查询,比如买家维度和卖家维度查订单。除了走搜索引擎之外,还可以在不同的系统中各写一条订单数据。
3.ID得通过ID生成器。
4.有热点数据问题,比如一个超级买家,买了好多种商品,然而还有不怎么热的买家,没什么订单。解决方法两种,热点数据拿出来放到单独的系统。或者按数据块分片,比如十种商品算一个块,但这种方法具体细节我忘了,只是听人分享过。
5.跨库事务问题,NPC一般不用,补偿是一种方法,TCC是一种方法,TCC的变种,比如SAGA比如XTS,努力送达是一种方法
6.数据扩展问题,可以看看阿里的愚公。我个人觉得还半夜停机维护比较靠谱。
7.分页的坑,前期可以用中间件Limit,中期得走搜索引擎,后期OLAP
8.可用性问题,依赖数据库高可用方案。据说会出现 sharding 算法 会因为网络抖动 造成部分分区错误 导致片出问题
9.配置中心问题。尽量使用配置中心,不要用zookeeper
10.非代理模式,就是JDBC路由模式 每个client都会对 db开启pool ,数据库可能会死在数据库连接上,一种方法是定制
Mysql,设置高低水位,让超过数据库处理能力的数据库连接排队。第二种方法是在JDBC路由模式之上做Mysql的Proxy