归档:构建服务重定向器

跳转到:导航搜索
Icon-obsolete.png 本文关于开放构建服务的文档已过时!
您可以在 https://github.com/openSUSE/MirrorCache 上找到最新的信息

openSUSE 下载重定向器

历史

为了方便 openSUSE 的下载,第一个下载重定向器版本于 2005 年底开发完成,并在 2006 年的 FOSDEM 上展示。这个第一个概念验证并没有包含今天重定向器所具备的任何功能,该重定向器可以在 download.openSUSE.org 上访问。

重定向器的前两次迭代是用 PHP 编写的。它们被 (当前的) C 作为 Apache 模块的实现所取代。还有一个用 Ruby 编写的 prototype 实现,可以通过 FastCGI 集成,但是我们使用的是 Apache 模块。

后来,该项目成为一个独立的项目,现在可以在 http://mirrorbrain.org/ 上找到。

当前的实现是几位人士共同努力的结果。值得一提的人有 Jürgen Weigert 和 Martin Polster (scanner, mirrorprobe),Peter Poeml (mod_mirrorbrain, mirrorprobe),Marcus Rueckert (Ruby prototype)。当然,还有许多其他人也贡献了自己的意见,特别是 ,他实现了下载重定向器的前两次迭代。(这些不再使用,但当前的实现源于他们基本的的技术设计。)

它做什么?

download.openSUSE.org 的目标是提供自动且透明的镜像选择,根据每个用户的地理位置 (GeoIP) 和镜像性能,为他们提供最佳匹配。为了实现这一点,有一个完整的框架,形成了一种“镜像大脑”,它将镜像数据库作为每个镜像上每个文件的“状态缓存”。该数据库由镜像“扫描器”不断更新,该扫描器能够通过 ftp、http 和 rsync 爬取镜像。框架的另一个重要部分是监控,一个定期使用 HTTP 请求探测镜像的守护进程,以检查它们的在线状态 - 以确保随时提供正常重定向。这个框架的关键是重定向器本身,一个名为 mod_mirrorbrain 的 Apache 模块。它使用 MaxMind 的 GeoIP,一个将 IP 地址映射到国家和地区的免费数据库,以确定请求者的位置,然后查询镜像数据库以获取潜在镜像的列表,并选择最佳镜像。

大多数 openSUSE 下载 (download.opensuse.org, software.opensuse.org, ftp.opensuse.org) 都是通过这种方式处理的。有些不是 - 出于安全原因,某些文件 (如签名) 直接从 download.opensuse.org 传送。小文件是另一个例外,因为 HTTP 重定向的大小与直接传送小文件的大小相同,因此可以节省客户端的往返时间。此外,尚未在任何镜像上存在的文件,或不打算镜像的文件,将直接发送。总而言之,这些例外导致大约 50% 的请求被重定向到镜像。

有关技术实现以及背景文档的更多信息可以在 MirrorBrain 项目页面 上找到。

它是如何工作的?

镜像选择的方式可能最容易通过查看一些 伪代码 来理解。算法如下

do not redirect in certain cases:
    is this a request for a directory index?
    does the file exist?
    is the file too small?
    is the file excluded from being redirected by user agent / client IP / mime type / filemask?

canonicalize filename, resolving symlinks in the path

look up country and continent of client IP via GeoIP

if client country needs to be treated as another country:
    /* New Zealand case -- pick a mirror from Australia */
    client country = other country

mirrors =
   SELECT file_server.serverid, server.identifier, server.country, server.region, server.score, server.baseurl \
   FROM file \
   LEFT JOIN file_server \
   ON file.id = file_server.fileid \
   LEFT JOIN server \
   ON file_server.serverid = server.id \
   WHERE file.path=canonicalized_filename AND server.enabled=1 AND server.status_baseurl=1 AND server.score > 0

