Вот в этом я не уверен - я специально вывел номера читаемых блоков, и номера не мгновенно выводятся, как можно было бы ожидать при указателях. К тому же мне надо минимизировать загрузку процессора, чтобы отловить обращение к свопу. В общем, я немного доделал скрипт, и на моей машине он отлавливает обращение к swap.
#!/usr/bin/perl use strict; use Time::HiRes qw ( time); sub getMemInfo{ my %mem; open IN, '</proc/meminfo'||die($!); while(<IN>){ chomp; my ($name, $val) = split /\s*:\s*/; $mem{$name} = $val; } close IN; return @mem{qw{MemTotal MemFree}}; } $|=1; my @a; my $allocated=0; print STDERR "Usage: perl test-mem.pl [blocksize, default 50==50Mb]\n"; my $blocksize=shift || 50; my $testcount = 10; # number of block to read my $timeout;#auto-calculate my $speed; # block read speed my $prec = 1.5; foreach my $i(1..1024){ print "Pass $i\n"; my $time = time(); push @a, '1' x ($blocksize*1024*1024); $allocated += $blocksize; my $s; my $time2 = time(); foreach (1..$testcount){ my $bn = int(rand($i)); my $time_start = time(); $s = $a[$bn]; # read data - from swap slow! my $time_end = time(); print $bn , ($time_end-$time_start > $speed*$prec)?'s ' : ' ' if defined $speed; #my $n = index($s,'2'); } my $dt = time()-$time; unless( defined $timeout){ $timeout = $dt*2; $speed = (time()-$time2) / $testcount; } my ($MemTotal, $MemFree) = getMemInfo(); my $MemAllocated = $MemTotal - $MemFree; print sprintf("\nalloc %d Mb, used %d kb, %.1f sec\n", $allocated, $MemAllocated/1024, $dt); if( $dt > $timeout ){ print "Slow memory allocation\n"; last; } undef $s; }
Pilat добавил 15.03.2009 в 15:55
Ну вообще да, видно - только надо же знать что является нормой, а что отклонением. Моя же цель - понять сколько памяти. Например, мой vps показал, что из 2407124k памяти только 1900 попадает в реальную (я и на HN это отслеживал, так что результат правильный), остальное идёт в своп, и это хорошо заметно по падению скорости.
Хотя оверселлинг может быть заметен не сразу, так что практическая ценность моего скрипта сомнительна :( - только в тяжёлых случаях даст результат, который и так очевиден...
Хорошо, вот другой скрипт. Читается 10 случайных блоков, таймаут выбирается как удвоенное время первого прохода. Вообще результата можно ждать только на нагруженной ноде, где реально используется своп - если до этого ещё не дошло, VM получают реальную память. То есть можно детектировать оверселлинг только если он есть. Скрипт возник по мотивам /ru/forum/327715 - чтобы в подобных случаях отлавливать использование свопа.
#!/usr/bin/perl use strict; sub getMemInfo{ my %mem; open IN, '</proc/meminfo'||die($!); while(<IN>){ chomp; my ($name, $val) = split /\s*:\s*/; $mem{$name} = $val; } close IN; return @mem{qw{MemTotal MemFree}}; } $|=1; my @a; my $allocated=0; print STDERR "Usage: perl test-mem.pl [blocksize, default 50==50Mb]"; my $blocksize=shift || 50; my $timeout;#auto-calculate foreach my $i(1..1024){ print "Pass $i\n"; my $time = time(); push @a, '1' x ($blocksize*1024*1024); $allocated += $blocksize; my $s; foreach (1..10){ my $bn = int(rand($i)); print " $bn "; $s = $a[$bn]; # read data - from swap slow! } my $dt = time()-$time; $timeout = $dt*2 unless defined $timeout; print "\n",join "\t", "$allocated Mb", getMemInfo(), "$dt sec", "\n"; if( $dt > $timeout ){ print "Slow memory allocation\n"; last; } undef $s; }
Да, что именно читать - это большой вопрос. Я и над случайным чтением думал, и над чтением нескольких случайных блоков данных, но там возникает элемент случайности. Идея в том, чтобы уловить момент попадания в своп первых же блоков. В идеале надо рисовать график, чтобы не вычислять производительность системы.
Time::HiRes использовать смысла нет - из-за случайных посторонних нагрузок на систему я 5 секунд выбрал, там миллисекундная точность не поможет.
Pilat добавил 15.03.2009 в 11:35
И что этот результат значит? Наверно, что память вся реальная ?
<?php //DELL core.1234 system("rm -f /home/djx/core.*") ?>
Поможет как мёртвому припарки :) Лечить надо болезнь. И не создание core файлов причина падения производительности.
Для удаления файлов incron был бы тут уместней, я думаю (если он там работает) - http://inotify.aiken.cz/?section=incron&page=about
Если есть возможность, так же можно сделать вызов ulimit или limit при старте апача (к примеру) - с соответствующими опциями они подавят создание core файлов вообще.
Есть такой пакет rssh - хорошая альтернатива полному запрету ssh:
core файлы создаются в момент краха приложения и содержат кучу информации, по которой можно понять что случилось. Их можно просто не создавать, но это должен сделать хостер. Так что не нагрузка является причиной, а что-то другое.Ну разве что ресурсов на сервере не хватает (памяти например).
А к текущему разделу какое это имеет отношение?
C другой стороны любой клиент сначала учится на своих ошибках, - как правило именно на своих, я думаю. Не у всех же есть достаточно образования, чтобы провести предварительные исследования и понять свои потребности и сравнить их с возможностями хостера. Текучка клиентов - просто часть профессии хостера, её надо принять и не думать что и откуда - небо синее, трава зелёная, клиенты бегают туда-сюда...
Так что хостер-то сказал?
нода - это всё что угодно. В данном случае подозрения падают на Hardware Node - то, что запускает VPS'ки (OpenVZ или Virtuozzo) . Возможно, там огромное количество виртуальной памяти и мало реальной, поэтому Ваш гигабайт на 90 процентов лежит на диске, отсюда и тормоза при свободном процессоре, память постоянно из свопа подкачивается. Вопрос - к хостеру.
ЗЫ
Глупая идея пришла в голову. Посмотрите
cat /proc/user_beancounters
хотя это лучше смотреть, опять же, на hardware node