mysql分表分库选型

三个方向:

一、应用中自己实现,可直连数据库,自己实现因目前使用的Mybatis框架可以使用两种做法:

1、在SQL中直接分表逻辑,我查了一下代码中的sql,发现join的千姿百态,不大动这些sql这事基本不现实,优点是定制化,针对性比较高,性能方面损耗比较低,调试调优简单,但是扩展性要差一些。

2、在Mybatis的拦截器里对SQL进行截取拼装,如果能对指定表做的并对相关表的join sql调整一下的话,就是需要规划下占位符及分表jion策略,另外需要对多种情况进行大量测试,这个策略要比手改sql通用所以也复杂很多,相对于上一条,优缺点都相对模糊一点。

二、直接购买云服务DRDS,DRDS基于TDDL,但是与我们目前的RDS是不同的产品,切换时可能需要停机,TDDL的重点部分并未开源,对关键点的实现不好评估。DRDS分共享版和专享版两种,价格差别是数量级层面的,共享版比我们目前用的RDS要便宜很多,专享版要贵差不多一倍。据说已经有P2P公司在使用这个产品,推测使用的是最大送达模型,这个模型需要保证幂等,协调者(重试服务)必须高可用。

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基础上进行二次开发,发现对我们公司不适合分库和多节点情况下使用,然而感觉单库单节点情况下,还要为它支出服务器和运维资源有些不值得。多节点情况下,分页的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

微信公众号:

                      

时间: 2025-01-01 20:47:38

mysql分表分库选型的相关文章

总结下Mysql分表分库的策略及应用

上月前面试某公司,对于mysql分表的思路,当时简要的说了下hash算法分表,以及discuz分表的思路,但是对于新增数据自增id存放的设计思想回答的不是很好(笔试+面试整个过程算是OK过了,因与个人预期的薪酬不太理想而忍痛放弃.),在此再深究下mysql 分表优化之类的设计思路方案.先来闲扯下发文目的: 为什么要分表和分区? 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情

Mysql分表分库分析

对于大型的互联网应用,数据库单表的数据量可能达到千万甚至上亿级别,同时面临这高并发的压力.Master-Slave结构只能对数据库的读能力进行扩展,写操作还是集中在Master中,Master并不能无限制的挂接Slave库,如果需要对数据库的吞吐能力进行进一步的扩展,可以考虑采用分库分表的策略. 1.分表 在分表之前,首先要选中合适的分表策略(以哪个字典为分表字段,需要将数据分为多少张表),使数据能够均衡的分布在多张表中,并且不影响正常的查询.在企业级应用中,往往使用org_id(组织主键)做为

mysql分表分库 ,读写分离

1.分表 当项目上线后,数据将会几何级的增长,当数据很多的时候,读取性能将会下降,更新表数据的时候也需要更新索引,所以我们需要分表,当数据量再大的时候就需要分库了. a.水平拆分:数据分成多个表 b.垂直拆分:字段分成多个表 c.插入/更新/删除数据和查询统计 MyISAM存储引擎有一个MERGE存储引擎,可以将多个表合成一个表,就可以进行这四种操作   InnoDB用alter able可以将变成MyISAM存储引擎,然后使用MERGE引擎 面试题:MERGE存储引擎将N个子表合并,那么在数据

重新学习Mysql数据13:Mysql主从复制,读写分离,分表分库策略与实践

一.MySQL扩展具体的实现方式 随着业务规模的不断扩大,需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量. 关于数据库的扩展主要包括:业务拆分.主从复制.读写分离.数据库分库与分表等.这篇文章主要讲述数据库分库与分表 (1)业务拆分 在?大型网站应用之海量数据和高并发解决方案总结一二?一篇文章中也具体讲述了为什么要对业务进行拆分. 业务起步初始,为了加快应用上线和快速迭代,很多应用都采用集中式的架构.随着业务系统的扩大,系统变得越来越复杂,越来越难以维护,开发效率变得越

Mycat分表分库怎么分?Mysql DBA学习

Mycat分表分库虽然能解决大表对数据库系统的压力,但也有一些不利,因此Mycat分表分库要先解决的问题是,分不分库,分哪些库,什么规则分,分多少分片.那么究竟是怎么分的呢? 1.能不分就不分,1000万以内的表,不建议分片,通过合适的索引,读写分离等方式,可以很好的解决性能问题. 2.分片数量尽量少,分片尽量均匀分布在多个DataHost上,因为一个查询SQL跨分片越多,则总体性能越差,虽然要好于所有数据在一个分片的结果,只在必要的时候进行扩容,增加分片数量. 3.分片规则需要慎重选择,分片规

Mysql分表和分区的区别、分库分表介绍与区别

分表和分区的区别: 一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看:mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,具体请参考mysql分区功能详细介绍,以及实例 二,mysql分表和分区有什么区别呢 1,实现方式上 a),mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完正的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表

分表分库方法总结

案例一: 1,背景:一个地址薄的应用程序,设计的用户量为2亿,统计出每个用户的地址薄为30个左右,整个数据量为60亿,使用mysql数据库 计划分为:1000个表,100个库 2,分库分表代码 ? 1 2 3 4 5 6 7 8 private function getDbNo($email)  {      $m = md5($email);      $n = hexdec(substr($m, 0, 16));      $tableNo = fmod($n, 1000);      $d

一、mysql分表简单介绍

一.Mysql分表的原因 1.当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了. 分表的目的就在于此,减小数据库的负担,缩短查询时间. 2.mysql中有一种机制是表锁定和行锁定,为什么要出现这种机制,是为了保证数据的完整性, 我举个例子来说吧,如果有二个sql都要修改同一张表的同一条数据,这个时候怎么办呢,是不是二个sql都可以同时修改这条数据呢? 很显然mysql对这种情况的处理是,一种是表锁定(myisam存储引擎),一个是行锁定(innod

Mysql分表分区

分表 1 我事先建100个这样的表,message_00,message_01,message_02..........message_98,message_99.然后根据用户的ID来判断这个用户的聊天信息放到哪张表里面,你可以用hash的方式来获得,可以用求余的方式来获得,方法很多,各人想各人的吧.下面用hash的方法来获得表名: 查看复制打印? <?php function get_hash_table($table,$userid) { $str = crc32($userid); if(