ioniceコマンドでLinuxのI/O優先度を設定する方法|バックアップ処理がサーバーを圧迫する問題を解決する

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips > ioniceコマンドでLinuxのI/O優先度を設定する方法|バックアップ処理がサーバーを圧迫する問題を解決する
「バックアップのcronを夜中に仕掛けたら、翌朝Webサイトのレスポンスが遅いというクレームが来た」
こんな経験はありませんか?ディスクの読み書き帯域は有限で、バックアップやrsyncなどのバッチ処理が全力で走ると、Webサーバーやデータベースの応答に影響が出ることがあります。

この問題を解決するのが ionice コマンドです。Linuxにはプロセスごとに「I/O(ディスク読み書き)の優先度」を制御する仕組みがあり、ioniceを使えば「このバックアップ処理は空き時間だけ使う」「このDBプロセスは優先的にディスクを使えるようにする」といった制御ができます。

この記事では、ioniceコマンドの3つのスケジューリングクラスの意味、実務でよく使うrsync・cron・systemdサービスへの適用方法、そして「設定したのに効かない」ときの原因と対処法まで解説します。

動作確認環境: RHEL 9.4 / Rocky Linux 9.4 / Ubuntu 24.04 LTS

この記事のポイント

・ionice -c 3 でアイドルクラス(空き時間のみ実行)に設定できる
・-p PID で実行中プロセスのI/O優先度をリアルタイムに変更できる
・systemdサービスに IOSchedulingClass=idle を設定する方法が最も確実
・NVMe SSD(noneスケジューラー)では ionice が無効になる場合がある


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

ioniceとは?I/O優先度を制御してサービスへの影響を防ぐ

Linuxのカーネルには「I/Oスケジューラー」が組み込まれており、複数のプロセスが同時にディスクにアクセスしようとした場合にどの順番で処理するかを決めます。

ionice コマンドは、このI/Oスケジューラーに対して「このプロセスのディスクアクセスは低い優先度で扱ってほしい」と指定するためのツールです。

設定できるスケジューリングクラスは以下の3種類です。
クラス番号 クラス名 動作 用途
1 real-time(リアルタイム) 他のプロセスより必ず先に処理される 絶対に遅延させたくない処理(root権限必要)
2 best-effort(ベストエフォート) プロセスのnice値に準じた優先度 デフォルト。一般的なプロセス
3 idle(アイドル) 他にI/Oがない時だけ実行される バックアップ・インデックス更新など低優先度処理
バックアップ処理の低優先度化にはほぼ常に idle クラス(-c 3) を使います。real-time クラス(-c 1)はroot権限が必要で、誤用するとシステム全体の応答を悪化させるため注意してください。

ioniceの基本的な使い方

1. 実行中プロセスのI/O優先度を確認する

ionice -p PID でそのプロセスに設定されているI/O優先度を確認できます。

# バックアップスクリプトのPIDを確認 pgrep -a rsync # I/O優先度を確認(PIDが1234の場合) ionice -p 1234

実際のサーバーでの出力例です。

$ ionice -p 1234 none: prio 0 $ ionice -c 3 -p 1234 $ ionice -p 1234 idle: prio 7

「none: prio 0」と表示された場合、I/Oスケジューラーがデフォルトの優先度を割り当てています。idleクラスを設定すると「idle: prio 7」と表示が変わります。

2. コマンドにioniceを適用して実行する

コマンドの前に ionice -c 3 を付けるだけです。

# rsyncをidleクラスで実行(最もよく使うパターン) ionice -c 3 rsync -avz /home/ /backup/home/ # tarバックアップをidleクラスで実行 ionice -c 3 tar -czf /backup/etc-$(date +%Y%m%d).tar.gz /etc/ # best-effortで優先度を7(最低)に設定して実行 ionice -c 2 -n 7 find / -name "*.log" -mtime +30 -delete

-n オプションはbest-effortクラス(-c 2)またはreal-timeクラス(-c 1)の場合のみ意味を持ちます。値は0(高優先度)から7(低優先度)で指定します。idleクラス(-c 3)には優先度レベルがないため、-nは無視されます。

3. 実行中のプロセスにI/O優先度を適用する(-pオプション)

すでに実行中のプロセスに対してもリアルタイムで変更できます。バックグラウンドで暴走しているプロセスへの即時対処に使えます。

# 実行中のrsync(PID:1234)をidleクラスに変更 ionice -c 3 -p 1234 # pgrep でPIDを取得して一括変更 for pid in $(pgrep rsync); do ionice -c 3 -p "$pid" done # 変更を確認 ionice -p 1234

別ユーザーのプロセスに設定するにはroot権限が必要です。自分のプロセスであれば一般ユーザーでも変更できます。

実務でよく使うioniceの適用パターン

1. cronジョブにioniceを組み込む

定期実行するバックアップスクリプトにioniceを付けるシンプルな方法です。

# crontab -e で以下のように設定する # 毎日午前2時に、idleクラスでバックアップを実行 0 2 * * * ionice -c 3 /usr/local/bin/backup.sh

ioniceをスクリプト呼び出しの前に置くことで、そのシェルと子プロセス全体にidleクラスが継承されます。スクリプト内で rsynctar を複数呼ぶ場合も、個別にioniceを付け直す必要はありません。

