数据库分库分表⽅案
oracle数据库怎么查询表MySQL使⽤为什么要分库分表
可以⽤说⽤到MySQL的地⽅,只要数据量⼀⼤, 马上就会遇到⼀个问题,要分库分表.
这⾥引⽤⼀个问题为什么要分库分表呢?MySQL处理不了⼤的表吗?
其实是可以处理的⼤表的.我所经历的项⽬中单表物理上⽂件⼤⼩在80G多,单表记录数在5亿以上,⽽且这个表
属于⼀个⾮常核⽤的表:朋友关系表.
但这种⽅式可以说不是⼀个最佳⽅式. 因为⾯临⽂件系统如Ext3⽂件系统对⼤于⼤⽂件处理上也有许多问题.
这个层⾯可以⽤xfs⽂件系统进⾏替换.但MySQL单表太⼤后有⼀个问题是不好解决: 表结构调整相关的操作基
本不在可能.所以⼤项在使⽤中都会⾯监着分库分表的应⽤.
从Innodb本⾝来讲数据⽂件的Btree上只有两个锁, 叶⼦节点锁和⼦节点锁,可以想⽽知道,当发⽣页拆分或是添加
新叶时都会造成表⾥不能写⼊数据.
所以分库分表还就是⼀个⽐较好的选择了.
那么分库分表多少合适呢?
经测试在单表1000万条记录⼀下,写⼊读取性能是⽐较好的. 这样在留点buffer,那么单表全是数据字型的保持在
800万条记录以下, 有字符型的单表保持在500万以下.
如果按 100库100表来规划,如⽤户业务:
500万*100*100 = 50000000万 = 5000亿记录.
⼼⾥有⼀个数了,按业务做规划还是⽐较容易的.
⼀、背景介绍
1.⼤数据量的存储需要⼤量的资源;
2.数据量的不断增长要求数据库存储具有可扩展性;
3.在保证⼤数据量的情况下,要保证性能、⾼可⽤性等质量要求;
4.现有框架中没有彻底解决⼤数据量的存储问题;
5.等海量存储⽅案价格不菲,采⽤MySQL进⾏分库分表节约IT成本。
⼆、可⾏性分析
1.    风险评估
1)      DBA数据库管理的资源和规范要求;
2.    业务数据量规模和变化的影响
1)      对于事先可规划的中等以上数据规模,采⽤单库分表(⼀个数据库实例,分多张表)、读写分离、或者多库多表(多个数据库实例,多张表)可以满⾜业务需求,且相应设计和实现相对简单,不易出错。
2)      对于初期数据规模不可准确预知,但随着业务发展数据规模不断增长的,要求数据存储具有可扩展性。这种可扩展性通过分库分表解决,要求分库分表在路由上具有极强的伸缩性,这也是分库分表的难点,本⽅案提出⼀个循序渐进的实现路线逐步解决这个问题。
3.    技术积累
1)      公司已有简单的分库分表⽅案
2)      这个⽅案缺乏扩展性
3)      本⽅案将提出短期实现⼀定扩展性、中长期⾼可扩展性的⽅案
4.    开源或产品
1)      商业版数据库Sharding:MySQL Proxy,提供MySQL协议接⼝(⾮JDBC),主从结构,可以负载平衡,读写分离,failover 等,lua语法复杂,不⽀持⼤数据量的分库分表;
2)      Amoeba,⽀持分数据库实例,每个数据相同的表,不⽀持事务;类似MySQL Proxy,设计上抛弃lua,更简单;
3)      阿⾥集团研究院开源的CobarClient,主要⾯向⼩规模的数据库sharding集访问,基于ibatis,需要规划数据规模,缺乏扩展性;另外有Cobar,阿⾥集团内部的⼀个完整DAL层,实现完整JDBC代理;
4)      HibernateShards,Hibernate提供的sharding,⽀持分数据库实例,⽐较复杂,事先规划数据规模,和框架不符;
5)      guzz,多库(虚拟的数据库,实际数据库的路由规则仍然⾃定义)、表分切、读写分离,以及多台数据库之间透明的分布式事务⽀持,设计⽬标是⽀持⼤型在线⽣产应⽤;需完全替换ibatis;完全和框架不符。
6)      TDDL,淘宝的DAL,很强的分库分表能⼒,仍然需要数据量实现规划,动态扩展有限。
7)      以上某些产品在⼀定程度上可以满⾜我们的需求,但不能彻底解决我们⼤数据量可扩展的问题。
三、性能指标
1.      和没有引⼊分库分表时相⽐,每次操作最⼤延迟<1ms;
四、特性列表和RoadMap
1.    垂直分库,不同业务数据使⽤不同数据库实例存储
2.    数据切分:
a)      根据切分字段Hash取模;
b)      确定需要切分的数据,尽量将可能进⾏关联的分⽚数据放在⼀个数据库实例中,例如同⼀⽤户的基本信息、好友信息或者⽂件信息等;
3.    短期:分库分表
a)      数据库实例编号递增
b)      每个数据库内分表序号从1递增,不全局编号
c)      基于数据源(ibatis基础上)拦截建⽴访问层,应⽤感知
d)      应⽤需在底层进⾏数据源、分布式事务考虑和管理等
e)      可扩展性:只⽀持向上扩展,不⽀持收缩
4.    长期:数据库访问层
a)      建⽴灵活的数据切分和路由规则
b)      ⽀持MySQL集
c)      读写分离和负载均衡
d)      可⽤性探测
e)      分布式事务
f)        对应⽤透明
⼀、互联⽹当下的数据库拆分过程
对于⼀个刚上线的互联⽹项⽬来说,由于前期活跃⽤户数量并不多,并发量也相对较⼩,所以此时企业⼀般都会选择将所有数据存放在⼀个数据库中进⾏访问操作。但随着后续的市场推⼴⼒度不断加强,⽤户数量和并发量不断上升,这时如果仅靠⼀个数据库来⽀撑所有访问压⼒,⼏乎是在⾃寻死路。所以⼀旦到了这个阶段,⼤部分Mysql DBA就会将数据库设置成读写分离状态,也就是⼀个Master节点对应多个Salve节点。经过Master/Salve模式的设计后,完全可以应付单⼀数据库⽆法承受的负载压⼒,并将访问操作分摊⾄多个Salve节点上,实现真正意义上的读写分离。但⼤家有没有想过,单⼀的Master/Salve模式⼜能抗得了多久呢?如果⽤户数量和并发量出现量级上升,单⼀的Master/Salve模式照样抗不了多久,毕竟⼀个Master节点的负载还是相对⽐较⾼的。为了解决这个难题,Mysql DBA会在单⼀的Master/
Salve模式的基础之上进⾏数据库的垂直分区(分库)。所谓垂直分区指的是可以根据业务⾃⾝的不同,将原本冗余在⼀个数据库内的业务表拆散,将数据分别存储在不同的数据库中,同时仍然保持Master/Salve模式。经过垂直分区后的Master/Salve模式完全可以承受住难以想象的⾼并发访问操作,但是否可以永远⾼枕⽆忧了?答案是否定的,⼀旦业务表中的数据量⼤了,从维护和性能⾓度来看,⽆论是任何的CRUD操作,对于数据库⽽⾔都是⼀件极其耗费资源的事情。即便设置了索引,仍然⽆法掩盖因为数据量过⼤从⽽导致的数据库性能下降的事实,因此这个时候Mysql DBA或许就该对数据库进⾏⽔平分区(分表,sharding),所谓⽔平分区指的是将⼀个业务表拆分成多个⼦表,⽐如user_table0、user_table1、user_table2。⼦表之间通过某种契约关联在⼀起,每⼀张⼦表均按段位进⾏数据存储,⽐如user_table0存储1-10000的数据,⽽user_table1存储10001-20000的数据,最后user_table3存储20001-30000的数据。经过⽔平分区设置后的业务表,必然能够将原本⼀张表维护的海量数据分配给N个⼦表进⾏存储和维护,这样的设计在国内⼀流的互联⽹企业⽐较常见,如图1-1所⽰:
图1-1 ⽔平分区
上述笔者简单的讲解了数据库的分库分表原理。接下来请⼤家认真思考下。原本⼀个数据库能够完成的访问操作,现在如果按照分库分表模式设计后,将会显得⾮常⿇烦,这种⿇烦尤其体现在访问操作上。因为持久层需要判断出对应的数据源,以及数据源上的⽔平分区,这种访问⽅式我们称之为访问“路由”。按照常理来说,持久层不应该负责数据访问层(DAL)的⼯作,它应该只关⼼one to one的操作形式,所以淘宝的TDDL框架诞⽣也就顺其⾃然了。
⼆、TDDL的架构原型
淘宝根据⾃⾝业务需求研发了TDDL(Taobao Distributed Data Layer)框架,主要⽤于解决分库分表场景下的访问路由(持久层与数据访问层的配合)以及异构数据库之间的数据同步,它是⼀个基于集中式配置的JDBC DataSource实现,具有分库分表、Master/Salve、动态数据源配置等功能。
就⽬前⽽⾔,许多⼤⼚也在出⼀些更加优秀和社区⽀持更⼴泛的DAL层产品,⽐如Hibernate Shards、Ibatis-Sharding等。如果你要问笔者还为什么还要对TDDL进⾏讲解,那么笔者只能很⽆奈的表⽰公司要这么⼲,因为很多时候技术选型并不是笔者说了算,⽽是客户说了算。当笔者费劲所有努⼒在google上寻TDDL的相关使⽤说明和介绍时,⼼⾥⼀股莫名的⽕已经开始在蔓延,对于更新缓慢(差不多⼀年没更新过SVN),⼏乎没社区⽀持(提问从不响应)的产品来说,除了蜗居在企业内部,必定⾛不了多
远,最后的结局注定是悲哀的。好了,既然抱怨了⼀番,⽆论如何还是要坚持讲解完。TDDL位于数据库和持久层之间,它直接与数据库建⽴交道,如图1-2所⽰:
图1-2 TDDL所处领域模型定位
传说淘宝很早以前就已经对数据进⾏过分库分表处理,应⽤层连接多个数据源,中间有⼀个叫做DBRoute的技术对数据库进⾏统⼀的路由访问。DBRoute对数据进⾏多库的操作、数据的整合,让应⽤层像操作⼀个数据源⼀样操作多个数据库。但是随着数据量的增长,对于库表的分法有了更⾼的要求,例如,你的商品数据到了百亿级别的时候,任何⼀个库都⽆法存放了,于是分成2个、4个、8个、16个
、32个……直到1024个、2048个。好,分成这么多,数据能够存放了,那怎么查询它?这时候,数据查询的中间件就要能够承担这个重任了,它对上层来说,必须像查询⼀个数据库⼀样来查询数据,还要像查询⼀个数据库⼀样快(每条查询要求在⼏毫秒内完成),TDDL就承担了这样⼀个⼯作(其他DAL产品做得更好),如图1-3所⽰:
图1-3 TDDL分库分表查询策略
上述笔者描述了TDDL在分库分表环境下的查询策略,那么接下来笔者有必要从淘宝官⽅copy它们⾃⼰对TDDL优点的⼀些描述,真实性不敢保证,毕竟没完全开源,和社区零⽀持,⼤家看⼀看就算了,别认真。
淘宝⼈⾃定的TDDL优点:
1、数据库主备和动态切换;
2、带权重的读写分离;
3、单线程读重试;
4、集中式数据源信息管理和动态变更;
5、剥离的稳定jboss数据源;
6、⽀持mysql和oracle数据库;
7、基于jdbc规范,很容易扩展⽀持实现jdbc规范的数据源;
8、⽆server,client-jar形式存在,应⽤直连数据库;
9、读写次数,并发度流程控制,动态变更;
10、可分析的⽇志打印,⽇志流控,动态变更;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。