Loading... **Hi,我是空夜,又是一周没见了!** 今天分享一下最近学习的分库分表技术,主要涉及两方面: - 分库分表的原因和基本概念,包括分库分表技术、策略、动态分库分表方案等; - 以 Sharding Sphere + Spring Boot 为例,展示分库分表技术的实际使用; 本节文章主要学习自 Advanced Java,会在表现手法上略有不同。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138204446.png) --- ## 为什么会有分库分表的需求呢? 这次不是产品的锅了,我们先来看看单库单表的问题: 单库:支持的并发有限,数据库服务器磁盘容量不足 单表:单表数据量太大,SQL 执行越来越慢 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138242717.jpeg) 针对单库单表的缺陷,可以将某些经常被检索的数据放到类似 ElasticSearch 的搜索引擎中。但这并不能解决全部问题。 如果业务并发量很高,达到 1000 qps,单库应该是扛不住了。这时候肯定要分库分表的。 果然,单恋一只花是不能解决单身问题的!要想脱单,还是得广... ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138270077.jpg) --- ## 分库分表后可以达到什么效果? 分库后:可承受的并发量增加,服务器得以扩充,磁盘容量不再紧张 分表后:单表数据量变少,SQL 执行速度提升 注意,分库和分表是两件事。你可以只分库,在不同的库中有一些相同结构的同名表,也可以只分表,一张表在一个库中有多个不同名的分表; 总而言之,按你的需求来。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138297471.jpeg) --- ## 数据拆分的方向 **垂直拆分**:将一个表的不同字段拆分到不同表中,尤其是将频率较高的单独拆出来。这样,对于访问频率较高的数据,数据库可以缓存更多的行。(这样分表感觉就是根据业务来拆了,在业务层做控制,比如用户订单表、订单支付信息表、订单商品表等) **水平拆分**:同一个表的数据拆分到多个库的多个表中,这些表的结构都相同。利用多个库的容量来扩容和提高并发请求的承受能力。 如果真的采用了分库分表的话,我个人感觉还是更专注水平拆分;而垂直拆分,一般在定需求的时候就已经分好了。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138345060.jpeg) --- ## 分库分表技术方案 目前有以下两种主流的技术方案: - **Sharding Sphere**: 当当开源的分布式数据库中间件解决方案。由 Sharding JDBC、Sharding Proxy、Sharding Sidecar 三款相互独立的产品组成。 Sharding 是在业务层进行分库分表;对于每个项目来说,各自引入 shardsphere 的依赖,添加分库分表的配置(其实就是对分库分表下的数据库的访问、路由配置) - **Mycat**: 在 proxy 层进行分库分表,需要自己运维一套中间件 所以,中小型公司一般用 Sharding Sphere 就够了。有足够能力的公司可以用 mycat 自己搭一个中间件。 说到这,你们应该还是有点迷。光是讲理论,没有实操也不行啊!不要担心,这篇文章后面,老衲也会给你们介绍一下 Sharding Sphere 的使用应用示例。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138395252.gif) --- ## 分库分表后如何平稳过渡上线 分库分表方案设计好了,程序也改好了,如何将新版本项目上线呢? - 停机,部署:这是最简单的方法,但我想聪明的你应该已经发现了华生,啊不,盲点。凌晨1点停机发布,让整个组陪你一块熬夜到天明,还是你打算让用户等着你更新,你也真敢想啊! ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138434721.jpeg) 就不能想想别的法子嘛! ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138776633.jpeg) - **双写迁移**:不停机,先上一套双写的版本,然后上一套最新的分库分表版本,最后,后台将老库的一些遗漏的数据刷到新库里。 这里的双写是什么意思呢?就是说,我上线一个新版本的代码,这个版本中对数据库的操作,是对原有的旧库旧表,以及废了老大劲设计好的分库分表,同时进行修改。总而言之,要保持新库新表的数据一定要是最新的! 等等,好像还有点问题。 如果我第一次分库分表上线了,解决了业务扩张的问题,用户越来越多,公司估值水涨船高,老板数钱数到手抽筋,放话要给项目组发奖金。 正当你得意的时候,运维告诉你一个惊天噩耗:由于公司业务发展迅速,每日新增用户几十万,数据库又扛不住了! 这下完犊子了!再重新设计分库分表方案,恐怕是很难了。你要同时关注几个数据库,几十个分表(甚至更多),要保证数据的一致性等等... 要秃了。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138463080.jpeg) 别急,这不都是老衲吓唬你的嘛?马上给你解决方案:在一开始,就设计一个支持动态扩容缩容的分库分表方案。 --- ## 如何设计一个动态扩容缩容的分库分表方案 - 一次性定好有多少个库,多少个表,比如 32 个库,每个库分 32 个表,那么一个表被分成了 1024 张分表;这样,可以提前做好分库分表的策略,扩容缩容时,程序就不用修改了。 - 简单来说,开始可能是一台数据库服务器,上面放这 32 个库;扩容时,如扩容成 4 个数据库服务器,每个数据库服务器上放 32/4 = 8 个库,每个库里还是 32 个表; - 极限情况:扩容到 32 个服务器,每个服务器一个库,每个库 32 个表;更极限,扩容至 1024 个服务器,每个服务器只有一个库一张表 - 缩容同理。 - 这种情况下,扩容缩容可以由 DBA(数据库管理员) 用一些工具快捷完成,不需要修改程序。 最后,还有一个小问题,咳咳,真的是最后一个了:分库分表情况下,如何保证同类型表中数据的 ID 不会重复呢?这就涉及到分布式 Id 生成策略了。 --- ## 分库分表方案下的 id 主键生成策略 **利用数据库自增 id**:由一个无用的表来生成自增的 id,然后插入到真正的分表中。缺点是:能承受的并发量低。 这个方法前两天我们组内技术分享会上有个小伙伴就提到了,在分布式系统中,利用 MySQL 的 Id 自增机制,来解决分布式系统中的 id 重复问题。想不到啊想不到。 这个方法不是最优解,但程序开发没有银弹,能解决我们需求痛点的就是好办法! **雪花算法 SnowFlake**:64 位,分布式 id 生成算法。下一节的示例代码也用的雪花算法。 基于雪花算法,还有一些扩展优化的 ID 生成策略。具体你可以自行百度,再写下去我晚上没得空吃了。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138499227.jpeg) 好了,理论部分学习完毕。下一节我们进入正题:在 Spring Boot 中如何使用 Sharding Shpere 来进行分库分表。 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138527619.jpg) 这篇文章换了下风格,自己也感觉舒服了 ![](http://zfh-public-blog.oss-cn-beijing.aliyuncs.com/image-1604138546802.jpeg) --- 更多请关注公众号:**猿生物语**(ID:**JavaApes**) Last modification:October 31, 2020 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 请作者喝杯肥宅快乐水吧!
3 comments
向贵站申请交换友情链接!站长同意的话请回复一下…
名称:建站知道网
本站网址: http://wozhidaole.com.cn/
本站描述: | 新老站长都喜欢的技术性优秀网站!
其他站长想与我站交换友情链接的,在此评论下回复或者在http://wozhidaole.com.cn/申请!
OωO夜佬文章风格越来越骚了
ヾ(´・ ・`。)ノ"