第20章 可扩展的架构
本章将为读者讲述可扩展的架构相关的知识和技术。
可扩展的架构意味着这个架构伸缩性好,我们可以用更多的节点来提高吞吐率,而性能(响应时间)不会下降到不可接受的范围。
互联网世界飞速发展,数据量、访问量对比过去有了爆炸式的增长,数据库比整个系统的其他组件受到的挑战更大。
一般来说我们可以通过增加Web服务器来提高处理能力,但我们很难简单地通过增加数据库服务器的节点来提高吞吐。

20.1 做好容量规划
做好容量规划,也就是收集足够的信息,看系统如何处理负载,如果负载增加时,系统应该如何扩展。
容量规划往往基于我们对于业务的理解,业务发展得如何,我们的应用需要怎样的性能目标?通过研究资源的限制和影响的因素,制订自己的容量规划。
研究资源限制的方式是:
首先,我们要衡量服务的请求数,监视其增长速率,
然后,衡量硬件和软件的资源使用情况,监控其增长速率,
然后,可以把请求数的增长和资源的使用映射起来,推断在目前的资源限制下(看哪个资源会最先到达瓶颈),还能提供的最大服务请求,
或者可以使用工具进行压力测试以判断最大服务请求,如果可能,应该用真实的业务流量进行压测,可以考虑tcpcopy这样的能够重放流量的工具。
如上的方法,难点之一在于如何将业务的指标转换为应用服务器的访问请求,再转换为数据库的QPS,你需要熟悉业务,
或者说需要数据库的维护人员和研发人员、产品人员一起探讨,确定未来的业务流量的增长会对数据库产生什么影响。
系统可能会很复杂,难以得出结论,但是,如果你留有一定的余量,技术团队也富有经验,
那么在一般情况下,是不会有太大的问题的,因为你将会有足够的时间处理突然增加的负荷。
对于大规模的和复杂的系统,则需要有更多的设计考虑, 监控和记录各种接口的调用情况,设计各个子系统的容量,做到更自动化的预警和扩容。
研究影响的因素是指,研究数据量增长、事务吞吐等会影响到资源使用的因素,现实中,特别是互联网应用,往往低估了数据量的增长和事务的增长。
所以前期要尽可能多地收集信息,了解你的实例所处的环境,做一些扩展性的规划,比如考虑是否要进行分片设计,是否要做负载均衡的规划等。
还需要考虑故障情况下的系统使用,对于海量高并发的应用,要注意其他组件的失效影响,所有的组件都需要监控和记录数据。
现实系统中可能包括了各种组件,比如:负载均衡设备、Web服务器、应用服务器、Cache服务器(如Memcached、Redis)、消息队列、DNS服务器、Proxy等。
要监控缓存性能的变化,统计命中率、失效率,缓存失效对数据库的冲击很大,所以你必须考虑到缓存命中率下降或缓存宕机的影响,留有一定的余量是必须的。
确保当你的缓存节点挂掉一个或多个时,你的整个系统,还能继续提供稳定的服务。
如果超过了系统能够提供服务的能力,那么你应该有措施和机制来保护数据库系统,以避免雪崩等连锁反应。
以上主要叙述的是随着应用规模不断增加的情况下的扩容考虑,现实中,我们还需要关注磁盘空间、内存等单一资源的扩展,由于它们相对比较简单,因此这里将不再赘述。

