我们如何让 Github 快速运行 已翻译 100%

oschina 投递于 2015/02/17 15:39 (共 16 段, 翻译完成于 03-03)
阅读 2391
收藏 10
1
加载中

既然现在迁移到Rackspace的事情已经结束,我想花点时间回顾下为给您带来速度更快、扩展性更强的Github,我们在架构上做的些改变。

在本文的第一稿里,我花了很多时间解释我们作每个技术的选择的原因。然而此后,从话语中将架构分离出来变得很困难,并且整个事情都变得令人困惑。所以我决定简单的解释架构,然后写一系列后续的帖子中更加详细的分析为什么我们做这样的选择。

我们有许多方法来衡量现代的 Web 应用程序。我将在此讲述我们选择的方法。这绝不应该是衡量一个程序的唯一途径。而把它当做基于我们独特需求的为我们所需的案例研究。

开源中国首席扫地僧
翻译于 2015/02/21 15:11
2

理解协议

我们暴露三个基本协议给Github终端用户: HTTP, SSH, 和 Git。 当你用你喜欢的浏览器浏览网站时, 你正在使用HTTP. 当你clone, pull, 或者 push 到一个私有 URL 时,比如git@github.com:mojombo/jekyll.git ,你正在通过SSH来实现这些。 当你从一个公开的仓库通过一个URL比如 git://github.com/mojombo/jekyll.git 来 clone 或者 pull 的时候,你正在使用 Git 协议。

理解它的构架最简单的方法是通过跟踪每一个请求是如何通过系统传送的。

跟踪一个 HTTP 请求

在这个例子中我会向你展示一个页面树的请求,例如http://github.com/mojombo/jekyll,是如何发生的。 

独孤影
翻译于 2015/02/21 11:47
3

当你从网络访问我们的服务,请求首先到达的是负载均衡服务器。对于负载均衡我们使用一对跑着ldirectord的 Xen 虚拟机实例,我们称之为 lb1a,lb1b。在任意时刻,其中主实例保持激活状态,当主实例故障从实例随时接替主实例的工作.负载均衡器不仅可以根据IP和端口号将请求定向到各种服务器,必要的时候还可以从负载均衡池中删除操作异常的服务器.当对指定的池没有对应的服务器在工作,则定向到一个简单的静态网站,而不是拒绝链接。

对主网站的访问将被负载均衡器分发到四个前端服务器.这四个服务器每个都是8核 16G内存的物理主机,命名为 fe1 ... fe4。Nginx 接受到请求链接后发送给 16 个进程的 Unicorn 守护进程.其中的一个进程获取请求后执行相应的 Rails 代码处理这个请求。

Yashin
翻译于 2015/03/01 15:46
2

许多页面需要查询数据库.我们的MySQL数据库运行在一个双八核处理器、32GB内存和15k RPM SAS硬盘的服务器上.它们的名字分别是da1a和db1b.在任意特定的时间内,其中的一个硬盘将作为主盘而另一个将作为从盘.MySQL的逻辑复制是通过DRBD(Distributed Replicated Block Device)完成的.

如果页面请求的信息是一个Git 仓库同时这些数据又没有被缓存,那么它就会用到Grit library去重新请求这些信息.为了适应Rackspace的环境,我们还改写了Grit从而实现一些新功能.我们尝试配对每一个需要登陆Grit::Git项目文件系统的请求,当我们把Grit::Git作为存根时就可以让RPC calls(远程过程调用)更配合Smoke服务.Smoke服务可以让磁盘访问这些存放,从而根本上把显示Grit::Git作为服务.它被叫做Smoke只是因为Grit是运行在云端的,懂了吗?

我的滑板鞋不时尚
翻译于 2015/02/24 11:34
2

被存放的 Grit 发起 RPC 请求到 smoke ,smoke 是一个负载均衡映射到前端服务器的主机名。每一个前端服务器运行四个 HAProxy 之下的 ProxyMachine 实例,这个实例是 Smoke 服务请求的代理。ProxyMachine 是可编写 Ruby 逻辑代码的内容意识 TCP 路由代理。这个代理检查请求并获取指定仓库的用户名。我们使用一个叫做 Chimney 的专有库去为用户路由。一个用户的路由是用户的仓库存放所在的文件服务器的主机名。

