分库分表事宜

分库分表概念
按字面解释,分库是把本来存储于一个库的数据分块存储到多个库上,分表是把本来存储于一个表的数据分块存储到多个表上。
合理的分库能够下降单台服务器的负载压力,合理的分表能够提高数据操做的效率。java

分库分表实施时能够分为:垂直切分和水平切分。
垂直切分
垂直切分是将表按照功能模块、关系密切程度划分出来,部署到不一样的库上,也就是分库。依据原则:将业务紧密,表间关联密切的表划分在一块儿。
例如,咱们会创建定义数据库workDB、商品数据库payDB、用户数据库userDB、日志数据库logDB等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。mysql

水平切分
水平切分是将表的数据按某种特定规范进行散列划分,而后存储到多个结构相同的表上。要实现水平切分,表中必须有冗余字段做为切分依据和标志字段。
例如,咱们的userDB中的用户数据表中,每个表的数据量都很大,就能够把userDB切分为结构相同的多个userDB:part0DB、part1DB等,
再将userDB上的用户数据表userTable,切分为不少userTable:userTable0、userTable1等,而后将这些表按照必定的规则存储到多个userDB上。sql

数据切分原则
实施数据库分库分表不只仅是一个技术方案,它须要开发人员充分了解系统业务逻辑和数据库schema,既要考虑业务逻辑的维护成本和可扩展性,同时也要兼顾数据库的性能及瓶颈。
若是数据库是由于表太多而形成海量数据,而且项目的各项业务逻辑划分清晰、低耦合,那么规则简单明了、容易实施的垂直切分必是首选。
若是数据库中的表并很少,但单表的数据量很大、或数据热度很高,这种状况之下就应该选择水平切分。
在现实项目中,每每是这两种状况兼而有之,这就须要作出权衡,甚至既须要垂直切分,又须要水平切分。
一般先对数据库进行垂直切分,而后,再针对一部分表,一般是用户数据表,进行水平切分。
分库分表也不是万能方案,与单库相比会带来以下问题:数据库

分布式事务问题。若是用数据库自身分布式事务管理,会付出高昂的性能代价;用程序逻辑控制,会形成开发上额外负担及风险。
跨库跨表的join问题。程序没法join位于不一样分库的表,也没法join分表粒度不一样的表,结果本来一次查询可以完成的业务,可能须要屡次查询才能完成。
额外的数据管理负担和数据运算压力。
  
通常来讲分库分表能够在如下层面进行实现:编程

实现层面
产品与框架
数据访问层(DAO层)    项目组自行实现
DAO与JDBC间的Spring数据访问封装层    CobarClient
JDBC驱动层    dbShards   shardingjdbc(当当开源)
ORM框架层    Guzz 、HibernateShards
应用服务器与数据库间的代理层    Routing4DB、TDDL、MysqlProxy、Amoeba服务器

DAO层实现
优点:
DAO层能够直接得到数据库表以及参数信息,无需SQL解析和路由规则匹配才能定位分区分片。
不受ORM框架制约,易于根据系统特色进行灵活的定制。
性能上没有额外的解析匹配,表现通常会比较好一些。
劣势:
有必定技术门槛,须要自行实现分库分表相关功能和特性。
因为缺乏框架支持,代码工做量会额外增长许多。
难以造成通用框架,每每只能在特定系统里工做。固然,在DAO层一样能够经过XML配置或是注解将分片逻辑抽离到“外部”,造成配置逻辑的可复用。mybatis

总结:通常小型项目才会采用这种技术选型,中大型项目会带来巨大的维护成本和风险。架构

Spring数据访问封装层实现
优点:
能够对上层代码透明。经过Spring的各类template来管理资源的建立与释放以及与事务的同步,能够达到和JDBC驱动层实现基本一致的效果,但实现就容易多了。
不受ORM框架制约。oracle

劣势:
须要依赖Spring。严格上说,目前Spring大行其道的今天,这不是一个问题,几乎没有哪一个java平台上构建的应用不使用Spring。
表明产品:阿里集团研究院开源的CobarClient。
CobarClient简介:
它是阿里巴巴研发的关系型数据的分布式处理系统,该产品成功替代了原先基于Oracle的数据存储方案,目前已经接管了3000+个MySQL数据库的schema,
平均天天处理近50亿次的SQL执行请求,优异的数据库性能和可靠的稳定性是它的突出优势,可是它存在以下限制:
只支持Mysql数据库,能够认为是CobarClient就是一种Mysql的大型集群方案。
有限度支持SQL语句,例如:不支持跨库状况下的join、分页、排序、子查询操做;分库状况下,insert语句必须包含拆分字段列名等。
有限度支持JDBC,例如:不支持useServerPrepStmts=true参数设置;BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法设置参数等。app