20.2 扩展和拆分
在互联网的架构设计中,一个关键的衡量指标就是系统的可扩展性,也称为伸缩性,指的是系统不断增加其承载能力的能力。
在业务的高速发展中,IT系统不应该成为整个公司的瓶颈。 扩展可简单地分为以下两类。
1.向上扩展(scale up)
相对而言,这是更简单的方式,你应该优先使用该方式,一般情况下向上扩展就足够了,但如果向上扩展的代价太大了,那么它就不可取了。
向上扩展总是有极限的,比如,你可以不断地增加CPU节点,但由于CPU节点之间还需要进行通信,因此CPU缓存一致性会越来越难以保证,
等到了一个极限,即使你增加了CPU节 点,系统的吞吐也不可能上升,甚至可能还会下降。
目前MySQL能充分利用的资源是有限制的,
比如主机使用的是256 GB内存、32核、一个PCI-E Flash卡一般就足够了,如果超过了这个硬件成本,即使有性能上的提升,但成本上可能就不合算了。
随着软硬件技术的发展和硬件价格的变化,你需要寻找一个性价比良好的方案合理搭配软硬件。
市场上的主流产品,不仅能够 做到更大规模的生产,而且成本也更低,一般是更值得考虑的。
如果硬件规格过高或过新,你可能不得不付出更昂贵的成本,性价比反而不好。
对于一些应用类型,比如复杂的查询,即使再昂贵的硬件也无济于事,因为性能更受限制于体系架构,你的体系架构无法充分利用到你的硬件资源。
所以笔者建议,在做扩展之前,要先确认你已经很难进行软件架构的优化了,比如,你是否一定要访问这么多数据?是否可以减少访问?是否可以归档和清理数据。
2.横向扩展
横向扩展也称为水平扩展(scale out),是指通过副本、垂直拆分、水平拆分的方式,把不同的数据放到不同的节点中,我们所说的节点指的是物理部署的 MySQL实例。
副本比较好理解,一般是指增加数据库的从库(复制副本),通过分担一部分读的流量到从库上,扩展整个系统的处理能力,也就是我们常说的读写分离,20.3节我们将详述读写分离。
垂直拆分指的是按功能模块划分数据,采用这种方式的多个数据库之间的表结构不一样。
比如一个电商网站,可能有库存管理的数据,也有用户相关的数据, 它们属于不同的功能,可以拆分到不同的节点。
对于更微观的层级,数据表可以按字段划分数据:大字段和字段访问频率相对于表中其他低很多的字段更适合从表中垂直分拆出去,通过减少I/O资源消耗来达到优化性能的目的。
水平拆分(sharding)指的是将同一个表中的数据进行分片保存到不同的数据库中,一般实现为数据库内的分表设计,这些数据库中的表的结构一般都是相同的。
当内存、磁盘空间、磁盘I/O、网络、CPU等资源受限制了,我们就需要拆分,以获得持续稳定的服务能力。
数据库节点的处理能力都是有限制的,进行水平拆分主要是需要扩展写的能力。
读的能力相对比较容易扩展,我们可以通过缓存、副本等进行扩展。
但写的能力,单个主机(节点)可能难以处理,这个时候,你需要进行水平拆分,将数据按照一定的规则,分配到不同的节点。
如果预知数据会有一个爆炸式的增长,那么可以直接从单节点过渡到分片(sharding)结构,而不是经过许多垂直拆分,导致架构变得复杂、难看。
市场中已经有一些数据库中间层产品,或者一些云数据库,宣称能够将数据透明地拆分到不同的节点中,可完美地实现水平扩展,
现实使用中,这样的产品可能会有各种限制,而且效率不高。
通过自己手动地分片数据,让应用层到具体的节点去获取数据会更高效,
因为我们要知道一个原则,应用层才真正地了解数据, 知道数据应该如何查询和处理,没有人比你自己更熟悉自己的应用。
进行数据分片设计的一个重要步骤是确定sharding key,常见的有用户ID,比如,我们可以通过对用户ID进行散列,把数据分布到不同的节点中。
大部分应用,使用一些简单的算法进行分库分表的路由,准备10倍到20倍的扩展,1到2年的扩展即可,
也就是说,我们把分库分表的逻辑直接写在程序里,使用mod、crc32等散列算法即可。
许多人还使用key分段的方法来做容量扩展及负载均衡,笔者不是很推荐采用这种方式,因为可能会导致数据不均衡和热点数据不均衡的问题,调整起来也会很困难。
如果预见到数据和负载会有爆炸式的增长,那么更值得推荐的方式是设计一张路由表,里面存储数据到后端物理节点的路由信息。
这样的实现方法有一个好处,我们可以达到一个效果,前端有许多逻辑的DB,而后端是有限的一些物理节点。这种方式更方便我们进行迁移和维护。
路由表不一定要保存在数据库里,你也可以设计一个高可用的服务来存储这个路由信息。
如下是设计和维护分片需要注意的一些要点。
1)确保最重要最频繁的查询访问尽可能少的节点,不仅要方便存储数据,还要确保数据读取方便高效。
2)要避免单个节点的资源超过限制,要有足够的监控和预警措施,各分片的数据也可能会不均衡,你需要及时发现这种情况,并进行调整。
3)分片数量要合适,要有利于负载均衡和进行维护,比如修改表结构。
分片数量也不能过多,过多可能会导致一些异常问题,比如,一个简单的查询要访问多个分片响应会变得很慢。
需要说明的一点是,分片可以让失效的数据保持在某个范围内,但同时分片将导致更多的硬件错误。
虽然按照分片的逻辑,把数据拆分到多个节点上很美好,如果可能发生故障,每次只会有一部分服务异常,但节点出问题的概率也大大增加了,
而实际生产环境中单台主机宕机的概率是很小的,所以不要过多地分片,你应该在资源可能短缺的情况下,为了扩容考虑的目的而考虑分片。
节点的个数和分片的数量有赖于DBA和研发、产品等团队一起讨论确定,
互联网应用数据的容量规划在很多情况下都不是很清晰,这是现实,所以应尽可能地沟通信息,掌握足够的数据是有必要的。
4)分片之后,表之间的连接会比较困难,你需要尽量避免连接,或者采用更合适的方案来组合数据,
比如,我们可以设定多个sharding key,使用不同的sharding key冗余多份数据,以做到减少连接,更高效地访问数据。
我们也可以使用缓存、统计表等手段来减少连接。
5)热点数据可能会导致性能问题,可能需要调整sharding key或算法,将数据切割为更小的分片,如果对于复制延时要求不高,也可以利用从节点来扩展读的能力。
6)应确保节点的快速恢复,比如对于单点故障,你可以自动路由到正常的节点,或者是提供开关降级服务,比如提供一个只读的节点,用于保障部分功能可用。
注意:
可扩展并不是要构建一个完美的扩展架构,而是应用程序真的需要进行扩展时,才考虑扩展,我们要预先规划,即使在以后规模变得很大的时候,系统也仍然能够提供合格的服务。

