🐧 Linux 総合学習プラットフォーム
OS内部/起動の仕組み ・ 上級

起動時間の分析

起動が遅いと感じたら、原因を勘で探す前に計測します。systemd-analyze は、ファームウェア・ブートローダ・カーネル・ユーザ空間それぞれにかかった時間を要約して表示します。systemd-analyze blame を使えば、起動に時間のかかったサービスを降順に並べられ、ボトルネックの特定に直結します。さらに systemd-analyze critical-chain で、起動完了までの依存の連鎖(クリティカルパス)を確認できます。どのサービスが全体を待たせているかが数字で分かるため、無効化や設定見直しの判断材料になります。

「最近サーバの起動が遅い気がする」「再起動してからログインできるまでがやけに長い」——こうした体感の問題に向き合うとき、いちばんやってはいけないのが、勘で『たぶんあのサービスのせいだろう』と決めつけて設定をいじることです。原因を推測する前に、まず計測する。これが鉄則です。systemd を採用した環境には、起動にかかった時間を段階ごと・サービスごとに数字で示してくれる systemd-analyze という専用のツールが標準で備わっています。どこで時間を食っているのかが客観的な数字で見えれば、無効化すべきサービスや見直すべき設定の判断が、思い込みではなく根拠に基づいて下せるようになります。

全体の所要時間を要約する — systemd-analyze

まず引数なしで systemd-analyze と打つと、起動全体にかかった時間が段階別に要約されて表示されます。出力は『Startup finished in 3.2s (firmware) + 5.1s (loader) + 4.8s (kernel) + 12.3s (userspace) = 25.4s』のような形になり、ファームウェア・ブートローダ(loader)・カーネル・ユーザ空間(userspace)のそれぞれが何秒かかったかが一目で分かります。ここでいうユーザ空間の時間は、init である systemd が動き始めてから、既定の target(graphical.target など)に到達して『起動完了』とみなされるまでの時間を指します。ここで重要なのは、この4区分のうちどこが支配的かをまず見ることです。userspace が突出して長ければ、原因はsystemdが管理するサービス群にある可能性が高く、次に挙げる blame で深掘りする価値があります。逆に firmware や loader が長い場合は、systemd の設定をいくらいじっても改善しません——そこはBIOS/UEFIやGRUBの領分だからです。この切り分けが最初の分岐点になります。

時間のかかったサービスを並べる — systemd-analyze blame

userspace に原因がありそうだと分かったら、systemd-analyze blame の出番です。このサブコマンドは、起動時に各サービス(unit)の初期化にかかった時間を、長い順に降順で一覧してくれます。出力は『8.4s NetworkManager-wait-online.service』『3.1s dnf-makecache.service』のように、所要時間とサービス名が並ぶ形です。リストの上の方に来ているサービスが、起動を待たせている主犯候補ということになります。ここでよく見つかる典型例が NetworkManager-wait-online.service で、これはネットワークが完全に接続されるまで起動を待つサービスのため、環境によっては数秒〜十数秒を消費します。本当にその待ちが必要かを検討し、不要なら無効化する、といった判断材料になります。

待ち時間の本質を見抜く — critical-chain

ただし blame には落とし穴があります。blame は各サービスの『所要時間』を単純に長い順で並べますが、サービスは並列に起動するため、所要時間が長いからといって、それが全体の完了を遅らせているとは限りません。他のサービスと同時並行で動いていて、待ち時間に隠れているだけかもしれないからです。そこで使うのが systemd-analyze critical-chain です。これは、起動が完了するまでに直列でつながった依存の連鎖——クリティカルパス——をツリー状に表示します。各行には、そのサービスが起動し終えた時刻(@で表示)と、そのサービス自体にかかった時間(+で表示)が示され、『どのサービスの完了を待ったせいで次が遅れたのか』という因果の鎖が見えます。本当に全体を遅らせている真犯人を突き止めるには、blame の所要時間ランキングと critical-chain の依存連鎖を両方見るのがコツです。

原因を特定したあとの対処

ボトルネックが分かったら、対処は前のトピックで扱った systemctl が担います。不要だと判断したサービスは systemctl disable サービス名 で自動起動を止め、効果を確かめるために再起動してから再度 systemd-analyze で測り直す、という流れになります。サービス自体は残しつつ完全に無効化したい場合は systemctl mask、逆に消したものを戻したい場合は systemctl enable と、状況に応じて使い分けます。なぜそのサービスに時間がかかっているのか、起動時に何が起きていたのかをもっと詳しく知りたいときは、journalctl -b でその回の起動ログを追うと、エラーや待ちの理由が見つかることがあります。たとえば何かの応答を待ってタイムアウトしている、依存先のサービスが立ち上がるのを待っている、といった事情がログから読み取れます。計測 → 特定 → 対処 → 再計測、というループで地道に詰めていくのが王道です。

よくある誤解と実務の使いどころ

よくある誤解は、blame の一番上に出たサービスをそのまま犯人だと決めつけてしまうことです。前述のとおり並列起動のため、所要時間が長いことと全体を遅らせることは別物で、critical-chain と突き合わせないと判断を誤ります。また、起動を速くしたい一心で必要なサービスまで無効化すると、ネットワークやログが立ち上がらないといった別の不具合を招きます——速さと安定性のバランスを忘れないことが大切です。実務では、サーバ構築後やトラブル後に起動時間を一度測ってベースラインを記録しておく、起動が遅くなったと感じたら推測ではなくまず systemd-analyze で数字を取る、という習慣が、無駄な設定変更や事故を減らしてくれます。平常時の数字を知っておけば、ある日とつぜん起動が倍に伸びたときに『何かが変わった』とすぐ気づけますし、対処の前後で測り比べれば、自分の変更が本当に効いたのかを客観的に判断できます。勘ではなく数字で語る——起動時間の改善は、その姿勢が最もはっきり実を結ぶ領域のひとつです。

この項目に出てくる用語

systemdしすてむでぃー
現代Linuxの標準的なinitシステム兼サービス管理基盤。unit単位で管理し、サービスを並列に起動する。
targetたーげっと
systemdで複数のunitをまとめた起動状態の単位。かつてのランレベルに相当する。
initいにっと
カーネルが最初に起動するユーザ空間プロセス(PID 1)。他のすべてのプロセスの起点となる。

関連コマンド

systemd-analyzesystemctljournalctl

▶ 学習アプリでこの続きを学ぶ・演習する