Pacman のパフォーマンスの向上

提供: ArchWiki
ナビゲーションに移動 検索に移動

データベースのアクセス速度を向上させる

Pacman はパッケージの全ての情報を、パッケージごとの小さなファイルに保存しています。データベースのアクセス速度を向上させればデータベースを使う処理 (例: パッケージの検索・パッケージの依存関係の解決) にかかる時間が短くなります。一番安全で簡単な方法は root で次を実行することです:

# pacman-optimize

小さなファイルをハードディスクのひとつの (物理的な) 場所にまとめて置くことでパッケージにアクセスするときにハードディスクのヘッドがあまり動かなくてもいいようにします。この方法は安全ですが、フールプルーフではありません。ファイルシステムによっては、ディスク上の使用している領域と空の領域がフラグメンテーションを起こすことがあります。さらにアグレッシブな方法として、データベースを最適化する前にインストールされていないパッケージをキャッシュから削除し使われていないリポジトリを削除するという方法があります:

# pacman -Sc && pacman-optimize

ダウンロード速度を向上させる

ノート: ダウンロード速度が極端に遅い場合、使っているミラーが ftp.archlinux.org ではないことを確認してください。2007年の3月からこのサーバーには速度制限がかかっています

Pacman に初めから入っているファイルダウンローダの代わりに、他のアプリケーションを使ってパッケージをダウンロードすることで Pacman のパッケージダウンロード速度を上げることができます。

どんな場合でも、修正を行う前に最新の Pacman を使っていることを確認してください。

# pacman -Syu

Powerpill を使う

Powerpill は Pacman の完全なラッパーで並行・分割ダウンロードを使うことによってダウンロード処理を高速化します。通常の Pacman は一度にひとつのパッケージしかダウンロードしないので、ダウンロードが完了するまで次のダウンロードが始まりません。Powerpill は異なるアプローチを取ります: 同時に可能な限り多くのパッケージをダウンロードしようとします。

Powerpill の wiki ページに基本的な設定・使用方法と、パッケージと上流のリンクがあります。

powerpill-light を使う (deprecated)

pacman2aria2 は "powerpill-light" という名前のスクリプトを提供しており、Perl で書かれたオリジナルの powerpill が失くなった後の埋め合わせとして作られました。Powerpill が再リリースされた現在、powerpill-light は廃止されています。

wget を使う

pacman に初めから入っている機能よりもパワフルな proxy 設定が必要な場合、wget はとても使い勝手がよいです。

wget を使うには、まず pacman -S wget で wget をインストールして、それから /etc/pacman.conf を編集して次の行を [options] セクションでアンコメントしてください:

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

/etc/pacman.confwget パラメータを記述する代わりに、wget の設定ファイルを直接修正することも可能です (システム全体のファイルは /etc/wgetrc、ユーザー別のファイルは $HOME/.wgetrc)。

aria2 を使う

aria2 はレジューム機能と分割 HTTP/HTTPS/FTP ダウンロードをサポートしている軽量なダウンロードユーティリティです。aria2 を使えば同時に複数の HTTP/HTTPS/FTP 接続を Arch ミラーにすることができ、ファイル・パッケージの取得の際のダウンロード速度が上昇します。

ノート: Pacman の XferCommand で aria2c を使っても複数パッケージの同時ダウンロードは行われません。Pacman はひとつのパッケージごとに XferCommand を呼び出し、それが完了してから次を呼び出すからです。同時に複数のパッケージをダウンロードするには、上の powerpill のセクションを見て下さい。

インストール

aria2 とその依存パッケージをダウンロード・インストールしてください:

# pacman -S aria2

設定

/etc/pacman.conf を編集して [options] セクションに次の行を追加して下さい:

XferCommand = /usr/bin/aria2c --allow-overwrite=true -c --file-allocation=none --log-level=error -m2 -x2 --max-file-not-found=5 -k5M --no-conf -Rtrue --summary-interval=60 -t5 -d / -o %o %u