20.3 读写分离
读写分离指的是,通过增加一些节点,扩展读的能力。
这些节点可以是主节点的全部内容的副本或部分内容的副本,也可以是缓存产品。
读写分离一般配合负 载均衡产品一起使用。
对于读多写少(非更新查询为主)的负载,特别适合做读写分离。
需要留意的是,要保证用户感知到自己所做的变更有效即可,用户在很多情况下并不需要知道其他用户的改变。
如果用户对于数据的一致性要求在某个时刻很高,那么这部分数据,建议不要使用读写分离,MySQL的复制可能会出现延时,无法满足业务的需要。
你可以采取变通的方式,比如,在用户修改了内容之后,临时强制用户访问主节点,以获取一致性的数据,
在过一段时间之后,再让用户访问副本的数据, 一般在此时,副本的数据已经同步到最新状态了。
读写分离往往和负载均衡技术配合使用。
负载均衡软硬件产品有F5、Haproxy及一些自己设计的MySQL Proxy代理等,
负载均衡可以更高效地利用硬件,你可以设置权重,分配更多的流量给性能更好的机器,
负载均衡产品一般还有故障检测、自动冗余切换等功能,这可以大大提高机器的可用性。
读写分离技术的一个难点在于延时的影响,你需要有一个手段来确保你没有读取到太旧的数据,写操作和一些不能容忍延时的查询,需要指向主库。
对于数据延时敏感度不高的数据,你需要定义延时的阈值,通过自动或手工的方式处理延时数据对于用户体验的影响。
你可以通过监控SHOW SLAVE STATUS里的输出Seconds_behind_master的方式判断是否有延时,但这种方式不太可靠。
监控复制滞后(replication lag)更稳健的方式是通过心跳表的方式。
我们很难确保MySQL的延时,因为网络波动、复制异常、性能问题等都可能导致复制中断,而往往需要人工来进行干预,
毕竟有能力开发专用的Proxy代理的公司很少,所以,不建议使用读写分离,
采用读写分离一般是基于一个前提,主库已经出现了读瓶颈,如果出现了读瓶颈,那么使用缓存一般是更有效、更成熟的解决方案。
由于没有好的读写分离的方案,如果你一定要使用读写分离,那么推荐应用程序自身实现读写分离,把读的流量指向负载均衡产品或Proxy代理。

