Improve pacman performance (简体中文)

From ArchWiki
Revision as of 13:00, 25 February 2008 by Darksheen (talk | contribs)
Jump to navigation Jump to search

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




pacman-optimize && sync



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

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


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



pacman -Sy pacman



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

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



According to the aria2 website, aria2 is "a download utility with resuming and segmented downloading. Supports HTTP/HTTPS/FTP/BitTorrent/Metalink." This means that you can make several HTTP/FTP connections to an Arch mirror at the same time, which should result in an increase in download speeds.

Install it with pacman -S aria2 and then edit /etc/pacman.conf by adding the following line to the [option] section:

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

Let's run over the options here:

  • /usr/bin/aria2c - the location of the aria2 application
  • -s 2 - use 2 concurrent connections (you can set this higher if you want, but it's not going to do a whole lot)
  • -m 2 - make 2 attempts to download the package per mirror
  • -o %o - output to the file pacman specifies
  • %u - download the file pacman specifies

Aria2 Mirror Script

This script will greatly improve the download speed for broadband users. It takes the download URL from pacman, then looks up the mirror list in /etc/pacman.d/mirrorlist and adds them all as mirrors to aria2. What ends up happening is aria2 connects to 10-20 servers (the default is 4 servers max) downloading from all of them at the same time, which should give anyone on broadband a huge boost in download speed. This should max out the download speed for most people.

Take note that you have to put 'exec' before /usr/bin/pacget in the XferCommand. This is needed so that when you terminate pacget or aria2 (with process id used by pacget), pacman would also terminate. This would prevent "inconvenience" because Pacman would not persist downloading a file when you tell it not to.

WARNING: You may experience a lot of problems when you become greedy. Just choose a handful of reliable servers (5 is already a lot) that syncs regularly with the master server. Do NOT choose out-of-date mirrors as these may cause problems like corrupted downloads, etc. Also, resolves to two IPs. You may want to choose only one of them and hard code and the chosen IP address to /etc/hosts.

WARNING: Needs testing with custom repos.


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

# The log file
# Number of connections per server (don't go beyond 2, please)
# Max number of servers to download from (follows ordering in include file)
# Maximum download speed (0 = unrestricted)
# Minimum download speed (0 = don't care)
# Maximum tries per download
# Server timeout period
# Passive FTP or not: 'yes' or 'no'
# 'none' or 'prealloc'
# Use color in messages

# ------------- 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
    echo -n "   -> ${1}" >&2

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

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

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

filename=$(basename ${1})

# Determine which repo is being used
repo=$( awk -F'/' '$(NF-2)~/^(community|core|current|extra|testing|unstable)$/{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
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} )

# 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 $?

Save this script as /usr/bin/pacget.

chmod 755 /usr/bin/pacget

This makes the script an executable

In /etc/pacman.conf the following needs to be added:

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

PS: If you use as the first server listed in your include files (/etc/pacman.d/*), some problems may occur when the mirrors you are using have not yet synced. To make great use of this script, choose a mirror (that syncs in a timely manner) that is more appropriate for you, then put that on top of the server lists. This is to prevent downloading only from when the mirrors have not yet synced.

Using other applications

There are other downloading applications that you can use with Pacman. Here they are, and their associated XferCommand settings:

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