赞
踩
如果数据量过大,大家一般会分库分表。分库需要注意的内容比较少,但分表需要注意的内容就多了。
工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过分表。最近手里有个项目,预估数据量会很大,分表方案是选项之一,趁着这次机会,把分表的内容整理一下。
这次要讲的主要是水平分库分表,其它种类的分库、分表比较容易理解。后面如果不详细说明,都指水平分库分表。
垂直分库:按照业务模块进行切分,将不同模块的表切分到不同的数据库中。
如电商系统有电商数据库,按照业务模块可以分为用户库、商品库、订单库,这些都可以当做独立数据库,不需要放到一起。好处是既能独立变更,又能隔绝相互影响。
垂直分表:也就是“大表拆小表”,基于列字段进行的。一般是因为表设计不合理,需要进行拆分。
如一张表存放学生、老师、课程、成绩信息,最好拆分为学生表、课程表、成绩表。
水平分表:针对数据量巨大的单张表(比如订单表),按照某种规则(RANGE,HASH取模等),切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。不建议采用。
水平分库分表:将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈。
分表时经常能看到两个名词:分区和分片。这两个词都是指将大表的数据分成多块,但两者还是有本质区别的。
Sharding(分片) 的思想从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而 Sharding 是能够跨数据库,甚至跨越物理机器的。
MySQL5.1提供的分区(Partition)功能确实可以实现表的分区,但是这种分区是局限在单个数据库范围里的,它不能跨越服务器的限制。
我们在分表的时候,一般使用的是分片方案,即数据存放在多个物理机器。
分片规则一般有如下:
mod-long:用于分区列为数值的hash分区
分片列 id=分区列值 mod 分片数
mod-long-by-hash:用于分区列为字符串的hash分区
分片列id=hash(分区列值) mod 分片数
range:建表时创建分区规则,根据分区规则就可以确定分区列的值在哪个分区上
一般分区列为时间或者数值,如
date_range:
0: 1000000
1: 2000000
2: 3000000
3: 4000000
4: maxvalue
如果分区列值为1500000,则数据放到1号分片上。
需要使用者感知不到这是分片表,使用时需要和正常表一样,一般需要引入中间件。
操作分片表一般有三种方式:
所谓的客户端分片即在使用数据库的应用层直接操作分片逻辑,分片规则需要在同一个应用的多个节点间进行同步,每个应用层嵌入一个操作切片的逻辑实现。如当当网的Sharding JDBC。
代理分片就是在应用层和数据库层之间添加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,在业务实现之后,在代理层配置路由规则即可。如Mycat就是基于此种解决方案来实现的。
支持分布式事务的框架,目前有OceanBase、TiDB框架,这些框架将可伸缩特定和分布式事务的实现包装到了分布式数据库内部实现,对使用者透明,使用者不需要直接控制这些特性,但是对事务的支持不如关系型数据,适合大数据日志系统、统计系统、查询系统、社交网站等。
支持事务的分布式数据库算另一种选型了,和MySQL已经没有关系。
对于客户端分片和代理分片,目前工作过的两家公司用的都是代理方式,一家用的是MyCAT,一家用的Dbatman。客户端分片方式没有接触过。这两种的区别为:
分片意味数据分布在多台物理机器上,引入分布式事务问题。我们将单表的数据切片后存储在多个数据库甚至是多个数据库实例中,所以依靠数据库本身的事务机制不能满足需要,这时就需要用到分布式事务来解决。关于分布式事务的相关内容可以看分布式系统与一致性协议。
这里不细讲分布式事务如何处理,后面会单独写篇文章。我们聊一下分布式事务会对操作MySQL产生什么影响。
既然知道引入了分布式事务问题,那么操作MySQL的时候,肯定不能和单表一样进行操作。不同中间件能力不一样,所以需要单独分析,我以Dbatman为例,阐述使用上的区别。
总结一下就是操作同一个分片没影响,操作不同分片需要看中间件支持不支持。
选择做分库分表,考虑的几个要素是:
针对以上3点,我们还可以多考虑一下,有没有更合适的方案
空间方面:
主库性能:
容灾方面:
现在项目需求为:
基于上面的需求,做如下设计:
通过这种设计能够实现需求。
但计算后发现,单表能存百亿条数据,而且索引设计比较合理,业务逻辑相对简单,无高并发请求,单表好像也可以搞。
正常情况下,我们一般需要做水平分库分表,这就涉及到分布式事务,一定要考虑清楚是否能满足自己的需求、想用的SQL语句是否都能支持,考虑一下是否还有别的方案。
关于中间件的实现原理,了解的不是很深,后面有时间的话,可以学习一下。
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
招聘
设计模式
语言
架构
存储
网络
工具
读书笔记
思考
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。