20.4 切勿过度设计
过度设计,指的是你的设计过度地考虑了未来的一些需求,或者根本就是想象出来的需求。
现实中,我们对于数据的量化往往做得还不够。我们要设计一个可扩展的架构,但由于没有进行足够的量化分析,往往导致了过度设计,比如采购了过多的硬件设备。
可扩展的目标的设定很重要,你要根据业务的发展和自己业务的特点,定义可扩展的目标,
在架构初期,可扩展往往并不是那么重要,尽快实现简单稳健的方案是最主要的,如果你留有一定的余量,可扩展性在大部分公司一般是不成为问题的。
你需要靠经验和数据设定这个余量,因为一旦扩展不下去了,成本就会变得很高,可能还会需要重构。
你需要衡量是否要预先进行分片,现实中,往往会出现的一种情况是,研发人员不熟悉硬件性能极限和业务增长,扩展太多,比如分库太多,导致整个方案变得复杂和成本高昂,
所以,如果需要进行分片,你一定要确认自己必须得这么做。
如果你不熟悉硬件,那么你应该去请教对硬件熟悉的人员。如果研发人员不熟悉硬件,那么硬件维护人员和软件架构人员共同探讨是有必要的。
可扩展性是建立在数据规划的基础上的,所以你要熟悉你的业务,熟悉业务需要存取的数据的行为,
我们在架构的初期,就应该确定数据的规模和访问的特点,可以考虑的一些因素具体如下:
各种操作的频率,比如读(SELECT)的次数和INSERT事务的次数。
峰值时刻的事务数。
查询是简单的还是复杂的,各自的比例如何。
并发连接数。
数据量,可以预估1~2年后的数据量。
数据的重要程度。
数据保留和清理的策略。
数据分片策略。
以上因素大部分是从运维的角度来考虑的,数据架构的时候,你还需要细化到具体的数据和具体的访问数据的行为,
比如,你需要特别关注访问量最大、频率最高的一些查询,优先对这部分数据进行库表设计和应用程序优化。
可以说,好的数据库是设计出来的,而不是调优出来的。
需要明确的是,互联网公司不同于传统企业,传统企业的业务类型比较固定,一般不会做变动,熟悉业务的系统架构人员、开发人员可以比较准确地进行性能规划,合理安排扩容的资源。
但互联网公司业务变化大,许多时候是追求迭代发布,而不再要求性能规划、数据规划的精准度。
我们应该确保的是,系统在一定时期内有足够的伸缩性,做好监控,确保系统有足够的性能余量可以支撑短期的负荷上升。
传统行业的规划周期太长,而互联网行业规划个半年、1年也许就足够了, 一般不用考虑2~3年之后的长期的扩展需求。
一般来说,我们已知的一些传统的性能规划的理论,并不适用于互联网公司不断变化和发展的应用,利用简单的基准测试来进行性能规划也是不切实际的,因为很难模拟真实的负荷。
比如我们经过基准测试,可以证明在一个新的硬件架构上,可以支撑起比目前的负荷高10倍的访问量。
但实际上,如果现实中真的有了10 倍的访问量的时候,许多情况就已经发生了变化,
如流量、用户、数据、应用复杂度、关联数据的交互、热点数据大小,甚至应用的核心功能也已经发生了大的变化。
所以,我们需要做到的是确认我们的系统能够满足未来一段时间的产品发展,有足够的余量,而不用去规划一个长期的目标,
当然,这需要足够的数据收集和量化工作,我们做不到完全精准,但是你不能有数量级别上的差异。

20.5 可扩展的方法
确保可扩展有许多方法,如果具体到某一个产品,那么也要有各种各样的手段,这里主要从更宽泛的角度去讨论一下可扩展的方法,
比如静态内容、动态内容、网络应该如何做到可扩展,以及可扩展的一个重要手段:解耦。
了解其他环节、其他领域的知识,将有助于我们确定调优的方向,合理地进行数据库的优化。

