mysql分表分库选型
Posted 起名什么的...
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql分表分库选型相关的知识,希望对你有一定的参考价值。
三个方向:
一、应用中自己实现,可直连数据库,自己实现因目前使用的Mybatis框架可以使用两种做法:
1、在SQL中直接分表逻辑,我查了一下代码中的sql,发现join的千姿百态,不大动这些sql这事基本不现实,优点是定制化,针对性比较高,性能方面损耗比较低,调试调优简单,但是扩展性要差一些。
2、在Mybatis的拦截器里对SQL进行截取拼装,如果能对指定表做的并对相关表的join sql调整一下的话,就是需要规划下占位符及分表jion策略,另外需要对多种情况进行大量测试,这个策略要比手改sql通用所以也复杂很多,相对于上一条,优缺点都相对模糊一点。
二、直接购买云服务DRDS,DRDS基于TDDL,但是与我们目前的RDS是不同的产品,切换时可能需要停机,TDDL的重点部分并未开源,对关键点的实现不好评估。DRDS分共享版和专享版两种,价格差别是数量级层面的,共享版比我们目前用的RDS要便宜很多,专享版要贵差不多一倍。据说已经有P2P公司在使用这个产品,推测使用的是最大送达模型,这个模型需要保证幂等,协调者(重试服务)必须高可用。
RDS迁移DRDS需要注意什么?
DRDS用的是最大努力送达?
分页如何处理的,会不会存在每次都是查询0到当前,越翻越慢的问题?
- 暂不支持非 WHERE 条件的 Correlate Subquery。
- 暂不支持 SQL 中带聚合条件的 Correlate Subquery。
https://help.aliyun.com/document_detail/49249.html?spm=5176.7947010.211449.2.4oyoNx
https://help.aliyun.com/document_detail/29669.html?spm=5176.7752178.6.586.xoHQwR
另外,阿里云还有全局事务服务,正在公测:https://www.aliyun.com/aliware/txc
三、通过中间件
首先排除掉收费的,之后考察了
MyCAT(https://github.com/MyCATApache):
社区爱好者在阿里cobar基础上进行二次开发,发现对我们公司不适合分库和多节点情况下使用,然而感觉单库单节点(单RDS主多从,拦截器实现读写分离)情况下,还要为它支出服务器和运维资源有些不值得,而且它本身没有提供高可用,需要另外部署haproxy,还要保证haproxy的高可用。多节点情况下,分页的sql在非第一页的情况下会被改写:
改写的原因应该是多节点数据混合排序,但是每次都是查0到当前最后对我们的应用情况来看,压力有些过,如果只用一个节点,看上去倒是不错
关于分表发现了这么一句注释:
这倒应该不是说不能join,说的应该是不能随意join,我并没花时间细致在代码里证明,它本身提供了一些说明,在join情况下有两种方式可用,一种是全局表,另外一种是join关联条件的数据要保证在同一库上,如果被jion的结果集中有部分数据没在当前SQL执行的所在库上,那么查询结果就是错的
第二个问题是分布式事务,也是多节点,无法保证强一致性:
循环执行收到的请求,如果是提交则执行CommitNodeHandler,如果是回滚则执行RollbackNodeHandler:
public void rollback() { final int initCount = session.getTargetCount(); lock.lock(); try { reset(initCount); } finally { lock.unlock(); } if (session.closed()) { decrementCountToZero(); return; } // 执行 int started = 0; for (final RouteResultsetNode node : session.getTargetKeys()) { if (node == null) { LOGGER.error("null is contained in RoutResultsetNodes, source = " + session.getSource()); continue; } final BackendConnection conn = session.getTarget(node); if (conn != null) { boolean isClosed=conn.isClosedOrQuit(); if(isClosed) { session.getSource().writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, "receive rollback,but find backend con is closed or quit"); LOGGER.error( conn+"receive rollback,but fond backend con is closed or quit"); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("rollback job run for " + conn); } if (clearIfSessionClosed(session)) { return; } conn.setResponseHandler(RollbackNodeHandler.this); //support the XA rollback if(session.getXaTXID()!=null && conn instanceof mysqlConnection) { MySQLConnection mysqlCon = (MySQLConnection) conn; String xaTxId = session.getXaTXID(); //exeBatch cmd issue : the 2nd package can not receive the response mysqlCon.execCmd("XA END " + xaTxId + ";"); mysqlCon.execCmd("XA ROLLBACK " + xaTxId + ";"); }else { conn.rollback(); } ++started; } }
但问题是已经成功的提交无法回滚,就会造成分库或多节点间数据不一致。
Vitess:
Youtube出的与我们现有架构中需要注入的接口对应不上,需要改造现有接口,不太满足要求
Atlas(https://github.com/Qihoo360/Atlas):
360开源的,但是在github上发现他们似乎不太会花精力维护了,最近一次代码的更新时两年前了,另外启了事务似乎不分读写都会走主库,关于跨库方面似乎也不是很符合我们的需求。
Oceanus(https://github.com/58code/Oceanus):已经很久没维护了,而且只有37个提交。
DBProxy (https://github.com/Meituan-Dianping/DBProxy)
美团,C语言开发的,独立部署式的,还是希望能有一个直连的,并且有问题可以自己改的
sharding-jdbc (https://github.com/dangdangdotcom/sharding-jdbc)
当当直连数据库式的,下面是2017-03-30截的图,大版本改动太大稳定性如何,感觉还是要看一段时间再入场比较好,
最大努力送达模型,其他方面目前感觉是最合适的,分片配置成一个就是不分库
==========================================================
咱最近用的github:https://github.com/saaavsaaa
微信公众号:
以上是关于mysql分表分库选型的主要内容,如果未能解决你的问题,请参考以下文章
分库分表 ---SpringBoot + ShardingSphere 实现分表