Improve pacman performance (简体中文)

From ArchWiki
Revision as of 18:47, 14 December 2008 by Byte (Talk | contribs) (Aria2 镜像脚本: rm all traces of [unstable] (and other cruft))

Jump to: navigation, search

Template:I18n links start Template:I18n entry Template:I18n entry Template:I18n links end


提高数据库访问速度

Pacman将所有软件包的信息放在一一对应的许多小文件中。通过改善数据库访问速度,可以减少花在数据库相关任务上的时间,比如:寻找软件包、检索软件包依赖性。

最安全最简单的方法是以root身份运行

pacman-optimize && sync

上述命令试图将所有小文件放在磁盘上同一个物理区域,以减少磁头移动。这种方法很安全,但不一定有效。其效果取决于你的文件系统、磁盘使用率、和磁盘碎片程度。

进一步的优化

ody 曾经发表了 a script on the forum 这篇文章,将目前的Pacman数据库替换成了一个回送文件系统(loopback filesystem),用来保证所有的小文件连续地存放在硬盘上。不少用户报告说会有很大的性能提升,但是也有问题出现。所以除非你是专业人士,否则不要这样做。

要使用ody的脚本,你必须确定内核添加了"loopback filesystem"支持(内核一般默认支持)。

加快下载速度

如果你的包下载速度变得极慢,首先确定你用的是那些镜像(mirrors)网站而不是ftp.archlinux.org,因为后者根据as of March 2007所述,被限速了。

可以通过各种下载工具而不是Pacman内置的下载方式,来改善Pacman的下载速度。

不论怎样,在做任何修改前,你必须确定拥有了最新版的Pacman:

pacman -Sy pacman

使用wget

对于需要更强大代理支持的用户来说,用wget比用Pacman自己的下载方式更加方便。

要使用 wget,首先使用pacman -S wget安装它,然后修改/etc/pacman.conf并在其中的[options]区段添加如下几行:

XferCommand = /usr/bin/wget -c --passive-ftp -c %u

除了将wget参数放在/etc/pacman.conf里,你也可以直接修改wget配置文件(全局文件是/etc/wgetrc,各个用户的文件是$HOME/.wgetrc)。

使用aria2

根据aria2网站的介绍,aria2“是一个具有断点续传和分块下载功能的软件,支持HTTP/HTTPS/FTP/BitTorrent/Metalink协议”。这意味着你可以多线程连接镜像服务器,显著提高下载速度。

通过pacman -S aria2安装它,然后修改code>/etc/pacman.conf</code>,在[option]段添加下列一行(如果已存在则修改之):

XferCommand = /usr/bin/aria2c -s 2 -m 2 -d / -o %o %u

让我们来看看各个参数的意思:

  • /usr/bin/aria2c - aria2主程序
  • -s 2 - 开两线程下载(你可以将数字改大,但是速度不一定会有太大改观)
  • -m 2 - 设置每个镜像的重试次数为2
  • -o %o - 将下载的文件命名为pacman指定的名字
  • %u - 下载pacman指定的文件


Aria2 镜像脚本

此脚本将大大提高宽带用户的下载速度。它从pacman获得下载链接,在/etc/pacman.d/mirrorlist中寻找镜像服务器并全部添加到aria2使用的镜像。最终的结果就是aria2同时连接到10-20个服务器(默认是4个)进行下载,这大大提高了宽带用户的下载速度。此法将使大部分用户达到带宽极限。

请注意,在XferCommand中,你必须将'exec'放在/usr/bin/pacget前面,因为一旦你终止了pacget或者aria2(用了pacget的进程ID),pacman也同时终止。这将防止一些“不便”,因为Pacman would not persist downloading a file when you tell it not to.

警告:如果你过于贪婪,可能会遭遇很多问题。只要选择几个和主服务器同步的、稳定的服务器(5个已经很多了)就行了。不要选择过期的镜像服务器,因为可能会引起错误。同时,ftp.archlinux.org 拥有2个IP地址,你可能只需要其中一个,并且将其添加到/etc/hosts中。

警告:尚需对自定义镜像的测试。

#!/bin/bash

# ------------ Begin Configuration ------------ #