20.5.1 优化静态内容、动态内容
首先要分离静态内容和动态内容,分离了静态内容和动态内容之后,我们才可以分别进行优化,选择更适合的应用服务器,
比如Nginx更适合静态文件,而 Apache相对来说更适合动态内容。某些静态文件还可以压缩传输。
完全静态化是不现实的,往往需要通过模板的方式,我们有必要了解我们所维护的项目的静态化策略。
不同的应用服务器适合处理不同的内容,尤其对于海量流量的应用,用更合适的产品来处理特定的内容,会更有规模效应。
静态内容优化的主要的技术是CDN技术,CDN的目的是将网站的内容发布到最接近用户的网络位置,使用户可以就近取得所需的内容。
动态内容优化的一些方法和指引规则具体如下:
计算复用:计算复用指的是,通过一些编程技巧,可以重复利用之前的计算结果,加快执行效率。
计算复用并不适合应用于复杂的算法操作,在日常的许多编程中,都可能碰到,如果有一些操作频繁的执行,又和上下文无关,那么可能是需要考虑计算复用的。
使用缓存:缓存系统缓存了程序处理的结果,它可以减少对后端的调用。
同样的内容不要产生两次:因为数据是可以被缓存的,无论缓存在服务器还是客户端,我们都不需要重复产生相同的内容,因为这样会浪费系统资源 。
仅在数据发生改变时,重新生成内容:有时我们想生成一些静态文件,提高访问效率,相对于重新生成所有的文件,仅重新生成数据发生了改变的页面,是成本更低的方式。
将系统切割为更小的组件,分离频繁变更的部分和不经常变动的部分。
减少对数据库的调用:相对于应用服务器,数据库的可扩展性更低,减少对数据库的调用,可以让数据库没那么可能成为整个系统的瓶颈所在。
对于缓存产品,如Memcached,需要留意缓存策略,比如,超时的设置或设置得过小,会导致数据库的压力。更有效率的做法是,在数据内容发生改变的时候,才通知缓存失效。
对于一些变化非常频繁的内容,几乎没有缓存的必要,这个时候有必要和产品经理、用户体验设计师、前端和后端的研发人员一起来考虑问题,是否可以减少变化的可能性。

20.5.2 网络优化
关于网络优化的参数,这里就不展开讲了,笔者很少调优网络相关的内核参数。
下面将叙述一些网络相关的注意事项,具体如下:
我们需要了解数据流,清楚我们的网络架构,这样有助于我们进行分析,在哪些环节可能存在网络问题,哪些环节可以优化。
比如用户最开始发起访问,一般要有DNS查询的环节,那么我们是否可以让用户选择最近的DNS服务器呢?
我们是否可以调度用户访问最近机房的服务器呢?我们是否需要配置一个反向代理来加速用户访问呢?
应用服务器处出现网络瓶颈的可能性远大于数据库,数据库一般网络流量很小。
现实中,优化网络的行为很少,这个主要是因为绝大部分项目在还远远没有到达网络瓶颈的时候就暴露出架构的问题了。
跨IDC的网络质量不能和内网质量相比,对于跨IDC的网络,两个节点之间来回往往需要几十毫秒,
节点之间的各种设备(路由器、交换机等)都可能影响到网络质量,运维比研发人员要更加意识到跨IDC网络质量对于整体系统的影响。

