h5手机网站实例,在建设厅网站上查询注销建造师,自己做的网站怎么给域名备案,许昌网络推广哪家好上篇文章中#xff0c;我给你留了一个思考题#xff1a;分库分表该如何设计#xff1f;
今天这篇文章#xff0c;我们来聊一下如何规划和设计分库分表#xff0c;以及要考虑哪些问题。 引言
当要解决海量数据的问题#xff0c;就必须要用到分布式的存储集群了#xff…上篇文章中我给你留了一个思考题分库分表该如何设计
今天这篇文章我们来聊一下如何规划和设计分库分表以及要考虑哪些问题。 引言
当要解决海量数据的问题就必须要用到分布式的存储集群了因为 MySQL 本质上是一个单机数据库所以很多场景下不是太适合存 TB 级别以上的数据。
但是绝大部分的电商大厂它的在线交易这部分的业务比如说订单、支付相关的系统还是舍弃不了 MySQL原因是只有 MySQL 这类关系型数据库才能提供金融级的事务保证。对于分布式事务那些新的分布式数据库提供的所谓的分布式事务多少都有点儿残血目前还达不到这些交易类系统对数据一致性的要求。
那既然 MySQL 支持不了这么大的数据量这么高的并发还必须要用它怎么解决这个问题呢还是按照我们之前的文章跟你说的思想分片也就是拆分数据。1TB 的数据一个库撑不住我把它拆成 100 个库每个库就只有 10GB 的数据了这不就可以了么这种拆分就是所谓的 MySQL 分库分表。
不过思路是这样没错分库分表实践起来是非常不容易的有很多问题需要去思考和解决。 如何规划分库分表
我们以订单表来举例子。首先需要思考的问题是分库还是分表分库呢就是把数据拆分到不同的 MySQL 库中去分表就是把数据拆分到同一个库的多张表里面。
在考虑到底是分库还是分表之前我们需要先明确一个原则 那就是能不拆就不拆能少拆不多拆。 原因也很简单你把数据拆分得越散开发和维护起来就越麻烦系统出问题的概率就越大。
基于这个原则我们想一下什么情况下适合分表什么情况下不得不分库
那我们分库分表的目的是为了解决两个问题
是数据量太大查询慢的问题。这里面我们讲的“查询”其实主要是事务中的查询和更新操作因为只读的查询可以通过缓存和主从分离来解决。解决查询慢只要减少每次查询的数据总量就可以了也就是说分表就可以解决问题。是为了应对高并发的问题。应对高并发的思想一个数据库实例撑不住就把并发请求分散到多个实例中去。所以解决高并发的问题是需要分库的。
简单地说数据量大就分表并发高就分库。
一般情况下我们的方案都需要同时做分库分表这时候分多少个库多少张表分别用预估的并发量和数据量来计算就可以了预估量建议为现有量的5-10倍。
另外我个人不建议你在方案中考虑二次扩容的问题也就是考虑未来的数据量把这次分库分表设计的容量都填满了之后数据如何再次分裂的问题。
现在技术和业务变化这么快等真正到了那个时候业务早就变了可能新的技术也出来了你之前设计的二次扩容方案大概率是用不上的所以没必要为了这个而增加方案的复杂程度。
这里强调一下越简单的设计可靠性越高。 如何选择 Sharding Key
分库分表还有一个重要的问题是选择一个合适的列或者说是属性作为分表的依据这个属性一般称为 Sharding Key。像我们上篇文章说到的归档历史订单的方法它的 Sharding Key 就是订单完成时间。每次查询的时候查询条件中必须带上这个时间我们的程序就知道三个月以前的数据查订单历史表三个月内的数据查订单表这就是一个简单的按照时间范围来分片的算法。
选择合适 Sharding Key 和分片算法非常重要直接影响了分库分表的效果。我们首先来说如何选择 Sharding Key 的问题。
选择这个 Sharding Key 最重要的参考因素是我们的业务是如何访问数据的。
比如我们把订单 ID 作为 Sharding Key 来拆分订单表那拆分之后如果我们按照订单 ID 来查订单就需要先根据订单 ID 和分片算法计算出我要查的这个订单它在哪个分片上也就是哪个库哪张表中然后再去那个分片执行查询就可以了。
但是当我打开“我的订单”这个页面的时候它的查询条件是用户 ID这里没有订单 ID那就没法知道我们要查的订单在哪个分片上就没法查了。当然你要强行查的话那就只能把所有分片都查一遍再合并查询结果这个就很麻烦而且性能很差还不能分页。
那要是把用户 ID 作为 Sharding Key 呢也会面临同样的问题使用订单 ID 作为查询条件来查订单的时候就没办法找到订单在哪个分片了。这个问题的解决办法是在生成订单 ID 的时候把用户 ID 的后几位作为订单 ID 的一部分比如说可以规定18 位订单号中第 10-14 位是用户 ID 的后四位这样按订单 ID 查询的时候就可以根据订单 ID 中的用户 ID 找到分片。
那我们系统对订单的查询方式肯定不只是按订单 ID 或者按用户 ID 这两种啊。比如说商家希望看到的是自己店铺的订单还有各种和订单相关的报表。对于这些查询需求我们一旦对订单做了分库分表就没法解决了。那怎么办呢
一般的做法是把订单数据同步到其他的存储系统中去在其他的存储系统里面解决问题。比如说我们可以再构建一个以店铺 ID 作为 Sharding Key 的只读订单库专门供商家来使用。或者把订单数据同步到 HDFS 中然后用一些大数据技术来生成订单相关的报表。
所以你看一旦做了分库分表就会极大地限制数据库的查询能力之前很简单的查询分库分表之后可能就没法实现了。
你要记得一句话分库分表一定是数据量和并发大到所有招数都不好使了比如缓存我们才拿出来的最后一招。 如何选择分片算法
举个例子我们能不能用订单完成时间作为 Sharding Key 呢比如说我分 12 个分片每个月一个分片这样对查询的兼容要好很多毕竟查询条件中带上时间范围让查询只落到某一个分片上还是比较容易的我在查询界面上强制用户必须指定时间范围就行了。
这种做法有个很大的问题比如现在是 3 月份那基本上所有的查询都集中在 3 月份这个分片上其他 11 个分片都闲着这样不仅浪费资源很可能你 3 月那个分片根本抗不住几乎全部的并发请求。这个问题就是“热点问题”。
也就是说我们希望并发请求和数据能均匀地分布到每一个分片上尽量避免出现热点。这是选择分片算法时需要考虑的一个重要的因素。一般常用的分片算法就那么几种刚刚讲到的按照时间范围分片的方法是其中的一种。
基于范围来分片容易产生热点问题不适合作为订单的分片方法但是这种分片方法的优点也很突出那就是对查询非常友好基本上只要加上一个时间范围的查询条件原来该怎么查分片之后还可以怎么查。范围分片特别适合那种数据量非常大但并发访问量不大的 ToB 系统。比如说电信运营商的监控系统它可能要采集所有人手机的信号质量然后做一些分析这个数据量非常大但是这个系统的使用者是运营商的工作人员并发量很少。这种情况下就很适合范围分片。
一般来说订单表都采用更均匀的哈希分片算法。比如说我们要分 24 个分片选定了 Sharding Key 是用户 ID那我们决定某个用户的订单应该落到那个分片上的算法是拿用户 ID 除以 24得到的余数就是分片号。这是最简单的取模算法一般就可以满足大部分要求了。当然也有一些更复杂的哈希算法像一致性哈希之类的特殊情况下也可以使用。
需要注意的一点是哈希分片算法能够分得足够均匀的前提条件是用户 ID 后几位数字必须是均匀分布的。比如说你在生成用户 ID 的时候自定义了一个用户 ID 的规则最后一位 0 是男性1 是女性这样的用户 ID 哈希出来可能就没那么均匀可能会出现热点。
还有一种分片的方法查表法。查表法其实就是没有分片算法决定某个 Sharding Key 落在哪个分片上全靠人为来分配分配的结果记录在一张表里面。每次执行查询的时候先去表里查一下要找的数据在哪个分片中。
查表法的好处就是灵活怎么分都可以你用上面两种分片算法都没法分均匀的情况下就可以用查表法人为地来把数据分均匀了。查表法还有一个特好的地方是它的分片是可以随时改变的。比如我发现某个分片已经是热点了那我可以把这个分片再拆成几个分片或者把这个分片的数据移到其他分片中去然后修改一下分片映射表就可以在线完成数据拆分了。 但你需要注意的是分片映射表本身的数据不能太多否则这个表反而成为热点和性能瓶颈了。查表法相对其他两种分片算法来说缺点是需要二次查询实现起来更复杂性能上也稍微慢一些。但是分片映射表可以通过缓存来加速查询实际性能并不会慢很多。 总结
对 MySQL 这样的单机数据库来说分库分表是应对海量数据和高并发的最后一招分库分表之后将会对数据查询有非常大的限制。
分多少个库需要用并发量来预估分多少表需要用数据量来预估。选择 Sharding Key 的时候一定要能兼容业务最常用的查询条件让查询尽量落在一个分片中分片之后无法兼容的查询可以把数据同步到其他存储中去来解决这个问题。
我们常用三种分片算法范围分片容易产生热点问题但对查询更友好适合并发量不大的场景哈希分片比较容易把数据和查询均匀地分布到所有分片中查表法更灵活但性能稍差。
对于订单表进行分库分表一般按照用户 ID 作为 Sharding Key采用哈希分片算法来均匀分布用户订单数据。为了能支持按订单号查询的需求需要把用户 ID 的后几位放到订单号中去。
最后还需要强调一下我们所提到的这些分片相关的知识不仅仅适用于 MySQL 的分库分表你在使用其他分布式数据库的时候一样会遇到如何分片、如何选择 Sharding Key 和分片算法的问题它们的原理都是一样的所以我们说的这些方法也都是通用的。 感谢阅读如果你觉得这篇文章对你有一些启发也欢迎把它分享给你的朋友。
思考题 怎么能避免写出慢SQL 期待、欢迎你留言或在线联系与我一起讨论交流“一起学习一起成长”。 上一篇文章
电商系统架构设计系列八订单数据越来越多数据库越来越慢该怎么办 推荐阅读
【架构】高可用高并发系统设计原则【总结】互联网技术架构中常用的分库分表方案汇总技术破局业绩狂飙十倍亿级电商平台重构大揭秘当我们聊高并发时到底是在聊什么如何真正地掌握高并发设计能力微服务架构实战 - 我的经验分享总结2019系统架构师架构演进过程-从信息流架构到电商中台架构
系列分享
Elasticsearch教程微服务架构实战架构思维成长系列电商系统架构设计系列 ------------------------------------------------------
------------------------------------------------------
我的CSDN主页
关于我个人域名更多我的信息
我的开源项目集Github 期望和大家 一起学习一起成长共勉O(∩_∩)O谢谢
如果你有任何建议或想学习的知识可与我一起讨论交流
欢迎交流问题可加个人QQ 469580884
或者加我的群号 751925591一起探讨交流问题
不讲虚的只做实干家
Talk is cheapshow me the code