1、知识框架图
2、MySQL可扩展的理解
2.1 可扩展的定义?与高可用的区别?
2.2 扩展与投入的关系?
2.3 扩展和拆分的概念区别?
3、垂直拆分
4、水平拆分
关注下面几个核心问题:
4.1 什么是水平拆分?
4.2 拆分原则有哪些?
4.3 如何进行水平拆分,有哪些切片方式,优劣比较?
4.4 如何选择分区键?
4.5 如何生成全局唯一ID?
5、实践
6、参考资料
一、知识框架图
二、可扩展的理解
可扩展性,是指随着系统负载的扩充,系统的可持续扩充能力,是一种软件系统处理能力相关的设计指标。系统扩充中,在尽量不影响现有系统的前提下,能够通过较少的变更或新增硬件资源,就能获取系统处理能力的提升,保持高性能。理解了这层定义,就不难理解可扩展和高可用的区别。“可扩展”代表了系统的伸缩能力,当系统负载迅速变高时,能以较小代价的调整来扩充系统的处理能力,持续提供有效支撑。而”高可用“则关注了有效服务处理能力的持续可用性,比如系统单点故障、某些节点的性能瓶颈导致服务无法响应或处理能力严重降低、宕机等都属于高可用相关。关于”扩展“和“拆分”的概念理解。当数据量大到一定程度后,读写效率会降低,如果想保持mysql服务器高效运转的话,就需要想办法进行扩展,比如各种分库分表方案。在《高性能Mysql》一书中,作者划分了”垂直扩展“,”水平扩展“,”向内扩展“,”多实例“,”集群“等多种方式。在《Mysql运维内参》中则主要关注了“水平拆分”和“垂直拆分”。起先并没意识到“扩展”和“拆分”的区别,其实两者切入点还是不同的,个人理解如下:“扩展”侧重于mysql服务器方面,“拆分”则更多是数据库(设计)层面。垂直扩展是想办法提升单机硬件性能,提升单实例的狐狸能力;而水平扩展的思路则是将数据库分布到多台机器上,分化负载。整体的关系可以参考第一部分的知识结构图,本篇文章主要是谈谈对“拆分”的理解和总结。
三、垂直拆分
垂直拆分,所谓的”垂直"可以理解为被分隔后的数据库相互独立且各不相同,一般在考虑拆分时应优先考虑垂直拆分。
比如一个论坛将用户数据和内容数据统一存储到单个数据库,随着业务量的增长,单个库已不能满足读写TPS量。这时研发人员对业务架构进行重构升级,拆分出3个业务库帖子、评论、用户,部署到同一个实例,暂时满足需求;
业务量进一步增长,单个数据库实例已经接近性能瓶颈,无法满足快速增长的存储需求和高并发需求,研发人员将3个业务库分别拆分到单独的mysql实例上;
业务量进一步增长,又面临DB瓶颈,研发人员这次将三个库的多张表分别拆分到多个实例上,比如将用户数据的多张表遍布于多个实例中,缓存了服务器压力。
业务量进一步增长,用户数达到数亿级,不同运营部门对数据的处理和使用需求日益增多和多样化,热帖的并发访问量巨大,这时垂直拆分已经无法满足,需要考虑使用水平拆分了。
上面只是个简单的例子。另外,在业务发展中因为原先数据库设计不合理或单表容量过大等原因而对表结构进行改造,将单表拆分为多张不同结构的表也属于垂直拆分,如下图,“垂直拆分”的优点是各部分数据仍然是相对完整的对象,并没有显著降低业务的理解复杂度和处理复杂度。但如果数据量持续膨胀,垂直拆分并非终极解决方案,当单表容量超过数百G时,很难满足公司的多查询维度和高并发场景。个人觉得这部分关键是理解什么是垂直拆分,何时可进行拆分,如何从某切入点(业务,实例,库,表等)进行拆分,垂直拆分的扩展局限性等。
四、水平拆分
什么是水平拆分?
拆分原则有哪些?
如何进行水平拆分,有哪些切片方式,优劣比较?
如何选择分区键?
如何生成全局唯一ID?
(1)什么是水平拆分?
水平拆分是对某个库或表按照指定算法或规则拆分为多个相同结构的库或表,以减少单库/表体积,将读写请求分配到各分库或分表上从而成倍的提高整体处理能力。下面是一个案例,
最初是一张订单表,承载用户中心、支付中心、商户中心等多个部门的写请求和多维度查询请求。单表容量迅速达到了上千万条记录,研发同学先将订单表按用户id拆分为10个表,降低每张表的容量。为了满足商户中心查询需求同时减少对订单应用的影响,又通过复制和处理组件得到一份按商户id分表的备份,如下。 ==>>>
单库吞吐能力成为瓶颈,研发同学按照特定分库分表算法将订单库拆分为多库多表,这是能满足今后几年业务发展了。==》
原则1:能不拆就不拆。
一般建议能不拆就不拆,而是优先考虑使用常用方法,如提升服务器性能,使用读写分离,优化数据库设计,使用和优化索引。现实中,存储模型与业务模型有一定关系,一定程度上反映了业务逻辑,任何拆分行为都或多或少的提升业务处理复杂度。分库分表可能会造成查询、合并和更新条件的分离,以及事务的分离(分库时可能要使用分布式事务保证数据强一致),使得业务处理时必须考虑这些因素,成倍提高了复杂度。
下面是需要拆分的场景,
原则2:数据量太大,日常的运维影响了正常的业务访问
数据量太大,单库或单表数据很大(比如超过5千万条记录),此时日常备份、迁移数据、更新等运维需求会影响服务器处理能力,造成业务响应变慢,部分业务处理失败。此时,需考虑拆分。
> 备份、迁移数据:资源瓶颈是磁盘IO和网络IO;
> 更新:DDL时会长时间锁表,影响业务访问;热点数据频繁更新,会造成锁等待,表压力大,经常出问题。
原则3:某些数据出现了无穷增长
这个场景的典型案例是微博和社交评论系统的数据存储。比如大V的每条微博都会扩散给上千万粉丝,可能一些索引或路由有存储需求,此时最佳解决方案是水平切分,使用按用户、日期、用途、类别等各种方式。(延伸下... 实际中,这个场景在设计层面有个“推拉模式”来做优化,参考“微博fed系统推拉模式和时间分区模式架构谈谈”http://www.cnblogs.com/sunli/archive/2010/08/24/twitter_feeds_push_pull.html 和 新浪微博架构和FEED架构分析 http://blog.sina.com.cn/s/blog_53b95aec0100ujim.html )
原则4:业务耦合性考虑,拆分不同业务或对单业务重构模型
从业务高度,需要对业务架构和技术架构进行重构升级,比如将一个论坛数据库拆分为用户、文章、评论三个库,或者将用户中心、商户中心的数据库拆分到不同的实例中以避免相互干扰。
原则5:表设计不合理,需要对某些表字段做拆分
见“垂直拆分”部分的例子。
原则6:安全性和可用性的考虑
分库分表客观上提升了安全性和高可用,单个实例的问题不至于影响整体业务。
(3)如何进行水平拆分,有哪些切片方式,优劣比较?
《高性能mysql》中作者将切分方式划分为几大类:固定分配、动态分配、混合分配、显示分配。分类方式有很多,这里暂时遵循着书中的这个框架来。3.1 固定分配
指借助于固定规则的分区函数,只使用分区键就能计算出分库分表的结果,常用的hash和取模、移位、按顺序运算都属于这类,见上图x。
优点是简单、高效、未引入外部依赖等;
缺点是
a. 分片较少时,难以平衡负载;
b. 无法自定义将数据放到哪个分片,可能出现热点数据分布不合理的情况。比如按商户id进行hash运算时,几个大商户的数据被放置到同一张表,造成该表压力很大。
c. 修改分配策略比较麻烦。比如原先的分表规则是%32, 后来数据据量增大需增加分表数量,遂将策略调整为%64,需要提前做数据迁移工作。
3.2 动态分配
将分区键和分库分表的映射关系提前配置和存储,该存储节点所存的内容相当于分配函数。
优点是能够细粒度的控制“分配规则”,比如将热点数据均匀分布在多个库或表中,将不同用途的数据做隔离等;
缺点是引入外部依赖,可用性和效率方面不如固定分配等。
3.3 混合分配
综合使用固定规则和动态配置两种策略,取两者优点,适用于一些特殊场景。比如根据url字段做分片,可以先对url做hash运算得出一个数值,然后根据动态分配方式映射到具体分表。
3.4 显式分配
将数据分片编码到ID中,感觉和静态分配本质上是一样的。见https://tech.meituan.com/dianping_order_db_sharding.html的分表键格式方案。
(4)如何选择分区键 ?
首先要明白分区键的功能和影响,然后思考下随便选个分区键会产生什么问题?实际中应该根据业务需求来选择适用的分区键,避免跨分片查询,方便存取且尽量不降低存取性能。
查询维度是多样的,有时可能需要多个分区键,比如在做一个评论应用中,有需要根据用户ID来查询用户所有的评论,也需要根据文章ID查询所有的评论,我们按用户ID或文章ID分片都不是好方法,因为总有一种要跨分片查询,我们的做法是存两份,分别以用户ID和文章ID进行分表,以满足上述两种查询场景。
有些数据遍布在个分片,又需要频繁跨片查询,可以分析是否有其他等同策略。还是上面提到的评论应用,能够将一些信息抽象为整体数据,比如数量统计,可以抽取出单张公共表。
这部分的重点是“选择分区键的方法”、“多分区键”、“跨分片查询问题”、“跨分片数据一致性”。
(5)全局唯一ID的生成
全局唯一ID推荐几个优秀的资源,
1. 美团的分布式ID生成系统 https://tech.meituan.com/MT_Leaf.html
2. 阅文集团分布式ID (类snowflake方法) https://mp.weixin.qq.com/s?__biz=MzIxMzgxMjQ1Mw==&mid=2247483661&idx=1&sn=4e459c618a2169f994f62f28f2159eba&chksm=97b05487a0c7dd91e45cd2c9d0dcc837586ee2652abc9efb3252e69b1bd2d6b2bb450c8c2e58&mpshare=1&scene=2&srcid=0525IV9AydzO0CEN4CXkEFuk&key=cf192bba2f919fcb70ed66331b7f4f5d4c61927abd688c4674e6088b2743fb2e495a694189f8dab322e8030e8a9143b9932ed7851e58024d51807a665ab48b9c0bd8f176efa0b7383fe7e857d55eddb6&ascene=0&uin=MjM3ODQzNjgwMA%3D%3D&devicetype=iMac+Macmini7%2C1+OSX+OSX+10.11.5+build(15F34)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=iZnDMUQlGa2cTsRI6ffMQ%2B585Qs0ZJK0s9FedcMFAmailXPsFNG2IPQ3oF3mBt5o
3. 贝聊亿级数据库分库分表实践 https://zhuanlan.zhihu.com/p/27363448
4. 唯品会订单分库分表实践 http://www.infoq.com/cn/articles/summary-and-key-steps-of-vip-orders-depots-table
5. 大众点评订单分库分表实践 https://tech.meituan.com/dianping_order_db_sharding.html
五、实践
+-------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+-------------------+-----------------------------+
| biz_tag | varchar(128) | NO | PRI | | |
| max_id | bigint(20) | NO | | 1 | |
| step | int(11) | NO | | NULL | |
| desc | varchar(256) | YES | | NULL | |
| update_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+--------------+------+-----+-------------------+-----------------------------+
代码摘要:IdTypeEnum即接入业务的枚举,
六、参考资料
1、《高性能mysql》第三版
2、《mysql运维内参》
相关推荐
【高性能MySQL 第三版读书笔记 一至六】主要涵盖了MySQL服务器优化、操作系统和硬件优化、复制技术、可扩展性方案、MySQL分支与变种以及高可用性策略等多个方面。以下是对这些知识点的详细说明: 1. **优化服务器...
MySQL读书笔记是对数据库管理系统MySQL深入理解的重要资源,它包含了关于SQL语言、数据库设计、性能优化、安全性以及备份恢复等多个方面的内容。以下是对这些知识点的详细阐述: 1. SQL语言基础: - 数据定义语言...
在“mysql markdown笔记”中,我们可以探讨以下几个重要的MySQL知识点: 1. **SQL基础**:SQL(Structured Query Language)是用于与关系数据库交互的语言。它包括了数据查询、数据更新、数据插入和数据删除等操作...
通过阅读"MySQL学习笔记",你可以系统地学习MySQL的各种概念和技术,无论你是初学者还是有经验的开发者,都能从中受益匪浅。这份笔记将帮助你更好地管理和利用MySQL数据库,提升你的数据库技能。
此外,为了保证系统的可扩展性和稳定性,可能还涉及到分布式系统设计、负载均衡、缓存策略、日志管理等多个方面的技术。 总的来说,这个基于Springboot的学生读书笔记共享系统源码数据库项目,不仅展示了Spring ...
### 基于Springboot的学生读书笔记共享系统关键知识点解析 #### 一、项目背景与目标 本系统旨在为学生提供一个便捷、高效的读书笔记共享平台。随着互联网技术的发展,尤其是移动互联网的普及,学生群体对于知识...
综上所述,萌音云笔记是一个结合了Node.js、Express.js、可能的数据库技术和前端框架的综合项目,旨在提供高效的技术文档在线创作、阅读、分享和托管服务。其背后的技术栈展示了现代Web开发的典型架构和最佳实践。
在这个平台上,学生们可以上传自己的读书笔记,浏览他人的笔记,进行互动讨论,从而提升学习效果和阅读体验。下面将详细阐述该项目涉及的技术栈、功能实现以及开发过程中的关键点。 1. **SpringBoot框架**:...
9. **RESTful API设计**: 遵循REST原则,使API具有无状态、统一接口等特点,提高系统的可扩展性和可维护性。 10. **权限管理**: 可能包括用户注册、登录验证、角色权限分配等功能,确保系统安全,防止未授权访问。 ...
- MySQL版本5.1之后的版本进一步增强了性能和可扩展性,改进了复制功能,并引入了对Windows平台更好的支持。 - MySQL版本5.5对InnoDB引擎进行了进一步优化,例如提供了更好的性能和更好的并发控制。 - MySQL版本5.6...
3. **系统设计**:设计阶段包括架构设计、数据库设计、界面设计等,应考虑系统的可扩展性、稳定性、安全性和易用性。 4. **技术选型**:OA系统常采用B/S架构,涉及的技术可能有Java、.NET、Python等后端开发语言,...
通过该系统源代码,学习如何使用这些技术构建可扩展的管理系统。涵盖前端开发、后端开发、数据库集成等核心内容。通过阅读和实践该系统源代码,将掌握Web应用程序开发技能,了解前后端交互方式。 适用人群: 该项目...
QT是Qt Company开发的一款跨平台的C++图形用户界面应用程序开发框架,而MySQL则是一种流行的开源关系型数据库管理系统,两者结合可以构建稳定且可扩展的游戏后端。 在进行这个项目时,首先需要对QT框架有深入理解。...
- **Oracle**:作为业界最广泛使用的大型数据库之一,Oracle以其强大的事务处理能力和高度可扩展性著称。 - **Sybase**:虽然市场占有率不如Oracle,但在某些特定领域仍然有广泛应用。 - **SQL Server**:Microsoft...
本系统基于Spring Boot、Vue.js、Element UI和MySQL,旨在为开发者提供一个可扩展的管理系统框架。通过前后端交互方式,实现了用户管理、权限管理等核心功能。 系统开发环境: 前端:Vue.js、Element UI 后端:...
笔记会讲述如何连接MySQL数据库,执行SQL语句,以及使用PDO或mysqli扩展进行数据库操作。 6. PHP面向对象编程:PHP5引入了完整的面向对象特性,包括类、对象、继承、封装、多态。笔记会详细解析这些概念,帮助读者...
本项目是基于Python Flask实现的一个书单笔记分享系统,旨在提供一个平台,让用户可以记录、分享自己的读书笔记,与其他读者交流心得,共同提升阅读体验。 Flask是Python的一个微型Web服务框架,由Armin Ronacher...
我们会探讨如何根据项目需求选择合适的架构模式,以及如何设计可扩展、可维护的系统。 4. **23种设计模式**:这些模式是软件工程中经过实践验证的最佳实践,如工厂模式、单例模式、建造者模式、观察者模式、装饰器...
例如,了解如何声明和使用变量,如何创建和实例化对象,以及如何利用继承和多态来设计可扩展的代码结构。 其次,数据库知识在Java应用中至关重要,尤其是对于需要持久化数据的项目。这部分可能讲解了SQL语言,包括...