20.5.3 解耦
解耦是确保可扩展的架构的最重要的技术之一。
许多知名的网站和服务,采取的都是一种松散耦合的服务导向的模型,比如Twitter、Amazon等。这种松散耦合的服务,可以尽快发布新特性。
小型的团队可以自己制定决策,发布面向用户的变更,而不依赖于其他团队。
解耦的方法具体如下。
1)异步。
异步指的是,有些操作并不需要要马上去做,而是可以延迟到以后再做,因为这并不会影响用户的体验。
“异步”的字面意思可能会导致混淆,“异步”并不是说一定要把工作推迟到以后去完成(尽管这可能会发生),
异步技术一般使用了队列,实际上队列往往不会被积压,它们会处理得很快,它的本质目的是为了解耦,因为有些操作并不需要等待另外一些操作,可以“异步”地、并发地进行。
2)把业务逻辑分解为更小的部分,分而治之。隔离那些可以异步操作的部分。
通过把系统分解为更小的部分,我们可以做到如下几点:
简化问题,原来一个复杂的逻辑,我们可以将其分解为一些更简单的问题。
故障隔离,针对更小的系统,我们可以针对性地设计处理策略,某个子系统的故障不会影响到其他的子系统,其他子系统仍然可以正常地运行。
分解我们的方法、策略和实现,这个比较好理解,分解为更小的部分,我们的复杂的方法、策略和实现就变成了更小的问题。
简化我们的设计,我们把复杂的问题分解为简单的问题,那么设计也会变得相对简单得多了。
更好地建立性能模型,因为能够更准确地衡量影响性能的因素,从而可以简化容量规划。
容量规划其实不是一件容易的事情,你首先得有一个性能模型,如果影响性能的因素有很多,那么你这个性能模型会很复杂,难以建立,或者不太准确;
现在我们分解了问题,因此我们可以建立一系列简单的模型,然后就可以综合这些简单的性能模型得到我们最终的性能模型。
3)使用消息队列。
这个和上面所说的异步,是结合在一起的,利用消息队列可以很好地异步处理数据传送和存储,我们把需要完成的工作的信息用队列进行传送,这样就可以实现异步幕后处理队列了。
也就是说,我不想现在就做某件事情,而是告诉其他人去做这件事情,这样可以加快我做事的效率。这也是我们上面所说的异步。
互联网应用大量地使用了消息队列。消息队列不仅被用于系统内部组件之间的通信,同时也被用于系统跟其他服务之间的交互。
当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据时,就可以采取消息队列来异步插入。
另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台进行处理,例如FLV视频转换、发送手机短信、发送电子邮件等。
消息队列的使用可以增加系统的可扩展性、灵活性和用户体验。非基于消息队列的系统,它的运行速度将取决于系统中最慢的组件的速度(也就是短板效 应)。
而基于消息队列,可以将系统中的各个组件解除耦合,这样系统就不再受到最慢组件的束缚,各组件之间可以异步运行,从而可以以更快的速度完成各自的工作。
除此之外消息队列还可以抑制性能波峰的产生,在瞬时业务高峰产生时可保持性能曲线的平滑。
消息队列有许多解决方案,有许多正在广泛使用的产品,许多互联网公司基于自身的业务特点,设计了满足内部需求的消息队列。
消息队列可能会有单点,所以,你也需要确认你的架构已经解决了单点问题。

20.6 使用云数据库
云计算,或者说云平台,更多的是属于水平扩展的范畴,系统建立在更小的虚拟系统之上,
所以,一开始你不需要购买庞大的系统,可以从很小的购买预算开始,你可以以更小的粒度进行扩展,而传统的方式可能需要添加整整一台机器。
由于更具有弹性,所以一开始可以从很小的规模开始,因此不像传统行业那样,需要精细的容量规划。
云服务商有时还可以提供高级的特性,可以按负载动态扩容和释放(需要配合可靠的监控)节点。
由于可以比较方便地增加和减少节点,性能优化很快就可以见效,因为优化了性能,就只需要更少的节点,
而对于传统行业来说,你投资了设备,那么即使你优化了性能,这些设备也是闲置的,不能立马起到降低成本的作用。
本质上来说,系统是不是可扩展的,很大程度上并不取决于使用的具体产品,而在于你的软件架构,
所以在云上,我们仍然可以使用传统数据库,而依然保持良好的扩展性。
而这也属于比较通用的做法。国内外的云服务商一般都提供了MySQL云。
如果不考虑维护成本,我们对比国内的IDC托管主机和云计算的成本,可以得出结论,云平台的成本比自己租用主机的费用高出不少,
一些初创小公司在项目初期,为了节省维护和部署的成本,可以使用商业公司的云服务,
而在规模扩大之后,你就需要考虑性价比是否合适,一般来说,对于大批量的节点购买,云服务商会提供更大的折扣。
使用云服务要考虑的一个问题是,针对云服务的调优(包括数据库)会变得很困难,由于多个实例可能位于同一台主机或同时申请使用了共享的资源。
这种多租户的环境,可能会导致一些异常,比如虽然你的程序没有问题,但你的服务可能会受到其他租户的影响,
调优诊断也会变得很困难,因为可能你所使用的资源难以监控,传统的许多调优方式在云中可能不太适用。
随着云服务的成熟和普遍使用,随着监控和诊断平台的完善,云服务的调优会变得越来越简单。
一些云服务的升级和维护,也可能导致你的服务出现异常。
云服务商一般提供99.5%的可用性保证,而基于传统的方式托管机器,运维得当,4个9(99.99%)的可用性也是可以轻易达到的。
一般售卖的云主机,主要依据内存的大小进行定价,其他资源,比如CPU,随着内存的增加,也会得到相应的扩展。
一些公司可能部分服务器自己托管在IDC,部分使用云服务,这样也是一个比较折中的想法,因为对于突发的负荷,可以使用云服务的弹性扩容能力来处理。

