# Improve Pacman Performance (日本語)

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

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

    # pacman-optimize

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

    # pacman -Sc && pacman-optimize

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

Note: ダウンロード速度が極端に遅い場合、使っているミラーが 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.conf` に `wget` パラメータを記述する代わりに、`wget` の設定ファイルを直接修正することも可能です (システム全体のファイルは `/etc/wgetrc`、ユーザー別のファイルは `$HOME/.wgetrc`)。

### aria2 を使う

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

Note: 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 が複数のサーバーから同時にひとつのパッケージをダウンロードするのでダウンロード速度が大幅に加速します。

Note: 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 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

Note: 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_Tips_(日本語)#pacman のキャッシュをネットワークで共有する を見て下さい。

Category:

- Package management (日本語)