web-dev-qa-db-ja.com

メモリ使用量をチェックして対応するための1行のスクリプト

これらの線に沿って何かを行うシェル/ bashの1行が欲しいのですが:

test "`free | grep | awk | whatever` -gt 80" && any_command

RAMの合計パーセンテージシステム全体で使用されている場合は、ハードコードされた数値(私の場合は80)と比較されます。 testは、any_command ramが指定されたパーセンテージよりも高い場合に実行されます。

  • パーセンテージの代わりに正確なバイト/メガバイトは問題ありません
  • これは典型的なubuntu14.04で動作するはずです
  • cronジョブとしての使用を目的としています
  • ボーナス:同じことをするが、特定のプロセスについてRAMをチェックするワンライナー

更新

これが、monit/bluepill/godのようなものが解決するために構築されている問題であるという答えがあります。私は100%同意します、そしてあなたはおそらくそれらの答えのアドバイスに従うべきです。ただし、この質問は、理由が何であれ、これに関連する可能性のあるすべての警告と問題を想定して、私が説明した正確な行に関するものです。

3
Max Chernyak

どうですか:

[ $(free -m| grep  Mem | awk '{ print int($3/$2*100) }') -gt "80" ] && echo "greater " || echo "lesser"

そして、プロセス消費のために、ここにソリューションの可能な部分があります:

for p in $(pgrep bash); do total=$(($total + $(awk '/VmSize/ { print $2 }' /proc/$p/status))); done ; echo "Total memory usage: $total kb" ; unset total

それらの両方を組み合わせることは、読者への課題として残されています。

5
aif

車輪の再発明をしないでください:)

Monitユーティリティ は、このような状況を処理するために作成されています。それは 十分に文書化された であり、たくさんの ここServerFaultの例 があります。

  check system kale.GreenLeaf.com
    if loadavg (5min) > 16 for 15 cycles then alert
    if memory usage > 92% then alert
    if swap usage > 10% then alert

またはプロセスの場合:

check process cups
    with pidfile "/var/run/cupsd.pid"
    start program = "/sbin/service cups start"
    stop program = "/sbin/service cups stop"
    if 10 restarts within 11 cycles then timeout
    if total memory > 1000.0 MB for 5 cycles then alert
    if total memory > 2000.0 MB for 5 cycles then restart
    if cpu usage > 95% for 11 cycles then restart

アラートまたは開始/停止/再起動アクションの代わりに、EXECを構成できます。

EXECを使用して任意のプログラムを実行し、アラートを送信できます。このアクションを選択する場合は、実行するプログラムを指定する必要があり、プログラムに引数が必要な場合は、プログラムとその引数を引用符付きの文字列で囲む必要があります。オプションで、実行されたプログラムが起動時に切り替わるuidとgidを指定できます。

if total memory > 2000.0 MB for 5 cycles then exec "/sbin/service sidekiq restart"
5
ewwhite

正確に何を達成しようとしていますか?あなたはおそらくそれを間違ってやろうとしているのです。

_[ $(free | Perl -nE 'if (/Mem/) { (undef,$total,$used) = split; say int(100*$used/$total) }') -gt 80 ] && echo foo
_

しかし、あなたがそれで達成しようとしていることはほとんど確実に役に立たない(そして恐らく有害でさえある)ことに注意してください。 「パーセンテージRAM使用中)」のようなものはありません。はい、freeは「空き」メモリの量を示しますが、それはおそらくあなたが考えていることを意味するものではありませんそれは意味します(そのフィールドは「無駄」または「決して購入すべきではなかった量のメモリ」という名前が付けられます)。

たとえば、カーネルはプログラムをメモリに「ロード」せず、それらをマップするため、数百MBのサンプルプログラムの中には、わずか12KBでも実行できるものがあります。また、アクセスされたすべてのファイルは同じメモリ(ページキャッシュと呼ばれます)にキャッシュされます-過去に実行されたプログラム(再度実行された場合、そのファイルはキャッシュされます)と読み取り/書き込みされたデータファイルに違いはありません過去(したがって、再度アクセスすると高速になります)

したがって、メモリよりも多くのディスクがある場合(通常の場合)、「空き」(別名「無駄」)メモリは、起動後すぐに100%近くに収束します(実際には、カーネルが維持しようとするため、80〜95%のようになります)。一部のメモリは解放されているので、メモリが不足している場合でもすぐにアクセスできます)。これは正常であり、実際に必要とされています。ディスクへのアクセスが大幅に高速化されるため(最良の場合)、同じファイルに再度アクセスするものがない場合は「メモリの解放」と同等になります(最悪の場合)。

したがって、実際には、メモリを「解放」することを回避したいと考えています(これは、メモリを大量に消費するプログラムが停止した後に時々発生します)。

Edit1:また、上記の結果は、そのような質問が定義されていないため、考えられる(そしてまったく異なる)答えにすぎません。たとえば、「Mem used」の代わりに、「Mem used-cached」(ディスクキャッシュを差し引いたときに使用されているメモリの量を示します)を使用できます。これにより、代わりに「15%」のような結果が得られる可能性があります。 「80%使用済み」)、より正確な場合があります-何を達成しようとしているのかによって異なります

プロセスのメモリ使用量についても同じです。プロセスが使用するメモリの量を言う方法は多すぎます。プログラムに必要な量です(ps出力のVSZ)。または、現在RAM(RSS列)にある量)。共有コードを持つインスタンスが複数ある場合はどうでしょうか(たとえば、それぞれ50MBのRSSのApacheプロセスが100ある場合、100を使用しません。 * 50 = 5000MB RAM、ただし全体で200MBに近い)など。必要なものが正確にわかっている場合にのみ、計算に進むことができます(VSZのみ、RSSのみ、RSS共有、またはRSS共有/数値) -of-processses-sharingなど)

また、このタイプの質問は、 superuser.com でより話題になっていることに注意してください。

Edit2:コメントに関しては、メモリリークを回避しようとしているのは何らかのプロセスです。空きメモリをチェックすることは、誤検知を引き起こすため、間違いなく間違っています。メモリリークによってシステムの残りの部分がダウンするのを防ぐために、プロセスを制限する必要があります(bashの_help ulimit_を参照)。プロセスはそれを処理する(良い)か、必要な量のメモリを取得できないときに終了する可能性があるため、(monit、supervise、runitなどを使用して)プロセスを再起動できます。

Edit3:プロセス制限の設定に加えて(または代替として、しかし本当に良いことに加えて)、RSSのときにプロセスを再開するためにこのようなものを使用できます大きくなりすぎます。

_[ $(awk '/^VmRSS/ { print $2}' /proc/$PID/status) -gt 200 ] && echo killmeplease
_

_$PID_の代わりに、もちろんPIDを使用します(たとえば、PID=$(cat /var/run/something.pid)またはPID=$(pidof somedaemon)などから)。

ただし、(VmSize)の代わりにVmPeak(またはVmRSS)を使用する方がよいことに注意してください。そうしないと、プロセスがスワップした場合にシステムをダウンさせる可能性があります(したがって、VmSizeは大きくなり、VmRSSは小さくなります)

2
Matija Nalis