-
Notifications
You must be signed in to change notification settings - Fork 284
Mirroring Howto
TUNA 收到了许多来信,咨询关于如何搭建一套软件镜像仓库,这其中有许多不同的需求,大致可以归类为:
- 类似 TUNA 及其兄弟姊妹站点一样的公开服务
- 镜像服务器可在线从外部拉取数据的内部服务
- 纯粹的内部镜像,站点在线联网存在困难
在此,我们尝试整理部分高频问题和相应解决办法,以供参考。
搭建一个镜像站,最基本的问题有如下几个:
- 评估是否真的需要一个新的镜像
- 计划镜像的内容清单
- 适宜的硬件资源
- 数据同步管理
- Web 服务和帮助文档
新建镜像一般要瞄准特定的用户群体,典型的例子是校园网、云计算租户网络、软件研发机构内网等。如果没有一定规模的用量,维护一套镜像所带来的人力、管理和资金成本很可能会高于收益,此时建议采用公网镜像并自建缓存(如 HTTP 代理)来提高带宽使用效率和用户体验。常见的代理软件有 Squid、Apache TrafficServer 等,针对 Debian/Ubuntu 也有如 apt-cacher-ng 的成套方案。需要注意的是,如果缓存没有正确配置,可能会导致出现严重的使用问题。
如果确实需要新建镜像,那么紧接着就是要针对计划镜像的内容做一份清单,这份清单应该按照需求的强烈程度排序。镜像不是越多越好,当规模增加到一定程度后,可能会带来意想不到的维护复杂度,因而导致相应的资源和精力投入并不总是随规模线性增减。
对镜像的最直观投入是存储和网络,因为镜像站属于重IO业务(disk & network),通常建议使用实体物理机来承载,以免在虚拟化平台上对其他业务造成影响。
- 存储容量可以参考 TUNA 镜像站同步状态页给出的各个镜像的大小;
- 网络接入建议将服务器放在尽量靠近流量主干的位置,或根据具体网络情况和使用需求评估适宜的位置;
- 为镜像服务器配置适宜的内存,建议采用 ECC 内存,具体容量根据投入大小决定;一个不精确的估算建议:为每TB镜像数据配置至少1GB内存,并额外配置若干内存用于数据同步等任务。
镜像站需要通过从外部进行数据同步来保持更新,因此如何管理和调度这些任务也成为了一个问题:
- 当镜像数量较少时,可使用 cron 或 systemd timers 的简单方式管理,易于理解和维护
- 镜像数量较多时,需要使用更复杂的调度器,如 tunasync
有几种明确 不建议 的做法:
- 将许多同步任务定时到同时启动,或安排在非常相近的时刻;这会导致上游和本地服务器均出现 io 瓶颈,显著降低同步效率和成功率;
- 两次同步间隔过短,绝大多数镜像建议每天同步 1-2 次,最多不超过 4 次;主要的上游源都不会更新过于频繁,更短的间隔不能明显提升时效性;
- 使用循环脚本,依次不停地尝试同步每个镜像;除上述效率原因外,这样做会浪费上游同步服务器资源,可能导致IP地址被封禁。
以下做法应务必避免:
-
定时启动同步任务,并且同步命令没有超时的时间限制。
在这种情况下,如果出现网络问题,则会导致已经执行的同步命令还未终止时,再次执行同步命令,长此以往将会积累较多的卡住的同步进程。一旦网络恢复,这些卡住的同步进程则会出现巨量的网络流量,阻塞网络。代替地,应该在同步任务结束一定时间间隔后启动下一次同步任务,而不是定时启动;或者限制同步命令的执行时间,确保在出现故障的情况下,同步命令可以在合理的时间内终止。
一个简单的 Web 服务器软件(例如 TUNA 使用的 Nginx),将所有有关文件设置好路径提供下载,就可以实现最基本的镜像站功能。镜像站绝大多数业务均为静态文件服务,因此类似的高性能静态文件 Web 服务器软件均可按需选择,不建议使用不常见的或过于侧重动态业务的 Web 服务器软件,如 SimpleHTTPServer、Tomcat 等。
如果希望用户界面更加友好,可以在主页前端、目录索引等功能上进行界面改进,可以参考如下几个项目:
- TUNA 镜像的前端页面:https://github.com/tuna/mirror-web
- USTCLUG 的镜像前端页面:https://git.lug.ustc.edu.cn/mirrors/mirrors-index
- 目录索引美化的 ngx-fancyindex
此外,还有镜像的使用帮助,可以参考:
- TUNA 的使用帮助:https://github.com/tuna/mirror-web/tree/master/help/_posts
- USTCLUG 的使用帮助:https://github.com/ustclug/mirrorhelp
根据不同的需求规模和财务预算,可使用的存储方案一般有以下几个:
- IOPS:HTTP 类型的服务对 IOPS 需求一般,RSYNC 则需要视情况配置 SSD;
- 硬盘:7.2K 硬盘总体较为均衡,不建议使用 10K 甚至 15K 盘作为镜像站存储,如有相关预算可考虑改配 SSD;
- RAID 卡
- 盘的数量较大或总体性能较高时,RAID 卡性能(IOPS、Cache 大小等)有可能成为瓶颈
- 建议选择有缓存的 RAID 卡,许多 RAID 卡自带 512MB、1GB 或 2GB 的 RAM 作为缓存,通常会有配套的电池或超级电容可以在意外掉电时降低故障概率
- (仅对于镜像站业务)推荐启用 Disk Write Cache,即硬盘自带的缓存,以常见的单盘 128MB 缓存为例每 8 块盘可提供约 1GB 的写缓存,但是这项配置会导致意外掉电时的文件系统故障概率增加(即使 RAID 卡自身有电池)
- 有条件的情况下,可选择带有 SSD 缓存功能的 RAID 卡并实配缓存盘,使用一般的 SATA SSD 作为缓存盘即可获得明显的 IOPS 提升
- ZFS/Btrfs 等软件方案
- 软件方案支持的功能更加丰富,目前 TUNA 和 USTC 镜像均有部分业务使用 ZFS,但其也存在一些性能和维护问题,选择时需综合考虑
- 如服务器有 RAID 卡推荐设置为 JBOD 模式(也有称为 HBA 模式),可使用无缓存、无电池的 RAID 卡节约成本
- 目前暂不推荐使用 BTRFS 应用于重负载镜像站
- RAID 级别
- RAID 50/60 或 RAID-Z/Z2 可较好地提升可用空间,并保持一定冗余度,但也会对性能带来负面影响
- 对于重负载场景,应考虑使用 RAID10 或相似配置,如 ZFS 的 mirror RAID
对于特殊的网络环境要求,镜像服务器不能直接与互联网连接时,可以采用这样的同步方案:
分别在内部网络和外部网络中各设置一台存储服务器。其中,外部网络中的存储服务器可以与互联网相连;内部网络中的存储服务器与内部网络中的用户相连,二者之间没有网络连接,但可以由外而内传输数据。一种推荐的方法是,两个服务器上都建立 ZFS 文件系统。在外部网络中的存储服务器上按照前述方法,保持与上游的同步。定期地,在外部网络中的存储服务器上建立 ZFS 文件系统的快照,并将该快照与前一个快照的增量信息(对于首次传输,则是全量信息)通过 zfs send
命令导出。将导出的数据拷贝至内部网络中的存储服务器上,并使用 zfs recv
导入。这样即可实现内部网络中的存储服务器上的镜像数据定期同步。
应特别注意的是,类似于 pypi 这样包含用户产生的内容的仓库,应特别小心,防止恶意的程序/代码流入。