本文主要是介绍分库分表问题汇总---更新中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
分布式全局唯一ID
往往直接使用数据库自增特性来生成主键ID,而在分库分表的环境中,数据分布在不同的分片上,不能再借助数据库自增长特性直接生成,否则会造成不同分片上的数据表主键会重复。
-
Twitter的Snowflake(又名“雪花算法”)
-
UUID/GUID(一般应用程序和数据库均支持)
-
MongoDB ObjectID(类似UUID的方式)
-
Ticket Server(数据库生存方式,Flickr采用的就是这种方式)
常见分片规则和策略
分片字段该如何选择
一般采用id和时间做分片字段,也可以集合业务,,对执行中的sql语句进行分析,选出最被频繁使用和重要的字段为分片字段
跨分片技术问题
跨分片的排序分页
当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片,
当排序字段非分片字段的时候,我们需要在不同的分片节点中将数据进行排序并返回,并将不同分片返回的结果集进行汇总和再次排序
跨分片join
(1)全局表
把一些类似数据字典又可能会产生join查询的表信息放到各分片中,从而避免跨分片的join
(2)ER分片
在关系型数据库中,表之间往往存在一些关联的关系。如果我们可以先确定好关联关系,并将那些存在关联关系的表记录存放在同一个分片上,那么就能很好的避免跨分片join问题。在一对多关系的情况下,我们通常会选择按照数据较多的那一方进行拆分
(3)字段冗余
一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。例如,订单表在保存userId的时候,也将userName也冗余的保存一份,这样查询订单详情顺表就可以查到用户名userName,就不用查询买家user表了。但这种方法适用场景也有限,比较适用依赖字段比较少的情况,而冗余字段的一致性也较难保证。
(4)数据组装
在系统service业务层面,分两次查询,第一次查询的结果集找出关联的数据id,然后根据id发起器二次请求得到关联数据,最后将获得的结果进行字段组装。这是比较常用的方法。
跨节点分页、排序、函数问题
跨节点多库进行查询时,会出现limit分页、order by 排序等问题。分页需要按照指定字段进行排序,当排序字段就是分页字段时,通过分片规则就比较容易定位到指定的分片;当排序字段非分片字段时,就变得比较复杂.需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序
在使用Max、Min、Sum、Count之类的函数进行计算的时候,也需要先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总再次计算
跨分片事务问题
跨分片事务也分布式事务,想要了解分布式事务,就需要了解“XA接口”和“两阶段提交”。值得提到的是,MySQL5.5x和5.6x中的xa支持是存在问题的,会导致主从数据不一致。直到5.7x版本中才得到修复。Java应用程序可以采用Atomikos框架来实现XA事务(J2EE中JTA)。感兴趣的读者可以自行参考《分布式事务一致性解决方案》,链接地址:
http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency
当更新内容同时存在于不同库找那个,不可避免会带来跨库事务问题。跨分片事务也是分布式事务,没有简单的方案,一般可使用“XA协议”和“两阶段提交”处理。 分布式事务能最大限度保证了数据库操作的原子性。但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间,导致事务在访问共享资源时发生冲突或死锁的概率增高。随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平扩展的枷锁。
最终一致性
对于那些性能要求很高,但对一致性要求不高的系统,往往不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,可采用事务补偿的方式。与事务在执行中发生错误立刻回滚的方式不同,事务补偿是一种事后检查补救的措施,一些常见的实现方法有:对数据进行对账检查,基于日志进行对比,定期同标准数据来源进行同步等。
数据迁移、扩容问题
当业务高速发展、面临性能和存储瓶颈时,才会考虑分片设计,此时就不可避免的需要考虑历史数据的迁移问题。一般做法是先读出历史数据,然后按照指定的分片规则再将数据写入到各分片节点中。此外还需要根据当前的数据量个QPS,以及业务发展速度,进行容量规划,推算出大概需要多少分片(一般建议单个分片的单表数据量不超过1000W)
什么时候考虑分库分表
能不分就不分
并不是所有表都需要切分,主要还是看数据的增长速度。切分后在某种程度上提升了业务的复杂程度。不到万不得已不要轻易使用分库分表这个“大招”,避免“过度设计”和“过早优化”。分库分表之前,先尽力做力所能及的优化:升级硬件、升级网络、读写分离、索引优化等。当数据量达到单表瓶颈后,在考虑分库分表。
数据量过大,正常运维影响业务访问
这里的运维是指:
对数据库备份,如果单表太大,备份时需要大量的磁盘IO和网络IO
对一个很大的表做DDL,MYSQL会锁住整个表,这个时间会很长,这段时间业务不能访问此表,影响很大。
大表经常访问和更新,就更有可能出现锁等待。
随着业务发展,需要对某些字段垂直拆分
这里就不举例了。在实际业务中都可能会碰到,有些不经常访问或者更新频率低的字段应该从大表中分离出去。
数据量快速增长
随着业务的快速发展,单表中的数据量会持续增长,当性能接近瓶颈时,就需要考虑水平切分,做分库分表了。
这篇关于分库分表问题汇总---更新中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!