Chimney 通过访问 Redis 查找路由。Redis 运行在数据库服务器中。我们使用 Redis 的键值存储来保存路由信息和数据的变化。 

Yashin
翻译于 2015/03/01 18:29
2

一旦 Smoke 代理判断好了用户的路由,它就建立一个透明的代理到对应的文件服务器上.我们有四对分别为8核 16G,六个 300G 15K RPM 的磁盘做 RAID 10 的文件服务器,命名为:fs1a,fs1b....fs4a,fs4b。每一对服务器有一台主服务器一台备用服务器,任何时间当主服务器出现问题备用服务器可以接替它的工作。通过使用DRBD,所有的仓库数据实时地从主服务器同步到备用服务器中。

每个文件服务器运行着两个 Ernie RPC 服务,每个 Ernie 产生 15 个 Ruby 进程。这些进程将发起 RPC 重新建立 Grit 请求。Grit 的响应将由 Smoke 代理被发送回 Rails 程序中。

Yashin
翻译于 2015/03/01 16:47
1

当 Unicorn 处理完 Rails action,这个响应将通过 Nginx 直接返回到客户端(响应返回不经过负载均衡)。

最后,你将看到一个完整的网页。

上诉流程是发生在没有缓存命中的情况下.在很多案例中Rails 代码使用  Evan Weaver 的Ruby memcached 客户端去访问运行在备用文件服务器的 Memcache 服务.因为这些机器是闲置的,所以我们开启了 12G Memcache。这些服务的别名是:memcache1, …, memcache4。

Yashin
翻译于 2015/03/01 16:57
1

BERT 和 BERT-RPC

对于我们的数据序列化以及 RPC 协议,我们使用的是 BERT 和 BERT-RPC。你可能没听说过他们,因为他们是新研发的。我研发这个两个产品是因为我评估过的相关产品找不到满意的选择,并且我想去实际思考了一段时间的想法.在你对此感到崩溃之前,不妨读读我的文章: Introducing BERTand BERT-RPC ,这是关于这些技术怎么来的,以及我打算怎么去实现。

如果你只是打算看一下说明,请访问:http://bert-rpc.org

如果对代码感兴趣,可以查看我的 Ruby BERT 序列化库 BERT,我的 Ruby BERT-RPC 客户端 BERTRPC, 以及我的 Erlang/Ruby 混合 BERT-RPC 服务程序 Ernie.。这些都是GitHub代码托管仓库使用的库。

Yashin
翻译于 2015/03/01 17:37
1

跟踪 SSH 请求

Git 使用SSH来加密你和服务器之间的通信。为了理解我们的架构是怎样处理SSH连接的,首要的是知道在更简单的设置中这个怎么工作。

Git依赖SSH允许你在远程服务器上执行命令这个特性。例如,命令 ssh tom@frost ls -al   在我的用户在forst服务器上的home目录运行ls -al。在本地得到这个命令的输出,SSH 本质上是把远程机器的STDIN、STDOUT以及 STDERR 连接到本地终端。

liuqiangchengdu
翻译于 2015/02/28 15:49
2

如果你运行一个命令:git clone tom@frost:mojombo/bert,在这个场景下,Git 所做的是,用 SSH 方式链接到 frost 主机,认证 tom 用户,以及在远程执行 git upload-pack mojombo/bert。现在你的客户端就可以用SSH的方式读写访问远程Git服务了。很便捷是吧。

当然,允许任意地执行命令是不安全的,所以 SSH 包含了限制什么命令可以执行的能力。一个非常简单的例子,你可以限制执行命令到Git所包含的 git-shell。所有这些脚本将检查确保你尝试执行的命令是以下之一:git upload-paack, git receive-pack , git upload-archive 。如果是以上之一,可以使用exec 来使新的进程代替当前进程。就犹如你直接执行了这个命令。

Yashin
翻译于 2015/03/01 18:50
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(4)

Yashin
Yashin
Yashin
Yashin

引用来自“红薯”的评论

@oscfox 这篇文章必看,咱们翻译一下吧
这文章我看过,先让咱们会员发挥吧,手机翻译很不方便
开源中国首席扫地僧
开源中国首席扫地僧

引用来自“红薯”的评论

@oscfox 这篇文章必看,咱们翻译一下吧
@红薯 我试着翻译了第一段。
红薯
红薯
@oscfox 这篇文章必看,咱们翻译一下吧
返回顶部
顶部