オプションの説明

/usr/bin/aria2c
aria2 実行ファイルのフルパス。
--allow-overwrite=true
対応するコントロールファイルが存在しない場合にダウンロードを再実行する (デフォルト: false)。
-c, --continue
対応するコントロールファイルが存在する場合に部分的にダウンロードされているファイルのダウンロードを続行する。
--file-allocation=none
ダウンロードが始まる前にファイルの領域を事前に準備しない (デフォルト: prealloc)。1
--log-level=error
ログレベルをエラーだけを出力するように設定する (デフォルト: debug)。
-m2, --max-tries=2
ミラー毎に指定したファイルのダウンロードを最大2回まで試行する (デフォルト: 5)。
-x2, --max-connection-per-server=2
ファイルごとにミラーに最大2つまで接続を設定する (デフォルト: 1)。
--max-file-not-found=5
5回試行したときにシングルバイトも受け取れなかった場合ダウンロードを中止する (デフォルト: 0)。
-k5M, --min-split-size=5M
サイズが 2倍、5MB = 10MB よりも大きい時だけファイルを分割する (デフォルト: 20M)。
--no-conf
aria2.conf ファイルが存在するときにロードを無効にする (デフォルト: ~/.aria2/aria2.conf)。
-Rtrue, --remote-time=true
リモートのファイルのタイムスタンプをローカルのファイルに適用する (デフォルト: false)。
--summary-interval=60
60秒ごとにダウンロードの進行状況を表示する (デフォルト: 60)。2
-t5, --timeout=5
接続が確立された後ミラー毎に5秒間のタイムアウトを設定する (デフォルト: 60)。
-d, --dir
pacman によって指定されているファイルのダウンロード先のディレクトリ。
-o, --out
ダウンロードするファイルのファイル名の出力。
%o
pacman によって指定されているローカルのファイル名を表す変数。
%u
pacman によって指定されているダウンロード URL を表す変数。

追記

1 --file-allocation=falloc
(エクステントをサポートしている) ext4, btrfs, xfs などの新しいファイルシステムはすぐに大きなファイル (GB) を割り振るのでこのオプションを使うことを推奨します。ext3 などの古いファイルシステムでは falloc は使わないで下さい。prealloc は通常のアロケーションとほぼ同じ時間を消費し aria2 はダウンロード処理を中断します。
2 --summary-interval=0
ダウンロードの進行状況の出力をおさえることで全体のパフォーマンスが向上するかもしれません。log-level オプションに設定された値によってログは出力され続けます。
3 XferCommand = /usr/bin/printf 'Downloading ' && echo %u | awk -F/ '{printf $NF}' && printf '...' && /usr/bin/aria2c -q --allow-overwrite=true -c --file-allocation=none --log-level=error -m2 --max-connection-per-server=2 --max-file-not-found=5 --min-split-size=5M --no-conf --remote-time=true --summary-interval=0 -t5 -d / -o %o %u && echo ' Complete!'
XferCommand の使用はあまり意味がありませんが、出力の可読性は向上します。

pacget (aria2) ミラースクリプト

このスクリプトはブロードバンドを使っているユーザーのダウンロード速度を格段に向上させます。aria2 でミラーとして /etc/pacman.d/mirrorlist 内のサーバーを使います。aria2 が複数のサーバーから同時にひとつのパッケージをダウンロードするのでダウンロード速度が大幅に加速します。

ノート: 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.
警告: You may experience some problems if the mirrors used are out-of-sync or are simply not up-to-date. Just use the Reflector script to generate a list of up-to-date and fast mirrors. Also, ftp.archlinux.org resolves to two IPs. You may want to choose only one of them and hard code ftp.archlinux.org and the chosen IP address to /etc/hosts.
/usr/bin/pacget
#!/bin/bash

