提升可伸缩性的8项最佳实践
提升可伸缩性的 8 项最佳实践
Wille Faler 曾提出 八项提升系统可伸缩性和性能的最佳实践,核心观点包括减少数据库操作、合理使用缓存、降低网络通信开销等。以下是这八项实践的详细解读。
1. 减少数据库操作
尽可能远离数据库。如无必要,不要打开数据库连接或者启动事务。数据库交互通常是系统性能的瓶颈,减少交互次数能显著提升效率。
2. 缓存带来的显著变化
缓存能极大地减轻数据库的负担,特别是当系统通过只读方式访问数据库时。缓存层级的一般优选顺序为:内存缓存优于磁盘缓存,而磁盘缓存又优于远程缓存和关系型数据库。
3. 尽可能缓存粗粒度对象
缓存粗粒度对象“可以省去遍历 N 个缓存单元的 CPU 开销和时间。而且,获得完整的对象关系图也省去了对象关系图的装配时间。”这意味着在缓存设计时,应优先考虑存储聚合后的数据而非细碎的单个字段。
4. 不要永久性保存瞬态信息
避免在数据库里面存储瞬态数据,比如登录的会话信息(Session)。
“状态怪物”是一只非常危险的怪兽。根据一般的规律,在持久性存储设施(数据库、磁盘等)里面只需要保存真实的、必要的、关键的,以及需要备录的业务数据,其他的都不在此列。
5. 位置、位置(Location, Location, Location)
把数据放在靠近需要使用它们的地方。相对于经过负载均衡器、Web 服务器、应用服务器和数据库多个环节,直接经过负载均衡器和 Web 服务器从 CDN 获取数据要快一些,开销也更小。就近原则是降低延迟的关键。
6. 约束对有限资源的并发访问
如果多个请求需要访问同样的资源,执行同样的计算,最好是只处理首个请求,让其他的请求等待计算完成后直接使用最终结果。让所有的线程去访问同一个资源只会减缓处理的速度。这种模式常用于防止缓存击穿或重复计算。
7. 分阶段地、异步地处理
根据处理过程的异步性,把该过程分散成单独的步骤,通过队列来隔离;每个步骤使用有限数量的工人线程进行处理:这样经常会给可伸缩性和性能同时带来奇迹般的变化。
通过引入消息队列和解耦步骤,系统可以更好地应对流量峰值。
8. 使网络延迟最小
尽可能使应用系统不去做远程访问,因为网络通信要明显慢于内存访问。本地调用永远快于远程过程调用(RPC)。
社区讨论与补充
针对上述实践,社区专家也提出了一些补充观点:
关于减少数据库操作:Steve M. Ciske 对减少数据库操作的做法表示了忧虑:
对于减少数据库操作的做法,我持谨慎态度。我见多了人们走向另一个极端,把所有的东西都放在应用层。
关于缓存层级:Paweł Stradomski 认为远程内存缓存要快于本地磁盘缓存,Faler 也表示了同意:
远程主机(通过网络连接)缓存可能会快于本地磁盘缓存。如果不考虑网络查找的时间,从磁盘顺序读取数据比从远程主机的内存里面读取数据要慢三倍。
延伸阅读
- Simon Brown 的文章"可伸缩性原则"。
- 查看英文原文:8 Best Practices to Improve Scalability
说明:本文引用的最佳实践最初发布于 2009 年。虽然核心架构原则(如缓存、异步、就近访问)至今仍具有指导意义,但具体的技术实现细节(如缓存工具、数据库类型、网络环境)可能已随技术发展而演变,请结合当前技术栈酌情参考。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/ti-sheng-ke-shen-suo-xing-de-8-xiang-zui-jia-shi-jian.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。