之前已经提过通过 Varnish 缓存进行网站性能优化,以及延迟对商业的影响

经历过太多这样的问题分析和定位过程:

  • 某大型网站的 Redis 集群的机器负载每几十分钟出现一个超越平时几十倍大的高峰,结果是因为这些实例每几十分钟对所有数据进行写盘持久化。
  • 某大型媒体网站的 MySQL 读流量异常大,结果是因为每个读操作都携带了 2MB 的页面初始化信息。这个 BUG 修正的直接结果不仅仅是降低了数据库的访问压力,而且是访问延迟直接降低了 75%,另外应用服务器的负载也降低很多,节省了服务器。



还有很多类似的故事。

这些故事看起来可笑,但是发生的原因并不可笑。大部分线上系统都会存在类似的问题。

一方面,所有公司都在大量使用开源软件类库,某些类库并不一定针对大流量设计。另一方面,每个运维和开发人员都难以面面俱到。而且,现在互联网应用越来越复杂,发现问题都非常难。

这种问题自底向上分析是难以避免的,也难以发现,所以应用性能优化需要自顶向下分析,从监控表现入手,寻找线索,进而定位问题。

当然应用整体性能监控、优化,运行成本的降低和把控本身是架构师的主要任务之一。

互联网应用性能优化 (APO, Application Performance Optimization) 有两个大的方向可以做:

1. 应用本身的 BUG 和不合理的地方

无论网站还是移动应用 API,或者是实时通讯和聊天系统,本质上都是用户通过 HTTP 和其他 TCP 协议交互信息的过程。

所以,其中大部分模式都是相通的,并且可以重复利用。比如一些常见的思路和技术:负载均衡、缓存、索引、命名系统、连接重用等等。

随着流量的变化,引起的延迟变化或者机器负载变化,有经验的架构师或者运维基本心里有数。通过对商业模式的分析,相对应的在线业务系统应该有的延迟、服务器压力等等数据可以从心里估算出大致的范围。结合此业务系统的监控图表,基本可以很快看出不合理的地方。然后从一个线索入手定位问题所在,进行修复。

2. 应用业务之外的架构层次的修改

假如不考虑程序的 BUG 或者代码本身的优化,在这之上的一个层次也可以有很多可以优化的方向。

这里主要说明一个利用 最终一致性 的思路修改缓存系统对网页延迟的优化。

Varnish 4.0 增加了一个新功能:

Background (re)fetch of expired objects. On a cache miss where a stale copy is available, serve the client the stale copy while fetching an updated copy from the backend in the background.

假如 cache miss,立刻返回给用户一个之前的旧版本缓存,然后再从应用服务器请求新的版本。这意味着如果缓存足够大,可以让用户 100% 访问到 Varnish 服务器上缓存的版本,而跳过后端服务器的延迟。这也是为什么标题写着降低到 0ms :-) 有点标题党了。

具体的实现方式:

  1. 保证缓存存储足够大
  2. 保证 Grace 时间足够长(无限长)
  3. 假如 obj.ttl + obj.grace > 0s 则返回缓存,否则访问后端服务器。

这样离保证用户 100 % 命中缓存还差一步,就是缓存的预热。为了避免第一个用户访问后端服务器,我们通过主动抓取的方式,或者叫做缓存推送的方式进行缓存的预热。方式很简单,逐个向每个 Varnish 实例请求网站的所有 URL。另外,新生成的 URL,首先进行预热。

需要注意的是,这种方式只适合于用户对信息新旧不是非常敏感的场景,比如所有的媒体页面,说明页面,电商网站的产品说明页面,移动应用的 Feed API (跳出 Varnish,应用类似思路)。另外,这个方案适用于所有需要针对搜索引擎 SEO 进行延迟优化的场景。

注册 DigitalOcean 1G 内存, 30GB SSD 硬盘 VPS, 获取 10 美元折扣

相关链接:
https://www.varnish-cache.org/content/varnish-cache-400

推荐这些相关文章

订阅这个博客:

关注我的微博:

关注我的推特: