分而治之思想
扩展规则简述:
1.避免过度设计
内容:设计中警惕复杂的解决方案。
场景:适用于任何项目并且应在所有的大型或者复杂系统或者项目的设计过程中使用。
用法:通过测试同事是否能够轻松地理解解决方案,来验证是否存在过度设计
原因:复杂的解决方案实施成本过高,而且长期的维护费用昂贵。
要点:过于复杂的系统限制了可扩展性。简单的系统易维护、易扩展且成本低。
风险降低:中
成本:低
利益和优先级:高/2
2.方案中包括扩展
内容:提供及时可扩展的DID方法
场景:所有项目通用,是保证可扩展性的最经济有效的方法(资源和时间)
用法:
Design(D)设计20倍的容量
Implement(I)实施3倍的容量
Deploy(D)部署1.5倍的容量
原因:DID为产品扩展了经济、有效、及时的方法。
要点;在早期考虑可扩展性可以帮助端对节省时间和金钱。在需求发生大约一个月前实施(写代码),在客户蜂拥而至的几天前部署
风险降低:低
成本:低
利益和优先级:中/3
3.三次简化方案
内容:在设计复杂系统时,从项目的范围、设计和实施角度简化方案。
场景:当设计复杂系统或产品是,面临着技术和计算资源的限制。
用法:
采用帕累托(Pareto)原则简化范围。
考虑成本优化和可扩展性来简化设计。
依靠其他人的经验来简化部署。
原因:只聚焦“不过度复杂”,并不能解决需求或历史发展与沿革中的各种问题。
要点:在产品研发的各个阶段都需要做好简化。
风险降低:低
成本:低
利益和优先级:中/3
4.减少域名解析
内容:从用户角度减少域名解析次数
场景:对性能敏感的所有网页
用法:尽量减少下载页面所需的域名解析次数,但要保持与浏览器的并发连接平衡。
原因:域名解析耗时而且大量解析会影响用户体验。
要点:减少对象、任务、计算等是加快页面加载熟读的好办法,但要考虑好分工。
风险降低:低
成本:低
利益和优先级:中/3
5.减少页面目标
内容:尽可能减少网页上的对象
场景:对性能敏感的所有网页
用法:
减少或者合并对象,但要平衡最大连接数。
寻找机会减轻对象的重量。
不断测试确保性能的提升。
原因:对象数量的多少直接影响网页的下载时间。
要点:对象和服务对象的方法之间的平衡是一门科学,需要不断的测量和调整。这是在客户的易用性、可用性和性能之间的平衡。
风险降低:低
成本:低
利益和优先级:中/3
6.采用同构网络
内容:确保交换机和路由器来源于同一供应商
场景:设计和扩大网络
用法:不要混合使用来自不同OEM的交换机和路由器;购买或者使用开源的其他网络设备(防火墙、负载均衡等)
原因:节省的成本与间歇性的互用性及可用性问题相比不值得。
要点:异构网络设别容易导致可用性和可扩展性问题,选择单一供应商。
风险降低:高
成本:高
利益和优先级:中/3
7.X轴扩展
内容:即水平扩展,通过复制服务或者数据库以分散事务处理带来的负载。
场景:数据库读写比例很高(可以达到至少5:1甚至更高——越高越好);事务增长超过数据增长的系统。
用法:克隆服务的同时配置负载均衡;确保使用数据库的代码清楚度和写之间的区别。
原因:一复制数据和功能为代价获得事务的快速扩展。
要点:X轴拆分实施速度快,研发成本低,事务处理扩展效果好。然而,从运维的角度看,数据的运营成本比较高。
风险降低:中
成本:低
利益和优先级:高/2
8.Y轴扩展
内容:有时也称为服务或者资源扩展,本规则聚焦在沿着动词(服务)或者名词(资源)的边界拆分数据、交易和技术团队
场景:数据之间的关系不是那么必要的大型数据集; 需要专业化技术资源的大型复杂系统
用法:用动词来拆分动作,用名词来拆分资源,或者两者混用;沿着动词/名词定义的边界拆分服务和数据
原因:不仅允许事务机器相关的大型数据集有效扩展,也支持团队的有效扩展。
要点:Y轴或者面向数据/服务的拆分允许事务和大型数据集的有效扩展,有益于故障隔离。Y轴拆分也有助于减少团队之间的非必要沟通。
风险降低:中
成本:中
利益和优先级:中/3
9.Z轴扩展
内容:经常根据客户的独特属性(例如ID、姓名、地理位置等)进行拆分。
场景:非常大而且类似的数据集,如庞大而且增长快速的客户群,或者当响应时间对在地理位置上广泛分布的客户变得很重要的时候。
用法:根据所知道的客户属性(例如ID、姓名、地理位置等)对数据和服务进行拆分。
原因:客户的快速增长超过了其他形式的数据增长,或者在扩展时,需要在某些客户群之间进行必要的故障隔离
要点:Z轴拆分对扩大客户基数的效果明显,也用在其他那些无法使用Y轴拆分的大型数据集上。
风险降低:高
成本:高
利益和优先级:中/3
10.向外扩展
内容:向外扩展是通过复制或拆分服务或数据库而分散事务负载的方法,与此相对的是向上扩展即通过购买更大的硬件而实现的扩展。
场景:任何预计会迅速增长或想追求低成本高效益的系统、服务或数据库
用法:用AKF扩展立方体因地制宜确定正确的拆分方法,通常最简单的是水平拆分。
原因:以复制数据和功能为代价实现事务的快速扩展
要点:让系统向外扩展,为成功铺好路。期待能向上扩展,结果却发现自己跑的越来越快,已经无法在购买到更快和更大的系统,千万不要掉进这个陷阱。
风险降低:中
成本:低
利益和优先级:高/2
11.用商品化系统(金鱼而非汗血宝马)
内容:尽可能采用小型廉价系统。
场景:在超高速增长的生产系统采用该方法,在比较成熟的产品中以此为架构原则。
用法:在生产环境中远离那些庞大的系统。
原因:可快速和低成本增长。只采购必要的容量,不浪费在尚未明确的容量需求上。
要点:构建能够依靠商品化硬件的系统,不要掉进高利润和高端服务器的陷阱中
风险降低:中
成本:低
利益和优先级:高/2
12.托管方案扩展
内容:把系统部署到三个或者更多活的数据中心,以降低总体成本、增加可用性并实现灾难恢复。数据中心可以是自由设施、托管或云计算(IasS或PaaS)实例。
场景:任何正在考虑添加灾难恢复数据中心(冷备)的快速增长的业务,或希望通过三数据中心方案优化成本的成熟业务。
用法:根据AKF扩展扩展立方体来扩展数据。以“多活”方式配置系统,使用PaaS/IaaS来解决突发容量问题,新投资或者作为三数据中心方案的一部分。
原因:数据中心故障的成本对业务的影响可能是灾难性的。
三个或者更多个数据中心的解决方案的成本通常比两个数据中心少。考虑使用云计算作为部署之一,高峰流量来临时向云扩展。拥有基础流量的设施;租赁解决高峰流量的设施。
要点:在实现灾难恢复时,可以通过系统设计实现三个或者更多个活跃数据中心以降低成本。
IaaS和PaaS可以快速的扩展系统,应用于高峰需求期。通过系统设计确保如果三个数据中心只要两个可用则功能完全不受影响,如果系统扩展到三个以上数据中心,则为N-1个数据中心,功能完全不受影响。
风险降低:高
成本:高
利益和优先级:中/3
13.利用云
内容:有目的的利用云技术按需扩展。
场景:当需求是临时的、突增的、偶发的,响应时间不是产品的核心问题。要将其看成是“租用风险”——新产品对未来需求的不确定性,需要在快速改变或放弃投资时间抉择,公司从双活向三数据中心迁移时,云可以作为第三数据中心。
用法:采用第三方云环境应对临时需求,如季节性业务变动、大的批处理任务或者测试中需要的QA环境;当用户请求超过某个峰值时,把应用设计成可以从第三方云环境对外提供服务。扩展云以应对高峰期,然后再把活跃的节点数减少到基本水品。
原因:在云环境中配置硬件需要几分钟,在自己的托管设施配置物理服务器需要几天或者几周。当临时使用时云的成本效益非常高
要点:在所有网站中利用虚拟化,并在云中扩展以应对意想不到的突发需求。
风险降低:低
成本:中
利益和优先级:低/4
14.适当使用数据库
内容:当需要ACID属性来保持数据关系和一致性时,可以使用关系型数据库。其他数据的存储需要考虑更适合的工具,如NoSQL
场景:当在系统中引入新数据和数据结构时。
用法:考虑数据量、存储量、响应时间长短、关系和其他因素来选择适当的存储工具。也要考虑数据结构以及产品需要对数据进行的管理和操作。
原因:关系型数据库提供了高度的事务完整性,但是成本很高,难以扩展,而且与其他许多可选的存储系统相比可用性较低。
要点:使用合适的数据存储工具,不要因为易访问而用关系型数据库存储所有数据。
风险降低:中
成本:低
利益和优先级:高/2
15.慎重使用防火墙
内容:只有在能够显著降低风险时使用防火墙。防火墙会导致可扩展性和可用性的问题
场景:总是。
用法:可以使用防火墙来满足关键的PII、PCI(支付卡行业)的合规性要求。不要用在低价值的静态内容防护上。
原因:防火墙会降低可用性并引起不必要的可扩展性瓶颈
要点:防火墙虽然有用,但常被滥用,设计和实施不当会带来可用性和可扩展性问题。
风险降低:中
成本:低
利益和优先级:高/2
16.积极使用日志文件
内容:使用日志文件来诊断和预防问题。
场景:制订监控日志文件的过程,迫使人们对发现的问题采取行动。
用法:使用任何监控工具,从自定义脚本到Splunk或者ELK框架,监视应用日志中的错误,导出这些错误信息,然后安排资源去确定和解决问题。
原因:日志文件是有关应用执行的绝好信息来源,不要轻易放弃
要点:若充分利用好日志文件,生产问题将越来越少,且当问题出现时可迅速定位解决。
风险降低:低
成本:低
利益和优先级:中/3
17.避免画蛇添足
内容:避免翻来覆去的检查刚完成的工作或马上读取刚写的数据。
场景:总是。
用法:避免为了确认操作是否有效而读取刚写入的数据,如近期处理需要,可把数据存储在本地或分布式缓存
原因:与不太可能出现的操作失败所产生的成本相比,确认操作成本更高。而且这类活动与有效扩展相背离。
要点:永远不要为确认操作是否有效而读取刚刚写入的数据,相信持久层会对写入的相关数据出现无法读取或操作失败时发出通知。通过把数据存储在本地而避免对近期写入的数据进行其他类型的读操作。
风险降低:低
成本:中
利益和优先级:低/4
18.停止重定向
内容:如有可能,避免重定向;确实需要时采用正确的方法。
场景:总是。
用法:如需重定向,考虑通过服务器配置来实现,而不是利用HTML或者其他基于代码的解决方案。
原因:总体来说重定向会延迟用户进程,消耗计算资源,造成错误,不利于页面在搜索引擎中的排名
要点:正确而且仅在必要时使用重定向。
风险降低:低
成本:低
利益和优先级:中/3
19.放宽时间约束
内容:尽可能放宽系统中的时间约束。
场景:当考虑在用户操作步骤之间,某些项目或者对象必须保持某种状态的时间约束时。
用法:放宽业务规则的约束
原因:因为大多数关系型数据库的ACID属性,要扩展带有时间约束的系统难度极高
要点:认真考虑诸如某个产品从用户查看开始,到购买为止的时间约束的必要性。与让用户有些失望相比,系统因无法扩展而停止服务相比更为严重。
风险降低:高
成本:低
利益和优先级:非常高/1
20.利用CDN缓存
内容:利用CDN(内容分发网络)来减少网站的负载。
场景:速度提升和扩展性水平的提高可以平衡额外的成本。
用法:大多数CDN借助DNS为网站提供内容。因此可能需要在DNS上做些小改动或者添加记录,以便把提供内容的网址迁移到新的子域名上。
原因:CDN有助于平缓流量高峰,而且常常是网站部分流量扩展比较经济的方法。常用于改善网页下载时间。
要点:CDN是快速而且简单的平缓高峰流量和一般流量增长的方式。确保进行成本效益分析,同时监控CDN的使用量。
风险降低:中
成本:中
利益和优先级:中/3
21.灵活管理缓存
内容:使用Expires头来减少请求量,提高系统的可扩展性和性能。
场景:所有的对象类型都需要考虑。
用法:可以通过应用代码在网络服务器上设置头字节。
原因:减少对象请求可提高用户页面性能并减少系统处理的单用户请求数。
要点:对每类对象(图片、HTML、CSS、PHP等)根据目标可缓存时间安排最合适其时间长度的头字节。
风险降低:低
成本:低
利益和优先级:中/3
22.利用Ajax缓存
内容:适当使用HTTP响应头以确保Ajax调用可以缓存
场景:除了因为数据刚更新过,所以绝对需要实时数据以外的任何Ajax调用。
用法:适当调整Last—Modified、Cache—Control和Expire头
原因:减少用户可感知的响应时间,增加用户满意度,提高平台或方案的可扩展性。
要点:尽量利用Ajax和缓存Ajax调用以提高用户满意度及可扩展性
风险降低:中
成本:低
利益和优先级:高/2
23.利用页面缓存
内容:在网络服务的前端部署页面缓存。
场景:总是。
用法:选择缓存的解决方案然后在部署
原因:通过缓存和分发以前产生的动态请求降低网络负载,快速响应静态对象请求
要点:页面缓存是减少动态请求的好办法,可以减少客户响应时间,以成本效益方式扩展。
风险降低:中
成本:中
利益和优先级:中/3
24.利用应用缓存
内容:使用应用缓存以成本效益方式扩展。
场景:当需要提高可扩展性和降低成本的时候。
用法:要最大化应用缓存的影响,首先分析如何拆分架构。
原因:应用缓存提供了以成本效益方式扩展的能力,但是应该与系统架构互补。
要点:在实施应用缓存,从成本和可扩展性角度看取得最大效果之前,应该考虑如何沿Y轴或者Z轴拆分应用
风险降低:中
成本:中
利益和优先级:中/3
25.利用对象缓存
内容:实现对象缓存以帮助扩展持久层。
场景:任何有重复查询或计算的时候。
用法:选择任何开源或者有供应商支持的解决方案和在应用代码中实现。
原因:实施相当简单的对象缓存可以节省大量应用或数据库服务器上的计算资源。
要点:在任何重复计算的场合考虑实施对象缓存,但主要在数据库和应用层之间
风险降低:高
成本:低
利益和优先级:非常高/1
26.独立对象缓存
内容:在架构中采用单独的对象缓存层。
场景:任何实施对象缓存的时候。
用法:将对象缓存移到自己的服务器上。
原因:对象缓存层独立的好处是可以更好的利用内存和CPU资源,并且具备可以在其它层之外对立扩展对象缓存的能力
要点:在实施对象缓存时,把服务配置在现有层如应用服务器上很简单。考虑把对象缓存实施或迁移到自己的层上,以便取得更好的性能和可扩展性
风险降低:中
成本:低
利益和优先级:高/2
27.失败乃成功之母
内容:抓住每个机会尤其是失败的机会,学习经验并吸收教训。
场景:不断的从错误和成功中学习。
用法:观察客户或用A/B测试验证,建立事后分析过程,在低故障率条件下采用假设失败的方法。
原因:做事情不考虑结果或发生事故而没用从中吸取教训,都会错失良机,从而让竞争对手乘机占便宜,最好的经验来自失败中的错误而不是成功
要点:要不断的努力学习。学习的最好最快和最频繁的是那些增长最快并且最具可扩展的公司。千万不要浪费失败的机会。抓住每个机会学习,发现架构、人和过程中需要纠正的问题。
风险降低:中
成本:低
利益和优先级:高/2
28.不靠QA发现错误
内容:利用QA减低产品交付成本,提高技术吞吐量,发现质量趋势,减少缺陷,但不提高质量。
场景:任何可能的机会下,通过专人聚焦测试而不是写代码以提高效率,利用QA从过去的错误中学习。
用法:每当测试活动获得超过一个工程师的价值输出时,就雇佣一个QA人员。
原因:降低成本,加快交付速度,减少缺陷重复
要点:因为系统质量无法测试,所以QA并不会提高质量,如果使用得当,可以提高生产力,同时降低成本,最重要的是,可以避免缺陷率的增长速度超过快速雇佣期间的组织增长率
风险降低:中
成本:低
利益和优先级:高/2
29.不能回滚注定失败
内容:必须具备代码回滚的能力。
场景:确保所有版本的代码都有回滚能力,在准生产挥着QA环境演练,必要时在生产环境用它来解决客户的问题。
用法:清理代码并遵循几个简单的步骤以确保可以回滚代码。
原因:如果没有经历过无法回滚代码的痛,还继续冒险地“修改-发布”代码,那么你可能会在某个时刻体会到这种痛。
要点:应用过于复杂或者代码发布太频繁所以不能回滚,这个接口无法接受。稳健的飞行员不会再飞机不能着陆时起飞,明智的工程师不会发布不能晋级回滚的代码。
风险降低:高
成本:低
利益和优先级:非常高/1
30.从事务处理中清除商务智能
内容:业务系统与产品系统分离、产品智能与数据库系统分离。
场景:任何考虑公司内部需求和将数据转入、转出或在产品之间转换的时候。
用法:把存储过程从数据库迁移到应用逻辑。在公司和产品系统之间不做同步调用。
原因:把应用逻辑放在数据库中是昂贵的而且会影响可扩展性。把公司系统和产品系统棒子一起也是昂贵的,同样会影响可扩展性并带来可用性问题。
要点:由于许可证和独特的系统特性,扩展数据库和公司内部系统的成本可能很高。因此我们希望它们用用于特定的任务。对于数据库,希望它是专用于事务处理,而不是产品智能。对于后台办公系统(BI)不希望产品系统与这些系统的扩展能力挂钩。采用异步方法向这些业务系统传输数据。
风险降低:高
成本:中
利益和优先级:高/2
31.正确使用数据库锁
内容:理解如何使用明锁和监控暗锁。
场景:每次采用关系数据库作为解决方案时。
用法:在代码审查时注意明锁。监控数据库暗锁,并在必要时进行明确调整以保证适度的吞吐量。选择允许锁类型和力度灵活性的数据与存储引擎。
原因:最大化数据库的并发性和吞吐量。
要点:理解锁类型并且管理其使用情况,以使数据库吞吐量和并发性最大化。改变锁类型,以便更好的使用数据库,并在成长中拆分数据结构或数据库。确保选择多种锁类型和粒度的数据库,已达到最大的并发量。
风险降低:高
成本:低
利益和优先级:非常高/1
32.禁用分阶段提交
内容:不要使用分阶段提交协议来存储或处理事务。
场景:总是传递或从不使用分阶段提交。
用法:不用;采用Y轴或Z轴拆分数据存储和处理系统。
原因:分阶段提交是一个阻塞协议,它不允许其他事务处理直至完成。
要点:不要使用分阶段提交协议作为延长单体数据库生命的简单方法。这可能不利于扩展甚至会导致系统更早消亡。
风险降低:中
成本:低
利益和优先级:高/2
33.避免选择所有列
内容:不要在查询中使用select *。
场景:总是,也就是永远不要选择所有列。
用法:始终在查询语句中声明你要选择或插入数据的列。
原因:当表结构发生变化时,查询语句中选择的所有列容易产生故障,从而传送不必要的数据。
要点:在选择或插入数据时不要使用通配符。
风险降低:高
成本:低
利益和优先级:非常高/1
34.拒绝单点故障
内容:永远不要实施会带有单点故障的设计,一直要消除单点故障。
场景:在架构审查和新系统设计时。
用法:在架构图上寻找单个实例。尽最大可能配置成主动/主动模式。
原因:通过多实例配置足底啊化可用性。
要点:使用负载均衡器在服务的不同实例之间实现流量平衡。
风险降低:高
成本:中
利益和优先级:高/2
35.使用分布式缓存处理状态
内容:使用分布式缓存在系统中存储会话数据。
场景:任何需要存储会话数据但又不能在用户的浏览器上存储的情况
用法:注意一些常见错误,如需要用户对web服务器黏性的会话管理系统。
原因:仔细考虑如何存储会话数据以帮助确保系统可以继续扩展。
要点:许多web服务器或语言提供基于服务器的简单会话管理,但这一般有问题,如用户与特定服务器的黏性。实现分布式缓存允许在系统中存储会话数据和继续扩展。
风险降低:中
成本:低
利益和优先级:高/2
36.尽可能异步通信
内容:尽可能优先考虑异步通信而不是同步通信。
场景:考虑在服务与层之间的所有调用尽可能异步实现。特别是所有非关键请求
用法:注意一些常见错误,如需要用户对web服务器黏性的会话管理系统。
原因:仔细考虑如何存储会话数据以帮助确保系统可以继续扩展。
要点:许多web服务器或语言提供基于服务器的简单会话管理,但这一般有问题,如用户与特定服务器的黏性。实现分布式缓存允许在系统中存储会话数据和继续扩展。
风险降低:中
成本:低
利益和优先级:高/2
37.警惕第三方方案
内容:扩展自己的系统;不要依赖第三方供应商的解决方案来实现可扩展性。
场景:每当考虑是否使用来自供应商的新功能或产品时。
用法:尽可能用最简单的方式使用供应商提供的产品或服务。
原因:遵循这条规则有三个理由:掌握自己的命运,保持架构简单,降低总的成本。要知道是客户(而不是供应商)要你对产品的可扩展性和可用性负责。
要点:不要依赖供应商的产品、服务或系统功能来扩展。保持架构简单,把命运掌握在自己手里,控制住成本。如果依赖供应商的专有扩展解决方案,那么有可能违反所有这三个规则
风险降低:高
成本:低
利益和优先级:非常高/1
38.分类处理不同负载
内容:通过分区和故障隔离,处理独特的工作负载,以最大的限度提高整体可用性、可扩展性和成本效益。
场景:每当架构中包含分析(归纳或演绎)和产品(批处理或用户交互)解决方案时。
用法:确保解决方案支持四种基本类型的工作负载(归纳、演绎、批处理和用户交互/OLTP)而且彼此故障隔离,每种都存在于自己的故障隔离区。
原因:每种工作负载到有独特的需求和可用性要求。另外,每种都会影响其他的可用性和响应时间。通过把这些工作隔离在不同故障隔离区,可以确保彼此不冲突,而且每个都可以有自己的架构,并以经济实惠的方式满足其独特的需求。
要点:归纳是从数据中形成假设的过程。演绎是对数据进行假设检验以确定有效性的过程。归纳和演绎解决方案应分离以获得最佳性能和可用性。
风险降低:高
成本:中
利益和优先级:高/2
39.保持竞争力
内容:让架构的每个组成部分都有竞争力或认同竞争力。
场景:任何在线交付的解决方案。
用法:对产品的每个组件,确定团队的责任和该组件的竞争力水平。
原因:对客户而言,每个问题都是你的责任。不能怨供应商。你提供的是服务,而非软件。
要点:不要把竞争力与自建还是购买或核心还是外围的决策混淆。可以购买解决方案,但必须在部署和维护时保持竞争力。事实上,这是客户要求这样的。
风险降低:高
成本:低
利益和优先级:非常高/1