小结:
本章为读者介绍了可扩展架构的一些知识,部分内容严格来说,并不属于数据库的范畴,但它们和数据库的可扩展性息息相关,而且,我认为一个好的DBA,应该熟悉这方面的内容。
DBA应该有容量规划的能力,知道常用的拆分数据的手段,审慎使用读写分离的技术,并且能够和研发人员一起探讨可扩展的一些方法。
可扩展要考虑的因素很多,在进行架构调优的过程中,你必须综合考虑性能和成本,做一些取舍。 关
于云平台的使用,笔者的经验不多,读者如果需要使用云服务,可以考虑亚马逊、阿里云等服务商。

20-MySQL DBA笔记-可扩展的架构的更多相关文章

  1. 1-MySQL DBA笔记-理解MySQL

    第一部分 入门篇 本篇首先介绍MySQL的应用领域.基础架构和版本,然后介绍MySQL的基础知识,如查询的执行过程.权限机制.连接.存储引擎,最后阐述一些基础概念. 第1章 理解MySQL 本章将介绍 ...

  2. Mysql DBA 20天速成教程,DBA大纲

    Mysql DBA 20天速成教程 基本知识1.mysql的编译安装2.mysql 第3方存储引擎安装配置方法3.mysql 主流存储引擎(MyISAM/innodb/MEMORY)的特点4.字符串编 ...

  3. 读书笔记——《MySQL DBA 工作笔记》

    关于前言 作者在前言中提出的一些观点很具有参考价值, 梳理完整的知识体系 这是每一个技术流都应该追逐的,完整的知识体系能够使我们对知识的掌握更加全面,而不仅仅局限于点 建立技术连接的思维,面对需求,永 ...

  4. Mysql DBA 20天速成教程

    Mysql DBA 20天速成教程 基本知识1.mysql的编译安装2.mysql 第3方存储引擎安装配置方法3.mysql 主流存储引擎(MyISAM/innodb/MEMORY)的特点4.字符串编 ...

  5. MySQL入门笔记

    MySQL入门笔记 版本选择: 5.x.20 以上版本比较稳定 一.MySQL的三种安装方式: 安装MySQL的方式常见的有三种: ·          rpm包形式 ·          通用二进制 ...

  6. [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...

  7. MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师年一线实战经验,我当然不能和我的老师平起平坐,得到老师三分之一的 ...

  8. (转)MySQL优化笔记(八)--锁机制超详细解析(锁分类、事务并发、引擎并发控制)

    当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异常重要了. 原文:http://www.jianshu.com/p/163c96983 ...

  9. MySQL DBA的修炼与未来(参考篇)

    转自:https://blog.csdn.net/xielingshao/article/details/77840101 MySQL DBA的修炼与未来 随着MySQL地位爆炸式的提升, MySQL ...

随机推荐

  1. android: ListView设置emptyView 误区

    使用ListVIew 来设置EmptyView的时候须注意: ListView listview = (ListView) findViewById(R.id.list); View emptyVie ...

  2. jquery页面滚动到指定id

    //jquery页面滚动到指定id  $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html ...

  3. angular 中*ngIf 和*ngSwitch判断语句

    <div style="text-align:center"> <h1> Welcome to {{ title }}! </h1> <p ...

  4. 【PHP】解决数据库查询出来的中文内容显示为问号“??”

    方法一:在数据库连接后执行: mysql_query('SET NAMES utf8'); 代码: $dbconn=mysql_connect("localhost", " ...

  5. DisplayAttribute应用——根据PropertyName自动获取对应的UI显示名

    model定义,使用DisplayAttribute public class AddressSetInfo { /// <summary> /// invoiceAddress.Id / ...

  6. request请求模拟导出文件

    ui界面: 实现代码: def export(self,host): '''导出课时券记录''' #测试接口 url='https://'+host+r'/ticket-record/export?t ...

  7. PAT 甲级 1037 Magic Coupon (25 分) (较简单,贪心)

    1037 Magic Coupon (25 分)   The magic shop in Mars is offering some magic coupons. Each coupon has an ...

  8. 展BOM

    CS_BOM_EXPL_MAT_V2 *&---------------------------------------------------------------------* *&am ...

  9. C#泛型学习

    什么是泛型 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明.各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数 ...

  10. LeetCode_67. Add Binary

    67. Add Binary Easy Given two binary strings, return their sum (also a binary string). The input str ...