# The log file
LOG=/var/log/pacget.log
# Number of connections per server (don't go beyond 2, please)
CONNECTIONS=2
# Max number of servers to download from (follows ordering in include file)
SERVERS=4
# Maximum download speed (0 = unrestricted)
MAX_SPEED=0
# Minimum download speed (0 = don't care)
MIN_SPEED=0
# Maximum tries per download
MAX_TRIES=2
# Server timeout period
TIMEOUT=15
# Passive FTP or not: 'yes' or 'no'
FTP_PASV="no"
# 'none' or 'prealloc'
FILE_ALLOC="none"
# Use color in messages
USE_COLOR="yes"

# ------------- End Configuration ------------- #

msg() {
  echo ""
  if [ "${USE_COLOR}" = "yes" ]; then
    echo -ne "   \033[1;34m->\033[1;0m \033[1;1m${1}\033[1;0m" >&2
  else
    echo -n "   -> ${1}" >&2
  fi
}

error() {
  if [ "$USE_COLOR" = "yes" ]; then
    echo -e "\033[1;31m==> ERROR:\033[1;0m \033[1;1m$1\033[1;0m" >&2
  else
    echo "==> ERROR: $1" >&2
  fi
}

ARIA2_BIN=$(which aria2c 2> /dev/null)

# ----- do some checks first -----
if [ ! -x "$ARIA2_BIN" ]; then
  error "aria2c was not found or isn't executable."
  exit 1
fi

if [ $# -ne 2 ]; then
  error "Incorrect number of arguments"
  exit 1
fi

filename=$(basename ${1})
server=${1%/${filename}}

# Determine which repo is being used
repo=$( awk -F'/' '$(NF-2)~/^(community|core|extra|testing)$/{print $(NF-2)}' <<<$server )
[ -z $repo ] && repo="custom"

# Override number of connections for db files
[[ ${filename} = *.db.tar.gz ]] && CONNECTIONS=1

# For db files, or when using a custom repo (which most likely doesn't have any mirror),
# use only the URL passed by pacman; Otherwise, extract the list of servers (from the include file of the repo) to download from
url=${1}
if ! [[ ${filename} = *.db.tar.gz || ${repo} = "custom" ]]; then
        mirrorlist=$( awk -F' *= *' '$0~"^\\["r"\\]",/Include *= */{l=$2} END{print l}' r=${repo} /etc/pacman.conf )
        [ -n mirrorlist ] && 
        url=$( sed -r '/^Server *= */!d; s/Server *= *//; s/\$repo'"/${repo}/; s:$:/${filename}:" ${mirrorlist}|head -n ${SERVERS} )
        #awk way of doing the same thing, 
        #url=$( awk -F' *= *' 'i<=n&&$1=="Server"{gsub(/\$repo/, r, $2);print $2"/"f;i++}' n=${SERVERS} r=${repo} f=${filename} ${mirrorlist} )
fi

# Passive FTP or not?
[ "${FTP_PASV}" = "yes" ] && OPT_FTP_PASV="--ftp-pasv" || OPT_FTP_PASV=""

msg "Downloading ${filename}"

cd /var/cache/pacman/pkg/

${ARIA2_BIN} --log=${LOG} --timeout=${TIMEOUT} --max-tries=${MAX_TRIES} --allow-overwrite=true \
             --split=${CONNECTIONS} ${OPT_FTP_PASV} --file-allocation=${FILE_ALLOC} \
             --lowest-speed-limit=${MIN_SPEED} --max-download-limit=${MAX_SPEED} \
             ${url} --out=${filename}.pacget && [ ! -f ${filename}.pacget.aria2 ] && mv ${filename}.pacget ${2} && chmod 644 ${2}

exit $?

将此脚本另存为/usr/bin/pacget,并且使其具有可执行属性:

chmod 755 /usr/bin/pacget

在/etc/pacman.conf中添加如下内容(如果已存在则修改之):

XferCommand = exec /usr/bin/pacget %u %o

注意:如果使用ftp.archlinux.org作为首选服务器,有可能会出现一些问题,例如镜像服务器还没有完全同步。要发挥此脚本的最大效力,需要选择一个更合适(有规律地进行同步)的镜像服务器,然后将其放在服务器列表的最顶端。这样做可以避免因为各个服务器还没有同步,而只能从ftp.archlinux.org获得数据的情况。

使用其它程序

这里还有一些可以和Pacman协同工作的下载软件。下面列举了它们对应的XferCommand命令写法:

  • snarf: XferCommand = /usr/bin/snarf -N %u
  • lftp: XferCommand = /usr/bin/lftp -c pget %u