1.按功能切分
根据功能切分应用,减低功能之间的耦合度。可以根据某个功能消耗对单个功能进行伸缩。
2.水平切分
随着访问量的增加,单项功能就出现资源瓶颈时,这是需要采用增加服务器的方式,让负载均衡器将请求分摊到每个服务器上。
前提是应用都是无状态的,便于水平切分。但数据库天生是有状态的,常用的切分方式是根据userId进行hash,或者采用userId分区,或者采用中间查询表的方式。
3.避免分布式事务
分布式系统的三项重要指标—— 一致性(Consistency)、可用性(Availability)和 分区耐受性(Partition-tolerance)——在任意时刻,只有两项能同时成立。对于高流量的网站来说,我们必须选择分区耐受性,因为它是实 现可伸缩的根本。对于24x7运行的网站,选择可用性也是理所当然的。于是只好放弃即时一致性(immediate consistency)。
分布式事务可以保证即时一致性,但成本太高,应该避免使用。分区耐受性是伸缩性的根本。
当然我们也采用了一些技术来帮助系统达到最终的一致性(eventual consistency):周密调整数据库操作的次序、异步恢复事件,以及数据核对(reconciliation)或者集中决算(settlement batches)。具体选择哪种技术要根据特定用例对一致性的需求来决定。
4.异步策略解耦应用
如果应用A同步调用应用B,那么伸缩A时,B也需要一起伸缩。若B不可用,则A也不可用。如果反过来A和B的联系是异步的,不管是通过队列、多播消息、批处理还是什么其他手段,它们就可以分别地伸缩。而且,此 时A和B的可用性特征是相互独立的——即使B受困或者死掉,A仍然能够继续前进。
5.将过程分解成异步执行的流
对于网站或者交易系统, 牺牲数据或执行的延迟时间(完成全部工作的实践)来换取用户的延迟时间(用户得到响应的时间)是值得的。活动跟踪、单据开付、决算和报表等处理过程显然都 应该属于后台活动。主要用例过程中常常有很多步骤可以进一部分解成异步运行。任何可以晚点再做的事情都应该晚点再做。
6.适当地使用缓存
缓存只用于存放变更频率低,以读为主的数据。减少对相同数据的重复请求能达到非常显著的效果。如果网站的可用性取决于缓存能否100%可用,那么就存在潜在危险,尤其是在重新分配缓存资源,冷启动缓存等情况时。