2. シェルスクリプトの先頭でI/O優先度を自分自身に設定する

既存のバックアップスクリプトを修正する場合、スクリプト内から自身のI/O優先度を変更できます。

#!/bin/bash # スクリプトの先頭で自身をidleクラスに変更 ionice -c 3 -p $$ echo "バックアップ開始: $(date)" rsync -avz /home/ /mnt/backup/home/ --delete tar -czf /mnt/backup/etc-$(date +%Y%m%d).tar.gz /etc/ echo "バックアップ完了: $(date)"

$$ はシェルスクリプト自身のPIDです。先頭に1行追加するだけで、以降の全I/Oがidleクラスになります。

3. systemdサービスにI/O優先度を設定する(最も確実な方法)

systemdで管理するサービスには、Unitファイルに IOSchedulingClass を設定するのが最も確実です。cronよりも設定が明示的で、管理しやすくなります。

# /etc/systemd/system/backup.service [Unit] Description=Daily backup service After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/backup.sh # I/O優先度をidleクラスに設定 IOSchedulingClass=idle # CPU優先度も下げる場合(任意) Nice=19 [Install] WantedBy=multi-user.target

# systemdタイマーで定期実行する場合 # /etc/systemd/system/backup.timer [Unit] Description=Run backup daily at 02:00 [Timer] OnCalendar=02:00 Persistent=true [Install] WantedBy=timers.target

# サービスとタイマーを有効化 sudo systemctl daemon-reload sudo systemctl enable --now backup.timer # タイマーの状態確認 sudo systemctl list-timers backup.timer

IOSchedulingClass=idle を設定するとサービスとその子プロセス全体に適用されます。tar コマンドの実用例と組み合わせて、バックアップ処理全体を低優先度で実行する構成が作れます。

ioniceが効かない時のトラブルシュート|原因と対処法

1. I/OスケジューラーがNVMe(none)の場合

最もよくある「効かない」原因です。 NVMe SSDなど高速ストレージを搭載したサーバーでは、I/Oスケジューラーが none(スケジューリングなし)に設定されていることがあります。この場合、ioniceはI/Oスケジューラーに影響を与えません。

# 現在のI/Oスケジューラーを確認(sdaの場合) cat /sys/block/sda/queue/scheduler # NVMe SSDの場合の出力例(noneが選択されている) [none] mq-deadline kyber bfq # HDDや一般的なSATASSDの場合の出力例 mq-deadline [bfq] none

[none] と表示されている場合、bfq(Budget Fair Queueing)スケジューラーへの変更を検討します。

# sda を bfq スケジューラーに一時変更(再起動で元に戻る) echo bfq | sudo tee /sys/block/sda/queue/scheduler # 変更確認 cat /sys/block/sda/queue/scheduler # 期待される出力 mq-deadline [bfq] none

永続化するには /etc/udev/rules.d/ にudevルールを追加します。

# /etc/udev/rules.d/60-io-scheduler.rules として保存 ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/scheduler}="bfq" ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="bfq" # udevルールを再読み込み sudo udevadm control --reload-rules sudo udevadm trigger

2. real-timeクラスで「Operation not permitted」が出る

real-timeクラス(-c 1)の設定はroot権限が必要です。

# 一般ユーザーでreal-timeを設定しようとするとエラー $ ionice -c 1 -p 1234 ionice: cannot set I/O priority: Operation not permitted # sudo を付けて実行する sudo ionice -c 1 -p 1234

3. idleクラスなのにI/O負荷が下がらない

ioniceはプロセスのI/O優先度を制御しますが、I/O帯域幅そのものを制限するわけではありません。他にI/Oがなければidleクラスでも全帯域を使います。I/O帯域幅を上限設定するには cgroupsのblkio(v1)または io(v2)コントローラーを使う必要があります。

どのプロセスがI/Oを多く使っているかを特定するには iotopiostat が有効です。Linux ポート確認の全コマンドでも解説している ss コマンドでソケット単位の状況確認と合わせて診断することで、I/O問題の全体像が見えてきます。

# iotopでリアルタイムにI/O使用状況を確認(要インストール) sudo iotop -o # iostatでディスク全体のI/O状況を1秒間隔で5回表示 iostat -x 1 5

本記事のまとめ

やりたいこと コマンド
新規コマンドをidleクラスで実行 ionice -c 3 コマンド名
実行中プロセスのI/O優先度を確認 ionice -p PID
実行中プロセスをidleクラスに変更 ionice -c 3 -p PID
best-effortで最低優先度に設定して実行 ionice -c 2 -n 7 コマンド名
cronジョブをidleクラスで実行 ionice -c 3 /path/to/script.sh
systemdサービスのI/O優先度を設定 IOSchedulingClass=idle(Unitファイルに追記)
I/Oスケジューラーを確認 cat /sys/block/sda/queue/scheduler
I/Oスケジューラーをbfqに変更 echo bfq | sudo tee /sys/block/sda/queue/scheduler
バックアップや定期メンテナンス処理が本番サービスに影響を与えるのは、よくある現場のトラブルです。ionice -c 3 の1行を追加するだけで防げることが多いので、今すぐcronやシェルスクリプトに組み込んでみてください。

systemdのサービス設定全般については、systemd-analyze で起動時間計測も合わせて読むと、systemdの全体像の理解が深まります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Linux無料マニュアルを受け取る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。