results example:
+----------+----------------------------+---------+--------+-------+---------------------------------------------------+
| serverid | identifier                 | country | region | score | baseurl                                           |
+----------+----------------------------+---------+--------+-------+---------------------------------------------------+
|       14 | ftp.ale.org                | us      | NA     |   100 | http://ftp.ale.org/pub/mirrors/opensuse/opensuse/ |
|       18 | ftp.fi.muni.cz             | cz      | EU     |    10 | http://ftp.fi.muni.cz/pub/linux/opensuse/         |
|       23 | ftp.iasi.roedu.net         | ro      | EU     |    10 | http://ftp.iasi.roedu.net/mirrors/opensuse.org/   |
|       41 | ftp.uni-heidelberg.de      | de      | EU     |   100 | http://download.uni-hd.de/ftp/pub/linux/opensuse/ |
|       44 | ftp5.gwdg.de               | de      | EU     |   200 | http://ftp5.gwdg.de/pub/opensuse/                 |
|       44 | ftp5.gwdg.de               | de      | EU     |   200 | http://ftp5.gwdg.de/pub/opensuse/                 |
|       70 | ftp.nux.ipb.pt             | pt      | EU     |    50 | http://ftp.nux.ipb.pt/pub/dists/opensuse/         |
|       74 | mirrors.uol.com.br         | br      | SA     |    50 | http://ftp.opensuse.org/pub/opensuse/             |
|       79 | ftp.halifax.rwth-aachen.de | de      | EU     |   100 | http://ftp.halifax.rwth-aachen.de/opensuse/       |
+----------+----------------------------+---------+--------+-------+---------------------------------------------------+

for mirror in mirrors:
    /* use the "score" to give each mirror a weighted randomized rank */
    mirror->rank = (rand()>>16) * ((RAND_MAX>>16) / mirror->score)

   if memcache daemon knows combination of this client ip and this mirror id: 
        /* client got this mirror before */
        chosen = mirror

    if country of client is same as mirror:
        put country into country pool
    else if continent of client is same as mirror:
        put country into region pool
    else
        put country into world pool

if country pool is not empty:
    chosen = find lowest ranked mirror(country pool)
else if continent pool is not empty:
    chosen = find lowest ranked mirror(continent pool)
else if world pool is not empty:
    chosen = find lowest ranked mirror(world pool)
else:
    do not redirect, send the file ourselves

store combination client ip <-> mirror id in memcache daemon

if metalink_requested:
    send metalink
else:
    do the redirect


一旦选择了镜像,重定向器将返回 HTTP 状态码 302 (Found),并在 Location 标头中包含重定向 URL,这将使请求者转到那里。如果对于给定的文件没有已知的镜像,服务器将直接传送该文件。

有一些重要的例外情况。对于某些文件,很难确保它们在所有镜像上都是最新的,因为它们经常更改。因此,服务器不会为这些文件重定向。

镜像“粘性”

过去,我们使用“镜像粘性”

一旦客户端被重定向到某个镜像,在下一次请求时,它将被重定向到同一个镜像,而不是随机选择另一个镜像。

这种配置被证明与仅仅随机分配镜像没有好处,因此不再激活 (我想从 2008 年初开始)。

内置 Metalink 支持

重定向器生成 metalink 文件 (参见 http://metalinker.org)。启用的客户端可以在出现问题时自动故障转移,甚至可以并行下载。每当将“.metalink”附加到要下载的文件的 URL 时,都会返回一个 metalink。

一个例子是 http://download.opensuse.org/distribution/11.1/iso/openSUSE-11.1-DVD-i586.iso.metalink

以下博客文章解释了如何充分利用它:http://lizards.opensuse.org/2008/12/16/best-way-to-download-opensuse/

重定向器支持将验证哈希和 PGP 签名注入到 metalink 中,并且对于大多数较大的文件 (如 iso 镜像) 都会包含它们。

有关使用 metalink 下载 openSUSE 的更多信息可以在 此处 找到。

其他说明

集中式分发文件的方式有一个有趣的含义 - 它允许我们收集有关请求文件的有趣数据,否则我们无法做到。因此,我们还有一个 apache 模块。它收集有关单个 Build Service 包下载的统计信息。原则上,该模块将路径和文件名拆分,并分别记录组件或增加 SQL 数据库中的计数器。来源可以在这里找到:https://forgesvn1.novell.com/svn/opensuse/trunk/tools/download-stats/mod_stats/


开发者信息和联系方式

致谢

本产品包含由 MaxMind 创建的 GeoLite 数据,可从 http://maxmind.com/ 获取

参见