MySQL - 扩展性 1 概述:人多未必力量大

咱们应该接触过或者据说过数据库的性能瓶颈问题。对于一个单机应用而言,提高数据库性能的最快路径就是氪金 - 买更高性能的数据库服务器,只要钱到位,性能不是问题。git

可是当系统性能增长到必定地步时,你会发现,原先花 3000 块提高了 50% 的性能,如今花 30000 块,才提高了不到 10%。程序员

也就是说,咱们花了钱,但没有获得等价的性能提高,这个时候,咱们就要考虑数据库的可扩展性了。github

要讨论 MySQL 的可扩展性,就要先明确可扩展性的定义。在此以前,咱们先抛开 MySQL,专一于扩展性,搞清楚什么是扩展性,才能更有针对性的去提高数据库的扩展性。数据库

1 什么是可扩展性

咱们经常把“可扩展性”、“高可用性”以及“性能”用做同义词,但事实上它们是彻底不一样的。简单来讲,性能是响应时间,可用性是宕机时间,而扩展性代表了当须要增长资源以执行更多工做时,系统可以得到等价的性能提高的能力。换种说法,可扩展性就是咱们可以尽量的花费相同的资源提高等价的性能。而缺少扩展能力的系统在达到收益递减的转折点后,将没法进一步增加。安全

容量是一个和可扩展性相关的概念。系统容量表示在必定时间内可以完成的工做量。服务器

容量和可扩展性并不依赖于性能。以高速公路上的汽车来类比的话:并发

  • 性能是汽车的时速。
  • 容量是车道乘以最大安全时速。
  • 可扩展性就是在不减慢交通的状况下,能增长更多车和车道的程度。

在上面这个类比中,可扩展性依赖多个条件:换道设计是否合理、路上有多少车抛锚或发生事故、汽车行驶速度不一样以及是否频繁变换车道。但通常来讲,和汽车的引擎是否强大无关。性能

这并非说性能不重要,性能确实重要,只是要注意的是,即便系统性能不是很高的系统也能够具有可扩展性。优化

从较高层次看,可扩展性就是可以经过增长资源来提高容量的能力。网站

对于容量,咱们能够简单的认为是处理负载的能力,而从不一样的角度考虑负载对咱们优化扩展性颇有帮助。

数据量

应用所能累计的数据量是可扩展性最广泛的挑战,特别是对于如今的互联网应用而言,由于从不删除数据。

用户量

首先,即便每一个用户只有少许的数据,但在累计到必定数量的用户后,数据量也会开始不成比例的增加,且速度快过用户数增加。其次,更多的用户意味着要处理更多的事务,而且事务数可能和用户数不成比例。最后,大量用户也意味着更多复杂的查询。

用户活跃度

不是全部的用户活跃度都相同,而且用户活跃度也不老是不变的。若是用户忽然变得活跃,例如 github 给小团队免费开放了私有化仓库,那么其对应的负载可能会明显提高。要注意的是,用户活跃度不只仅指页面浏览数(PV),即便一样的 PV,若是网站的某个须要执行大量查询工做的功能变得更受欢迎,也可能致使更多的工做。

相关数据集的大小

若是用户间存在关系,应用可能须要在整个相关联用户群体上执行查询和计算,这比处理一个个的用户和用户数据要复杂的多。

说了这么多,只是为了让咱们更好的理解可扩展性的让咱们用下面图表来更明确的表达可扩展性。

假设有一个只有一台服务器的系统,而且可以测量它的最大容量,如图 1 所示:

图 1:一个只有一台服务器的系统

假设咱们如今增长一台服务器,系统的能力加倍,如图 2 所示:

图 2:一个线性扩展的系统增长一台服务器得到两倍容量

图 2 就是线性扩展。咱们增长了一倍的服务器,增长了一倍的容量。然而,理想是美好的,现实是骨感的。大部分系统并非线性扩展的,而是如图 3 所示的扩展方式:

图 3:一个非线性扩展的系统

大部分系统都只能以比线性扩展略低的扩展系数进行扩展。这就致使,多数系统最终会达到一个最大吞吐量临界点,超过这个点后增长投入可能反而会下降系统的吞吐量。

到这一步,你们对扩展性应该已经有一个较为清晰的概念了。在此基础上,让咱们再深刻一步:Amdahl 扩展 和 USL 扩展。

简而言之,USL 说的是线下扩展的误差可经过两个因素来创建模型:

  1. 没法并发执行的一部分工做;
  2. 须要交互的另一部分工做。

