MySQL - 扩展性 1 概述:人多未必力量大
我们应该接触过或者听说过数据库的性能瓶颈问题。对于一个单机应用而言,提升数据库性能的最快路径就是氪金 - 买更高性能的数据库服务器,只要钱到位,性能不是问题。
但是当系统性能增加到一定地步时,你会发现,原先花 3000 块提升了 50% 的性能,现在花 30000 块,才提升了不到 10%。
也就是说,我们花了钱,但没有得到等价的性能提升,这个时候,我们就要考虑数据库的可扩展性了。
要讨论 MySQL 的可扩展性,就要先明确可扩展性的定义。在此之前,我们先抛开 MySQL,专注于扩展性,搞清楚什么是扩展性,才能更有针对性的去提高 MySQL 的扩展性。
1 什么是可扩展性
我们常常把“可扩展性”、“高可用性”以及“性能”用作同义词,但事实上它们是完全不同的。简单来说,性能是响应时间,可用性是宕机时间,而扩展性表明了当需要增加资源以执行更多工作时,系统能够获得等价的性能提升的能力。换种说法,可扩展性就是我们能够尽可能的花费相同的资源提升等价的性能。而缺乏扩展能力的系统在达到收益递减的转折点后,将无法进一步增长。
容量是一个和可扩展性相关的概念。系统容量表示在一定时间内能够完成的工作量。
容量和可扩展性并不依赖于性能。以高速公路上的汽车来类比的话:
- 性能是汽车的时速。
- 容量是车道乘以最大安全时速。
- 可扩展性就是在不减慢交通的情况下,能增加更多车和车道的程度。
在上面这个类比中,可扩展性依赖多个条件:换道设计是否合理、路上有多少车抛锚或发生事故、汽车行驶速度不同以及是否频繁变换车道。但一般来说,和汽车的引擎是否强大无关。
这并不是说性能不重要,性能确实重要,只是要注意的是,即使系统性能不是很高的系统也可以具备可扩展性。
从较高层次看,可扩展性就是能够通过增加资源来提升容量的能力。
对于容量,我们可以简单的认为是处理负载的能力,而从不同的角度考虑负载对我们优化扩展性很有帮助。
数据量
应用所能累计的数据量是可扩展性最普遍的挑战,特别是对于现在的互联网应用而言,因为从不删除数据。
用户量
首先,即使每个用户只有少量的数据,但在累计到一定数量的用户后,数据量也会开始不成比例的增长,且速度快过用户数增长。其次,更多的用户意味着要处理更多的事务,并且事务数可能和用户数不成比例。最后,大量用户也意味着更多复杂的查询。
用户活跃度
不是所有的用户活跃度都相同,并且用户活跃度也不总是不变的。如果用户突然变得活跃,例如 github 给小团队免费开放了私有化仓库,那么其对应的负载可能会明显提升。要注意的是,用户活跃度不仅仅指页面浏览数(PV),即使同样的 PV,如果网站的某个需要执行大量查询工作的功能变得更受欢迎,也可能导致更多的工作。
相关数据集的大小
如果用户间存在关系,应用可能需要在整个相关联用户群体上执行查询和计算,这比处理一个个的用户和用户数据要复杂的多。
说了这么多,只是为了让我们更好的理解可扩展性的让我们用下面图表来更明确的表达可扩展性。
假设有一个只有一台服务器的系统,并且能够测量它的最大容量,如图 1 所示:
假设我们现在增加一台服务器,系统的能力加倍,如图 2 所示:
图 2 就是线性扩展。我们增加了一倍的服务器,增加了一倍的容量。然而,理想是美好的,现实是骨感的。大部分系统并不是线性扩展的,而是如图 3 所示的扩展方式:
大部分系统都只能以比线性扩展略低的扩展系数进行扩展。这就导致,多数系统最终会达到一个最大吞吐量临界点,超过这个点后增加投入可能反而会降低系统的吞吐量。
到这一步,大家对扩展性应该已经有一个较为清晰的概念了。在此基础上,让我们再深入一步:Amdahl 扩展 和 USL 扩展。
简而言之,USL 说的是线下扩展的偏差可通过两个因素来建立模型:
- 无法并发执行的一部分工作;
- 需要交互的另外一部分工作。
在对第一个因素继续建模后,就有了著名的(听过这个著名吗?)阿姆达尔定律(Amdahl)。第一个因素最终会导致吞吐量趋于平缓。如果部分任务无法并行,那么不管你如果分而治之,该任务至少需要串行部分的时间。这句话很重要,让我们用一个栗子再简单阐述下:
假设大家都做过韭菜煎蛋这道菜,我们做这道菜时,有几个必要步骤:
- 切韭菜,耗时 t1;
- 打蛋液,耗时 t2;
- 开煎,耗时 t3;
就上面 3 个步骤而言,你可以在切韭菜的时候,让你女票帮你打蛋液,也就是说 1、2 是可以并行的,但是我们能边切菜边煎吗?或者边打蛋液边煎吗?显示是不行的。因此,步骤 3 和 1、2 是串行的。
这时候,我们就会发现,做韭菜煎蛋这个任务需要的时间 t 为:
t = MAX(t1, t2) + t3;
对第二个因素,需要交互的工作而言,交互就意味着内部节点间或者进程间的通信。这种通信的代价取决于通信信道的数量,而信道的数量将按照系统内工作者数量的二次方增长,所以最终开销比带来的收益增长的更快,这就是产生扩展性倒退的原因。由此和 Amdahl 定律,就得出了 USL。
图 4 阐明了目前讨论的三个概念:线性扩展、Amdahl 扩展以及 USL 扩展。而大多数真实系统看起来更像 USL 曲线。
至此,关于扩展性的概念描述告一段落。接下来,我们回到正题,看看 MySQL 的扩展性如何规划。
2 规划可扩展性
什么情况下需要扩展?,这是个值得我们牢记的问题。当我们提到系统的可扩展性时,一般只有两种情况:
- 刚开始规划一个应用;
- 当前应用无法满足增加的负载;
上述两种情况,大多数情况下我们碰到的应该都是后者。具体表现为:
- CPU 密集型变成 I/O 密集型;
- 并发查询竞争;
- 不断增大的延迟;
如果是可扩展的应用,可以简单地增加更多的服务器来分担负载。但如果是可扩展性比较差的,你就会发现 - 只剩下提高可扩展性这一条路可走。
只有一条路,那就且行且 996 吧!
走上了提升扩展性这条路,接下来的问题就是,如何提高可扩展性?这里比较困难的部分是估算应用承担的负载到底有多少?这个值不一定非常精确,但必须在一定的数量级范围内。什么?你问为什么要在一定范围内?不清楚敌人的火力,咱们是准备用高射炮打蚊子还是用大刀对机枪呢?
除此之外,为了能帮助我们更好的规划可扩展性,咱们最好还能想清楚下面这个问题:
- 应用的核心功能完成了多少?很多可扩展性方案可能会导致某些功能实现起来更加复杂。在核心功能没完成前,问问自己,真的要走提升扩展性这条路吗?换个说法,准备好迎接 996 了吗?
3 为扩展赢得时间
程序员们理想的开发环境应该是:计划先行、有足够能够一起战斗的同伴、有花不完的预算等等。但现实是:
- boss:诶,小九啊,咱们系统提升下性能要多久啊?三天应该差不多了吧,最多不能超过一周,上次提升性能,小六一天就搞定了的。
- 小九:。。。卒
正常情况下,提升系统的扩展性的难度可能要比重构的难度还要大。因此,在你没有完全把系统摸熟悉,或对扩展性还模糊的时候,千万别给老板说要提升系统的扩展性。
在老板要求提升性能时,你要想尽一切办法满足他提升性能的需求,同时,要多想下如何提高系统的扩展性,为将来提升扩展性赢得时间。
可以通过以下工作先提升系统性能:
- 优化性能。很多时候可以通过一个简单的改动来获得明显的性能提升。例如为表建立正确的索引,或从 MyISAM 切换到 InnoDB。再进一步,可以通过慢日志来分析。
- 购买性能更强的硬件。在应用早期,升级或增加服务器可以显著的提升系统性能,并且还能快速的完成。就像我们把服务器从 1 台增加到 3 台,可能就能让性能提升 100%,但是当我们的服务器已经到达 100 台时,再从 100 增加到 300,这时候的复杂度和成本可能已经让你心甘情愿走上提升系统扩展性的道路上了。
总结
- 扩展性是当需要增加资源以执行更多工作时,系统能够获得等价的性能提升的能力。
- 不准确评估应用负载的扩展,都是耍流氓。
MySQL - 扩展性 1 概述:人多未必力量大的更多相关文章
- mysql扩展性架构实践N库到2N 库的扩容,2变4、4变8
mysql扩展性架构实践N库到2N 库的扩容,2变4.4变8 http://geek.csdn.net/news/detail/5207058同城 沈剑 http://www.99cankao.com ...
- MySQL - 扩展性 3 负载均衡:眼花缭乱迷人眼
负载均衡的基本思路很简单: 在一个服务器集群中尽可能地的平均负载量. 基于这个思路,我们通常的做法是在服务器前端设置一个负载均衡器.负载均衡器的作用是将请求的连接路由到最空闲的可用服务器上.如图 1, ...
- MySQL - 扩展性 2 扩展策略:氪金氪脑任君选
如果将应用的所有数据简单地放在一台 MySQL 服务器实例上,就不用谈什么扩展性了.但是业务能稳定持续的增长,那么应用肯定会碰到性能瓶颈. 对于很多类型的应用而言,购买更高性能的机器能解决一大部分性能 ...
- MySQL 复制 - 性能与扩展性的基石 1:概述及其原理
1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步. 接下来,我们将从复制概述及原理.复制的配置. ...
- MySQL 复制 - 性能与扩展性的基石:概述及其原理
原文:MySQL 复制 - 性能与扩展性的基石:概述及其原理 1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他 ...
- (转)mysql数据库高可用高扩展性架构方案实施
http://shanhu.blog.51cto.com/1293405/1212605-----mysql数据库高可用高扩展性架构方案实施
- Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结
Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结 1. 什么是可扩展的应用程序?1 2. 松耦合(ioc)2 3. 接口的思考 2 4. 单一用途&模块化,小粒度化2 ...
- OpenStack 企业私有云的若干需求(6):大规模扩展性支持
本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...
- 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
随机推荐
- DDGScreenShot—截取图片的任意部分
写在前面 DDGScreenShot 库提供了截取任意图片的功能, 支持手势截图,当然,输入任意的区域也可以,下面看看具体的代码 代码如下: 方法封装 /** ** 用手势截图(截取图片的任意部分) ...
- [Python学习之路] 猜大小游戏
# coding =utf-8 import random def roll_dice(number=3, points=None): if points == None: points = [] w ...
- Android官方开发文档下载
Android官方开发文档 docs-24_r02.rar(链接:https://pan.baidu.com/s/12xC998JeUHj3ndfDXPM2ww 密码:bxyk) ADT下载.Andr ...
- Java(五、类和对象中的例题)
一.方法中的参数为数值型的(int) import java.util.Scanner; public class ScoreCalc { public void calc(int num1,int ...
- SSH学习之路(一).Net开发与Java Web开发
摘要:一直再使用.net mvc5开发,期间学习过java web相关的知识,现如今想要进阶一下便开始学习ssh框架. 1..net web开发 对于微软的东西,开发者考虑的东西不需要太多,你新建一个 ...
- bugku misc writeup(一个普通的压缩包)
这个题做了好几个小时,因为没有writeup,一点一点摸索,做题思路写出来给大家交流 首先这是一个zip.rar压缩包,下载下来第一步就是拖进hexeditor中观察,检查下文件的头尾结构是否有问题, ...
- 根据appId匹配项目名称
有时候后端返回的接口中也许没有我们想要的字段,可以通过下面的方式拿到想要的字段 代码如下: //获取项目名称 getBizName(appId) { let proNameList = this.$s ...
- MySql在生产环境中是用mysqldump还是xtrabackup备份和恢复数据
如题,究竟该使用mysqldump还是xtrabackup,要说用,两个都能备份,都支持热备,但是生产环境我们要考虑的是效率,就是不管备份还是恢复,都要快,要稳定. 之前我在维护mysql数据库的时候 ...
- Mysql中外键的 Cascade ,NO ACTION ,Restrict ,SET NULL
外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update 外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配 ...
- Linux内核编程、调试技巧小集
1. 内核中通过lookup_symbol_name获取函数名称 内核中很多结构体成员是函数,有时可能比较复杂不知道具体使用哪一个函数.这是可以通过lookup_symbol_name来获取符号表名称 ...