文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏
参与翻译: CY2 (8)

GitHub Pages 是一个静态的网站托管服务,使用非常简单的架构。服务从推出到 2015 年初,服务一直使用结对服务器运行(主从服务器配置),所有用户数据存储在 8 个 DRBD 后端分区中。每 30 分钟运行一个 cron 作业来生成一个 nginx map file ,用于映射主机名到磁盘路径。

这个方法有一些问题:新的 Pages 网站在 map 生成之前不能访问(时间可能需要近 30 分钟);nginx 冷重启会花很多时间从磁盘上加载 map 文件;此外我们的存储能力被限制在单机器的 SSD 容量上。

第 1 段(可获 2 积分)

尽管存在这些问题,这个简单的架构还是运行非常良好 —— 就算是 Pages 的服务负载提升到每秒数千请求,有五十几万的网站使用的情况下也如此。

当我们开始研究如何尽量接近机器的存储容量限制并思考重新架构后的 Github Pages 是怎么样的时候,我们必须一致的是之前的架构工作良好这一点 —— 使用简单组件,避免过度去接近一些尚未发生的问题。

全新架构

第 2 段(可获 2 积分)

新的 Pages 架构已经从 2015年1月开始在生产环境中使用,我想是时候分享一下它的工作方式。

architecture diagram

前端架构

当请求通过我们前端的负载均衡系统后被送到 Pages 服务。此服务层使用一些运行着 Nginx 的 DELL C5220s 服务器。模块 ngx_lua 负责处理请求并决定将其转发到具体某台文件服务器上。这涉及到通过 MySQL 的读副本查找对应的后端存储服务器并转发到对应服务器进行进一步处理。

第 3 段(可获 2 积分)

一旦我们的 Lua 路由做出一个路由决策,只需要使用 nginx 的 proxy_pass 指令将请求转发到后端的文件服务器。这是 Nginx 集成了 ngx_lua 的真正闪光点,我们产品环境的 nginx 配置再复杂也不过如此:

location / {
  set $gh_pages_host "";
  set $gh_pages_path "";

  access_by_lua_file /data/pages-lua/router.lua;

  proxy_set_header X-GitHub-Pages-Root $gh_pages_path;
  proxy_pass http://$gh_pages_host$request_uri;
}

我们关注的一个主要点是从 MySQL 查询路由信息,这就依赖了 MySQL 数据库本身的可用性。也就是说如果 MySQL 集群宕机,Github Pages 也会无法使用。对外部网络调用的依赖也增加了额外故障模式 —— 网络上执行 MySQL 查询失败的原因也很多,而一个简单的内存哈希表查询就不会。

第 4 段(可获 2 积分)

这是我们能接受的最终权衡结果,但我们有一些在出问题时减少用户影响的缓解措施。如果路由在做查询过程中发生问题,它会重试几次连接到不同的读数据库上进行查询。我们也使用了 ngx_lua 的 shared memory zones 来在 pages-fe 节点中缓存路由信息,缓存时间是 30 秒,来降低 MySQL 架构上的负载,也让我们的容错性更好一些。

如果我们正在查询度副本,那么 MySQL 主服务器的故障就对该模块没有影响。这表明 Pages 在数据库维护窗口期仍然是可用的。

第 5 段(可获 2 积分)

在 Github Pages 前面我们还有一些其他的系统来缓存所有 200 个响应信息。这也最小化 Pages 路由模块故障导致的宕机。在最坏的情况下,被缓存的 Pages 网站仍然可以访问,不受影响。

文件服务器端

文件服务器端使用一组主从配置的 DELL R720s 服务器运行。每对服务器非常类似之前老的 Pages 架构中的单对服务器。事实上,我们甚至能够重用大部分旧的 Pages 系统的机构、工具以及配置。这块的变化不大。

第 6 段(可获 2 积分)

我们使用 DRBD 去在两台结对机器上同步 Pages 的网站数据。DRBD 让我们从主服务器到从服务器同步的复制所有文件的变更,以确保每个从服务器的数据都是最新的,并随时可以在主服务器崩溃或者维护时接管主服务器的工作。

我们同时在文件服务器上运行一个非常简单的 nginx 配置,我们所要做的只是设置文档根目录到 $http_x_github_pages_root (当然还要做一些简单的验证以阻止任何路径遍历的尝试)即可。

第 7 段(可获 2 积分)

结束

现在我们不仅可以水平的扩展存储端,而且因为 MySQL 的路由表确保数据的不断更新,新的 Pages 网站会立即发布,而不像之前的需要 30 分钟的时间。这对我们的用户来说是一个巨大的进步。而且 Nginx 在启动的时候不再需要加载一个巨大的预先生成的 map 文件,这意味着老架构中的冷启动问题不再存在。

response times

同时我们对 ngx_lua 的工作也非常满意。其性能是非常好的 —— 在 Lua 中 98%的请求的处理时间小于 3 毫秒(包括外部的网络调用),每小时可以处理数以百万级的 HTTP 请求。其允许在 Nginx 请求生命周期中嵌入代码的特性,意味着我们可以利用 Nginx 坚如磐石的 proxy 功能,而不是再造一个轮子。

第 8 段(可获 2 积分)

文章评论

CY2
其实说到底新架构就是增加了 MySQL 路由表