快速建设网站工具,办公楼网络组建方案设计,公司一般有哪些部门,徐州关键字优化公司中大型项目中#xff0c;一旦遇到数据量比较大#xff0c;小伙伴应该都知道就应该对数据进行拆分了。有垂直和水平两种。
垂直拆分比较简单#xff0c;也就是本来一个数据库#xff0c;数据量大之后#xff0c;从业务角度进行拆分多个库。如下图#xff0c;独立的拆分出…中大型项目中一旦遇到数据量比较大小伙伴应该都知道就应该对数据进行拆分了。有垂直和水平两种。
垂直拆分比较简单也就是本来一个数据库数据量大之后从业务角度进行拆分多个库。如下图独立的拆分出订单库和用户库。 水平拆分的概念是同一个业务数据量大之后进行水平拆分。 上图中订单数据达到了4000万我们也知道mysql单表存储量推荐是百万级如果不进行处理mysql单表数据太大会导致性能变慢。使用方案可以参考数据进行水平拆分。把4000万数据拆分4张表或者更多。当然也可以分库再分表把压力从数据库层级分开。
关注公众号架构之路回复666可获取一份 2TB 架构师资料。
分库分表方案
分库分表方案中有常用的方案hash取模和range范围方案分库分表方案最主要就是路由算法把路由的key按照指定的算法进行路由存放。下边来介绍一下两个方案的特点。
1、hash取模方案 在我们设计系统之前可以先预估一下大概这几年的订单量如4000万。每张表我们可以容纳1000万也我们可以设计4张表进行存储。 那具体如何路由存储的呢hash的方案就是对指定的路由key如id对分表总数进行取模上图中id12的订单对4进行取模也就是会得到0那此订单会放到0表中。id13的订单取模得到为1就会放到1表中。为什么对4取模是因为分表总数是4。 优点
订单数据可以均匀的放到那4张表中这样此订单进行操作时就不会有热点问题。 热点的含义热点的意思就是对订单进行操作集中到1个表中其他表的操作很少。 订单有个特点就是时间属性一般用户操作订单数据都会集中到这段时间产生的订单。如果这段时间产生的订单 都在同一张订单表中那就会形成热点那张表的压力会比较大。 缺点
将来的数据迁移和扩容会很难。
如业务发展很好订单量很大超出了4000万的量那我们就需要增加分表数。如果我们增加4个表 一旦我们增加了分表的总数取模的基数就会变成8以前id12的订单按照此方案就会到4表中查询但之前的此订单时在0表的这样就导致了数据查不到。就是因为取模的基数产生了变化。 遇到这个情况我们小伙伴想到的方案就是做数据迁移把之前的4000万数据重新做一个hash方案放到新的规划分表中。也就是我们要做数据迁移。这个是很痛苦的事情。有些小公司可以接受晚上停机迁移但大公司是不允许停机做数据迁移的。 当然做数据迁移可以结合自己的公司的业务做一个工具进行不过也带来了很多工作量每次扩容都要做数据迁移 那有没有不需要做数据迁移的方案呢我们看下面的方案
2、range范围方案
range方案也就是以范围进行拆分数据。 range方案比较简单就是把一定范围内的订单存放到一个表中如上图id12放到0表中id1300万的放到1表中。设计这个方案时就是前期把表的范围设计好。通过id进行路由存放。 优点
我们小伙伴们想一下此方案是不是有利于将来的扩容不需要做数据迁移。即时再增加4张表之前的4张表的范围不需要改变id12的还是在0表id1300万的还是在1表新增的4张表他们的范围肯定是 大于 4000万之后的范围划分的。 缺点
有热点问题我们想一下因为id的值会一直递增变大那这段时间的订单是不是会一直在某一张表中如id1000万 id2000万之间这段时间产生的订单是不是都会集中到此张表中这个就导致1表过热压力过大而其他的表没有什么压力。
3、总结
hash取模方案没有热点问题但扩容迁移数据痛苦
range方案不需要迁移数据但有热点问题。
那有什么方案可以做到两者的优点结合呢即不需要迁移数据又能解决数据热点的问题呢
其实还有一个现实需求能否根据服务器的性能以及存储高低适当均匀调整存储呢 方案思路
hash是可以解决数据均匀的问题range可以解决数据迁移问题那我们可以不可以两者相结合呢利用这两者的特性呢
我们考虑一下数据的扩容代表着路由key如id的值变大了这个是一定的那我们先保证数据变大的时候首先用range方案让数据落地到一个范围里面。这样以后id再变大那以前的数据是不需要迁移的。
但又要考虑到数据均匀那是不是可以在一定的范围内数据均匀的呢因为我们每次的扩容肯定会事先设计好这次扩容的范围大小我们只要保证这次的范围内的数据均匀是不是就ok了。
方案设计
我们先定义一个group组概念这组里面包含了一些分库以及分表如下图 上图有几个关键点 1id04000万肯定落到group01组中 2group01组有3个DB那一个id如何路由到哪个DB 3根据hash取模定位DB那模数为多少模数要为所有此group组DB中的表数上图总表数为10。为什么要去表的总数而不是DB总数3呢 4如id12id%102那值为2落到哪个DB库呢这是设计是前期设定好的那怎么设定的呢 5一旦设计定位哪个DB后就需要确定落到DB中的哪张表呢 核心主流程 按照上面的流程我们就可以根据此规则定位一个id我们看看有没有避免热点问题。
关注公众号架构之路回复666可获取一份 2TB 架构师资料。
我们看一下id在【01000万】范围内的根据上面的流程设计1000万以内的id都均匀的分配到DB_0,DB_1,DB_2三个数据库中的Table_0表中为什么可以均匀因为我们用了hash的方案对10进行取模。 上面我们也提了疑问为什么对表的总数10取模而不是DB的总数3进行取模我们看一下为什么DB_0是4张表其他两个DB_1是3张表 在我们安排服务器时有些服务器的性能高存储高就可以安排多存放些数据有些性能低的就少放点数据。如果我们取模是按照DB总数3进行取模那就代表着【04000万】的数据是平均分配到3个DB中的那就不能够实现按照服务器能力适当分配了。
按照Table总数10就能够达到看如何达到 上图中我们对10进行取模如果值为【0123】就路由到DB_0【456】路由到DB_1【789】路由到DB_2。现在小伙伴们有没有理解这样的设计就可以把多一点的数据放到DB_0中其他2个DB数据量就可以少一点。DB_0承担了4/10的数据量DB_1承担了3/10的数据量DB_2也承担了3/10的数据量。整个Group01承担了【04000万】的数据量。 注意小伙伴千万不要被DB_1或DB_2中table的范围也是04000万疑惑了这个是范围区间也就是id在哪些范围内落地到哪个表而已。 上面一大段的介绍就解决了热点的问题以及可以按照服务器指标设计数据量的分配。 如何扩容
其实上面设计思路理解了扩容就已经出来了那就是扩容的时候再设计一个group02组定义好此group的数据范围就ok了。 因为是新增的一个group01组所以就没有什么数据迁移概念完全是新增的group组而且这个group组照样就防止了热点也就是【4000万5500万】的数据都均匀分配到三个DB的table_0表中【5500万7000万】数据均匀分配到table_1表中。
系统设计 思路确定了设计是比较简单的就3张表把groupDBtable之间建立好关联关系就行了。 group和DB的关系 table和db的关系
上面的表关联其实是比较简单的只要原理思路理顺了就ok了。小伙伴们在开发的时候不要每次都去查询三张关联表可以保存到缓存中本地jvm缓存这样不会影响性能。 一旦需要扩容小伙伴是不是要增加一下group02关联关系那应用服务需要重新启动吗
简单点的话就凌晨配置重启应用服务就行了。但如果是大型公司是不允许的因为凌晨也有订单的。那怎么办呢本地jvm缓存怎么更新呢
其实方案也很多可以使用用zookeeper也可以使用分布式配置这里是比较推荐使用分布式配置中心的可以将这些数据配置到分布式配置中心去。 完