mirrors 修复部分文件不能更新问题

mirrors 9月重装后使用 root 同步,一些文件 owner 变成了 root。对所有文件进行 chown,但事实上没有全部 chown。后来改用 mirror 用户同步,就有一些文件一直不能同步成功(Permission Denied)。感谢 HUANG Jianbo 的反馈。

chown 时使用的命令是 chown -R /srv/{array/exports,array/repo,ftp1,ftp2,ftp3,ftp4},而 ftp1,ftp2,ftp3,ftp4 是符号链接(链接到 /mnt/{d,e,f,g}),重装系统之前是直接挂载在这里的。对这些符号链接,chown 并没有 follow symlink,因此 ftp1,2,3,4 事实上没有 chown。正确的做法是在后面加 /,也就是 chown -R /srv/ftp{1,2,3,4}/。希望引以为戒。

mirrors 修复 page allocation failure

从 syslog 里看到,从9月3日(也就是 mirrors 最近一次故障刚恢复服务)开始,每天都有几十次甚至上百次 page allocation failure,最多的一天 266 次。诱发者大部分是 swapper/0,少数是 rsync,nginx,collectd。

Aron Xu 建议修改 sysctl 中的下列参数:

vm.vfs_cache_pressure=1000
vm.zone_reclaim_mode=2

现在不再出现 page allocation failure 了。

mirrors 修复 Debian 源缓存不一致问题

mirrors 在此前两个星期,Debian 源有时 Packages 文件与软件包有时会 MD5 不一致,这是因为 SSD cache 没有及时更新。本来是希望每次同步之后更新当前源,每6小时整体更新(failover,以防万一)。但实际出现了三次问题:

  1. 对 rsync 参数理解不对,旧缓存文件没有删除,导致 SSD 满了。现在自己写了个很丑的 bash 脚本来实现。
  2. ftpsync 的同步写在文件末尾,而末尾的 runmirrors 有可能失败,导致脚本提前退出,不执行更新。
  3. ftpsync 的同步写在 stage1 后,stage2 更新 Packages 和索引文件后并没有更新缓存。

ftpsync 真是个比较复杂的东西。非常抱歉这种间歇性的缓存不一致给 Debian 用户带来的麻烦。

mirrors 修复缓存更新慢的问题

现在设置了 trigger,每个源同步完成后都会立即更新这个源的 cache,而不用等每天凌晨统一更新 cache 了。这使得缓存不一致的时间缩短到秒级。

此外,由于 rsync 同步不够灵活,全部删掉再重新复制又太浪费,我重新发明了轮子来做同步。算法见下面的注释:

# There are actually 3 file lists:
#  - cache_list: files to be cached (param 1 of this func)
#  - WWWROOT: authoritative source
#  - CACHEROOT: cache files
# After sync, CACHEROOT should contain up-to-date files in and only in the intersection of cache_list and WWWROOT.
# So comes the algorithm:
#  1. Remove files in CACHEROOT but not in cache_list
#  2. Remove files in CACHEROOT but not in WWWROOT or not up-to-date
#  3. Copy non-cached files in cache_list to CACHEROOT, if it exists in WWWROOT

完整的代码 git clone https://gitgeek.net/mirrors/ssd-cache.git

mirrors 部分源从磁盘阵列迁移到本地磁盘

由于磁盘阵列负载过高,io util 常年 100%,现将一些大源移到本地磁盘。选取目标磁盘主要有两个原则,一是空余空间足够,二是目前负载不高。

移到 sdd 上的源是 qtproject。sdd 上原有的源主要有 debian 和 gentoo。

移到 sde 上的源是 ubuntu 和 ubuntu-releases。sde 上原有的源主要有 CPAN,CTAN,deepin,opensuse 和 cygwin。

移到 sdf 上的源是 debian-cd。sdf 上原有的源主要有 centos,eclipse 和 archlinux。

To Mirrors Maintainers:移动源的步骤:

  1. 以 mirror 用户登录 sync LXC
  2. 在 screen 或 byobu 中 rsync -av /mnt/original-disk/mirror /mnt/new-disk/
  3. 修改 ~/etc/ 中对应的配置文件
  4. git commit -a -m “commit message” –author=”Your Name <you@gmail.com>”
  5. git push
  6. rsync 结束后,原子地替换掉 HTTP 根目录中的符号链接:ln -s /mnt/new-disk/mirror /tmp/
  7. mv /tmp/mirror /srv/www/
  8. 检查 HTTP 是否可以正常访问。
  9. 如果有提供 FTP 服务,要到主机里修改 /etc/fstab,并 mount -a
  10. 如果有提供 rsync 服务,要到主机里修改 /etc/rsyncd.conf

修复 mirrors 缓存过期问题

mirrors 的源有一些没有更新,原因是使用了过期的 SSD cache。SSD cache 本来会与源目录同步,不幸的是 SSD 满了。撑满 SSD 的原因是同步时没有删除已经不在缓存文件列表中的文件,这又是因为我对

rsync --delete --file-list

的理解有误。我以为这样会删除源目录中不在 file-list 中的文件,事实上不会。

改成了根据缓存文件列表生成符号链接到临时目录,再同步文件到 SSD:

rsync --delete --copy-links $TMP_LINK_ROOT/ $SSD_CACHE_ROOT/

commit: https://gitgeek.net/mirrors/ssd-cache/commit/6602b3b47d55d47d2185a9ed8ad1220a54cd905a

服务器优化 TCP 参数

blog 和 mirrors 服务器调整了 ip_conntrack 配置:

net.ipv4.netfilter.ip_conntrack_max=655360</code>

# should not be less than net.ipv4.tcp_keepalive_time (default 7200)
net.netfilter.nf_conntrack_tcp_timeout_established=14400

blog,mirrors 和 gitlab 调整了 TCP 发送窗口大小限制,以充分利用高延迟和高带宽的线路:

net.core.wmem_max=12582912
net.core.rmem_max=12582912
net.ipv4.tcp_rmem= 10240 87380 12582912
net.ipv4.tcp_wmem= 10240 87380 12582912

blog,mirrors 和 gitlab 在 HTTP 持久连接期间不再慢启动,以加快第二次及以后访问页面:

net.ipv4.tcp_slow_start_after_idle=0

增加 TCP 发送和接收默认窗口大小到 10 个 MSS,以减少小 HTTP 请求和 HTTPS 握手的来回次数。对 2.6.33 以下内核只能调整默认发送窗口大小(以下命令仅为示例):

# example on Debian wheezy
ip route change default via 202.141.176.126 initrwnd 10 initcwnd 10
# example on Debian squeeze
ip route change default via 202.141.176.126 initcwnd 10