msg() {
  echo ""
  echo -e "   \033[1;34m->\033[1;0m \033[1;1m${1}\033[1;0m" >&2
}

error() {
  echo -e "\033[1;31m==> ERROR:\033[1;0m \033[1;1m$1\033[1;0m" >&2
}

CONF=/etc/pacget.conf
STATS=/etc/pacget.stats
ARIA2=$(which aria2c 2> /dev/null)

# ----- do some checks first -----
if [ ! -x "$ARIA2" ]; 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}
arch=$(grep ^Architecture /etc/pacman.conf | cut -d '=' -f2 | sed 's/ //g')
if [[ $arch = "auto" ]]; then
  arch=$(uname -m)
fi
# Determine which repo is being used
repo=$(awk -F'/' '$(NF-2)~/^(community|core|extra|testing|comunity-testing|multilib)$/{print $(NF-2)}' <<< $server)
[ -z $repo ] && repo="custom"

# 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 || $repo = "custom" ]]; then
  mirrorlist=$(awk -F' *= *' '$0~"^\\["r"\\]",/Include *= */{l=$2} END{print l}' r=$repo /etc/pacman.conf)
  if [ -n mirrorlist ]; then
    num_conn=$(grep ^split $CONF | cut -d'=' -f2)
    url=$(sed -r '/^Server *= */!d; s/Server *= *//; s/\$repo'"/$repo/"'; s/\$arch'"/$arch/; s/$/\/$filename/" $mirrorlist | head -n $(($num_conn *2)) )
  fi
fi

msg "Downloading $filename"
cd /var/cache/pacman/pkg/

touch $STATS

$ARIA2 --conf-path=$CONF --max-tries=1 --max-file-not-found=5 \
  --uri-selector=adaptive --server-stat-if=$STATS --server-stat-of=$STATS \
  --allow-overwrite=true --remote-time=true --log-level=error --summary-interval=0 \
  $url --out=${filename}.pacget && [ ! -f ${filename}.pacget.aria2 ] && mv ${filename}.pacget $2 && chmod 644 $2

exit $?
/etc/pacget.conf
# The log file
log=/var/log/pacget.log
# Number of servers to download from
split=5
# Minimum file size that justifies a split, i.e. concurrent download (default 20M)
min-split-size=1M
# Maximum download speed (0 = unrestricted)
max-download-limit=0
# Minimum download speed (0 = do not care)
lowest-speed-limit=0
# Server timeout period
timeout=5
# 'none' or 'falloc'
file-allocation=none

このスクリプトを /usr/bin/pacget として保存してください。

# chmod 755 /usr/bin/pacget

上のコマンドでスクリプトが実行可能になります。

/etc/pacman.conf の [options] セクション内に、以下を追加する必要があります:

XferCommand = exec /usr/bin/pacget %u %o
ノート: If you use ftp.archlinux.org 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 ftp.archlinux.org when the mirrors have not yet synced. The rankmirrors script can be useful in this case.

他のアプリケーションを使う

Pacman で利用できるダウンロードアプリケーションは他にもあります:

  • snarf: XferCommand = /usr/bin/snarf -N %u
  • lftp: XferCommand = /usr/bin/lftp -c pget %u
  • axel: XferCommand = /usr/bin/axel -n 2 -v -a -o %o %u

最速のミラーを選ぶ

パッケージをダウンロードする際 pacman は /etc/pacman.d/mirrorlist に記述されている順番でミラーを使用します。リストの一番上のミラーがデフォルトで使われますが、最速ではない可能性があります。最速のミラーを選択するには、Mirrors を参照してください。

LAN 上でパッケージを共有する

LAN 上で複数の Arch を動かしている場合、パッケージを共有することでダウンロード時間を減らすことが可能です。問題が生じるので、異なるアーキテクチャ間 (つまり i686 と x86_64) で共有することはできません。

Pacman ヒント#pacman のキャッシュをネットワークで共有するを見て下さい。