ORM框架层实现
优点:
能够和ORM无缝集合,减小开发工做量。
劣势:
受ORM框架制约。若是ORM框架发生变更,就会带来很大的维护成本。例如:hibernate下有hibernateShards的分库分表方案,
而mybatis由于插件机制控制不到多数据源的链接层面尚未成熟的分库分表框架。
O-RMapping的支持有限,不少场合仍是须要手动编写SQL。

表明产品:开源软件Guzz、hibernate的扩展产品hibernateShards。
Guzz简介:
Guzz是一种用来进行快速开发和高性能网站设计的框架,用于替代或者补充hibernate或mybatis的持久化实现,并提供更多的大型系统架构设计支持。
支持像hibernate同样的对象持久,映射和方便的增删改查
支持像ibatis同样,让dba参与sql设计的复杂数据库操做和优化
支持大量的数据库和主从分离
支持数据表在多组机器中水平分布(Shard)
它自己是以网站开发为主要目的,所以分库分表并不是核心,仍是有很多局限:
须要手动编写分片路由规则的java类,不能彻底依靠配置完成。
有限度支持SQL语句,例如:不支持分库分表状况下的join、Union等操做。

hibernateShards简介:
多数据库水平分区解决方案,Hibernate的一个扩展,用于处理多数据库水平分区架构。由google工程师在2007年捐献给Hibernate社区

JDBC API层实现
JDBC驱动层是不少人都会想到的一个实现分库分表的绝佳场所,若是能作到此点,那么分库分表方案对于整个应用程序来讲就是彻底透明的。
可是涉及各类平台的数据库,这种方案的技术门槛和工做量显然不是通常团队能作得来的,所以基本上没有团队会在这一层面上实现分库分表,甚至也没有此类的开源产品。
笔者知道的只有一款商业产品dbShards采用的是这一方案。能够采用当当开源的shardingjdbc产品。

代理实现
优点:
对应用程序彻底透明,通用性好。这种方案在应用服务器与数据库之间加入一个代理,应用程序向数据发出的数据请求会先经过代理,
代理会根据配置的路由规则,对SQL进行解析后路由到目标分片。业务层彻底不知道这些操做,所以这也成了不少中间件产品的选择方案。
可靠性高,不依赖任何框架。

劣势:
性能不是最优的。由于增长了代理,增长了额外的消息通信,对于实时性很高的业务系统,须要慎重考虑。
表明产品:TDDL、MysqlProxy、Amoeba


TDDL简介:
淘宝根据本身的业务特色开发了TDDL框架,主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的jdbc数据源实现,
具备主备,读写分离,动态数据库配置等功能。可是它存在以下限制:
支持mysql和oracle数据库,支持的数据库种类比较少。
只开源动态数据源,分表分库部分还未开源。TDDL必需要依赖diamond配置中心(diamond是淘宝内部使用的一个管理持久配置的系统,
目前淘宝内部绝大多数系统的配置,由diamond来进行统一管理,同时diamond也已开源)。
TDDL复杂度相对较高,当前公布的文档较少。

MysqlProxy简介:
它是Mysql的官方代理工具,处于客户端和MySQL服务端之间的中间层程序,它能够监测、分析或改变它们的通讯。它使用灵活,没有限制,
常见的用途包括:负载平衡,故障、查询分析,查询过滤和修改等等,它的局限很明显:

只支持Mysql数据库,并非一种通用技术解决方案。
使用lua脚本,能够实现复杂的链接控制和过滤。这一点技术团队必须考虑额外的学习成本。

Amoeba简介:
Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy。它集中地响应应用的请求,依据用户事先设置的规则,
将SQL请求发送到特定的数据库上执行。基于此能够实现负载均衡、读写分离、高可用性等需求。它使用很是简单,不使用任何编程语言,只须要经过xml进行配置。
它的局限以下:只支持Mysql数据库,并非一种通用技术解决方案。
还不支持事务。
只支持主从模式,还不支持分库分表。

 

还有一个很重要的就是Mycat,功能强大,能够参考。

开源选择的两个形式:jdbc层:shardingjdbc。

不作任何修改,直接迁移的mycat

相关文章
相关标签/搜索