在对第一个因素继续建模后,就有了著名的(听过这个著名吗?)阿姆达尔定律(Amdahl)。第一个因素最终会致使吞吐量趋于平缓。若是部分任务没法并行,那么无论你若是分而治之,该任务至少须要串行部分的时间。这句话很重要,让咱们用一个栗子再简单阐述下:
假设你们都作过韭菜煎蛋这道菜,咱们作这道菜时,有几个必要步骤:

  1. 切韭菜,耗时 t1;
  2. 打蛋液,耗时 t2;
  3. 开煎,耗时 t3;

就上面 3 个步骤而言,你能够在切韭菜的时候,让你女票帮你打蛋液,也就是说 一、2 是能够并行的,可是咱们能边切菜边煎吗?或者边打蛋液边煎吗?显示是不行的。所以,步骤 3 和 一、2 是串行的。

这时候,咱们就会发现,作韭菜煎蛋这个任务须要的时间 t 为:

t = MAX(t1, t2) + t3;

对第二个因素,须要交互的工做而言,交互就意味着内部节点间或者进程间的通讯。这种通讯的代价取决于通讯信道的数量,而信道的数量将按照系统内工做者数量的二次方增加,因此最终开销比带来的收益增加的更快,这就是产生扩展性倒退的缘由。由此和 Amdahl 定律,就得出了 USL。

图 4 阐明了目前讨论的三个概念:线性扩展、Amdahl 扩展以及 USL 扩展。而大多数真实系统看起来更像 USL 曲线。

图 4:线性扩展、Amdahl 扩展以及 USL 扩展定律

至此,关于扩展性的概念描述告一段落。接下来,咱们回到正题,看看 MySQL 的扩展性如何规划。

2 规划可扩展性

什么状况下须要扩展?,这是个值得咱们牢记的问题。当咱们提到系统的可扩展性时,通常只有两种状况:

  1. 刚开始规划一个应用;
  2. 当前应用没法知足增长的负载;

上述两种状况,大多数状况下咱们碰到的应该都是后者。具体表现为:

  • CPU 密集型变成 I/O 密集型;
  • 并发查询竞争;
  • 不断增大的延迟;

若是是可扩展的应用,能够简单地增长更多的服务器来分担负载。但若是是可扩展性比较差的,你就会发现 - 只剩下提升可扩展性这一条路可走。

只有一条路,那就且行且 996 吧!

走上了提高扩展性这条路,接下来的问题就是,如何提升可扩展性?这里比较困难的部分是估算应用承担的负载到底有多少?这个值不必定很是精确,但必须在必定的数量级范围内。什么?你问为何要在必定范围内?不清楚敌人的火力,我们是准备用高射炮打蚊子仍是用大刀对机枪呢?

除此以外,为了能帮助咱们更好的规划可扩展性,我们最好还能想清楚下面这个问题:

  • 应用的核心功能完成了多少?不少可扩展性方案可能会致使某些功能实现起来更加复杂。在核心功能没完成前,问问本身,真的要走提高扩展性这条路吗?换个说法,准备好迎接 996 了吗?

3 为扩展赢得时间

程序员们理想的开发环境应该是:计划先行、有足够可以一块儿战斗的同伴、有花不完的预算等等。但现实是:

  • boss:诶,小九啊,我们系统提高下性能要多久啊?三天应该差很少了吧,最多不能超过一周,上次提高性能,小六一天就搞定了的。
  • 小九:。。。卒

正常状况下,提高系统的扩展性的难度可能要比重构的难度还要大。所以,在你没有彻底把系统摸熟悉,或对扩展性还模糊的时候,千万别给老板说要提高系统的扩展性。

在老板要求提高性能时,你要想尽一切办法知足他提高性能的需求,同时,要多想下如何提升系统的扩展性,为未来提高扩展性赢得时间。

能够经过如下工做先提高系统性能:

  • 优化性能。不少时候能够经过一个简单的改动来得到明显的性能提高。例如为表创建正确的索引,或从 MyISAM 切换到 InnoDB。再进一步,能够经过慢日志来分析。
  • 购买性能更强的硬件。在应用早期,升级或增长服务器能够显著的提高系统性能,而且还能快速的完成。就像咱们把服务器从 1 台增长到 3 台,可能就能让性能提高 100%,可是当咱们的服务器已经到达 100 台时,再从 100 增长到 300,这时候的复杂度和成本可能已经让你心甘情愿走上提高系统扩展性的道路上了。

总结

  1. 扩展性是当须要增长资源以执行更多工做时,系统可以得到等价的性能提高的能力。
  2. 不许确评估应用负载的扩展,都是耍流氓。
相关文章
相关标签/搜索