web-dev-qa-db-ja.com

ユーザーごとの合計CPU時間を監視する最も公平な方法は何ですか?

マルチユーザーシステムでは、各ユーザーのCPU使用率をCPU時間の秒単位で測定します。この測定のために、PIDがユーザーに属している場合、このユーザーがCPU時間を引き起こしていると想定します。つまり、デーモンとカーネルを無視しています。

現在、5秒ごとにこれを行っています。

  1. ps auxを介して、各ユーザーと実行中のPIDを取得します
  2. 各PIDについて、xtime、cutime、stimeおよびcstimeの合計/proc/[pid]/stat を取得します
  3. t = x / intervalを計算します(負荷が高い場合、間隔は常に正確に5秒とは限りません)

これを実行すると、賢明な見た目の値が得られます。たとえば、このシステムのユーザーはpython(while True: pass)でスピンし、システムは毎秒約750ミリ秒のCPU時間を示していました。システムが少しハングしたとき、1秒のインバーバルにつき1600msと報告されました。これはほぼ正しいように思えますが、これらの値が偽物である可能性があることは理解できません。特に、本当にそれらを理解していない場合、.

だから私の質問はこれです:

ユーザーごとにCPU負荷を測定する公正で正しい方法は何ですか?

メソッドはかなり正確でなければなりません。このシステムには何百人ものユーザーがいる可能性があるため、ps auxからパーセンテージを抽出することは、特に多くのソフトウェアが生成することを好む短命のスレッドの場合、十分に正確ではありません。

これは複雑かもしれませんが、それが可能であることは絶対に知っています。これが私の出発点でした:

カーネルは、プロセスの作成時間と、その存続期間中に消費するCPU時間を追跡します。クロックティックごとに、カーネルは現在のプロセスがシステムモードとユーザーモードで費やした時間を一瞬で更新します。 —( Linux Documentation Project )から

後の値は、ユーザーがCPUに費やした秒数(またはjiffies)であり、システム負荷やCPU使用率のパーセンテージではありません。

プロセスの実行中にCPU時間を測定することが重要です。プロセスのなかには0.5秒しか続かないものもあれば、数か月続くものもあります。両方の種類をキャッチして、ユーザーのCPU時間をきめ細かく把握できるようにする必要があります。

25
Stefano Palazzo

プロセス会計が必要なようです。

http://www.faqs.org/docs/Linux-mini/Process-Accounting.html

Ubuntuでは、プロセスアカウンティングツールは acctパッケージInstall acct

ユーザーごとのレポートを取得するには、次を実行します

sa -m
11
Alan Bell

これにより、ユーザー名と合計CPU時間を示す各ユーザーの行が表示されます。

ps -w -e --no-header -o uid,user \
        | sort -u \
        | while read uid user; do
                echo -e "$user\t"$(
                        ps --no-headers -u $uid --cumulative -o time \
                                | sed -e s/:/*3600+/ -e s/:/*60+/ \
                                | paste -sd+ \
                                | bc
                );
        done
2

より明白な答えの1つは、現在あなたが現在していることを単に拡張することです。

Bashスクリプトとmysqlを使用してユーザーのCPU時間を追跡するためのこのモニタープロセスに出会いましたが、それはあなたが話していたよりもはるかに長い時間枠にまたがっていました。

うまくいけば、これがあなたが向かう方向についてのより多くのアイデアをあなたに与えることができるでしょう。

http://www.dba-Oracle.com/t_Oracle_unix_linux_vmstat_capture.htm

2
Linztm

これは、数日間実行されていたプロセスも処理します。数週間/月/年拡張する方法がわからない.

ps -w -e --no-header -o uid,user \
    | sort -u \
    | while read uid user; do
            echo -e "$user\t"$(
                    ps --no-headers -u $uid --cumulative -o time \
                          | sed -e s/-/*86400+/ -e s/:/*3600+/ -e s/:/*60+/ 
                          | paste -sd+ \
                          | bc
            );
    done
0
Patrik Arlos