25 July 2014

读《构建高性能 Web 网站》时,我把缓存、负载均衡和数据库扩展看成一条请求链路上的不同选择。它们解决的问题不同,只有先定位瓶颈,才知道该在哪一层投入。

先画出请求经过什么

浏览器 -> DNS/入口 -> 反向代理 -> 应用 -> 缓存或数据库

每一层都可能增加等待。记录请求量、延迟分位数、错误率和资源占用,区分是慢查询、连接池等待、CPU 计算还是网络传输。平均延迟下降,也可能掩盖少量请求越来越慢。

几种负载均衡各有边界

方式 调度发生在哪里 需要关注什么
HTTP 重定向 服务端返回新地址,客户端再次请求 额外往返、客户端行为与目标可达性
DNS 多地址 名称解析时选择地址 缓存与 TTL、健康探测和失效传播
反向代理 代理选择后端并转发 超时、连接、TLS开销与代理自身冗余
四层调度 按连接或报文转发 连接状态、网络拓扑与回程路径

DNS 缓存减少了解析请求,但不代表 DNS 永远没有容量问题。内核转发也仍然受 CPU、包速率与连接状态等限制,不能只按带宽判断。NAT 不等于完整的访问控制,LVS-DR 与隧道模式还各有网络条件。

会话粘滞可以减少会话跳转,但 IP hash 不保证用户身份隔离,也不能解决节点故障后的状态恢复。会话共享、无状态化与粘滞选择,要按实际应用设计。

缓存需要考虑更新

缓存减少重复工作,同时引入过期、并发重建和数据陈旧问题。先确定事实来源,再决定更新或失效策略。静态资源可以用内容指纹配合缓存,个性化或授权数据则需要明确缓存键和共享范围。

数据库扩展改变的不只有容量

读写分离需要处理复制延迟和读后写一致性,副本不能替代备份。分库分表则影响唯一键、事务、关联与数据迁移;按时间拆分便于生命周期管理,按键分散负载则需处理热点和扩容。

不必一次引入所有机制。选一个瓶颈做可测量的调整,比较同等负载下的结果,并保留回退方式。性能优化的收益应该来自测量,而不是组件数量。

参考:Nginx HTTP 负载均衡。





blog comments powered by Disqus
Fork me on GitHub