Как узнать размер RAM в OpenVZ контейнере?

12
P
На сайте с 08.03.2007
Offline
250
2471

Задача: понять, сколько реальной памяти на VPS в данный момент.

Наваял я скрипт, может кто-то покритикует, или другую методику предложит? Идея в том, чтобы, забивая память мусором, проверить замедление чтения предыдущего заполненного фрагмента памяти, который при недостатке реальной памяти будет читаться из свопа. Размер блока и таймаут следует выбирать исходя из скорости процессора и скорости диска.

test-mem.pl

#!/usr/bin/perl
use strict;
$|=1;
my @a;
my $allocated=0;
my $blocksize=50;
foreach my $i(1..1024){
my $time = time();
my $s = '1' x ($blocksize*1024*1024);
push @a, $s;
$allocated += $blocksize;
print "\r$allocated Mb";
$s = $a[$i-10]; # read data - from swap slow!
if( time()-$time > 5 ){
print "\n$allocated Mb: Slow memory allocation\n";
last;
}
}
LineHost
На сайте с 20.01.2007
Offline
339
#1

1800 MbOut of memory! когда на ноде изпользуется всего лишь 2 ГБ из 8 :)

SERV.LT - Стабильные услуги хостинга, KVM VPS в Литве, Франции. (https://www.serv.lt/ru/vps/kvm/) Недорогие выделенные серверы (https://www.serv.lt/ru/dedicated-lt/) в Литве.
litos0
На сайте с 17.07.2008
Offline
122
#2

У OpenVZ интересная методика подсчета памяти внутри VE, так как занятой там считается та, которую поаллокейтили скриптом, а не ту, которая реально занята, поэтому вполне подобное сообщение можно наблюдать.

N
На сайте с 06.05.2007
Offline
419
#3

Кажется, лучше будет постоянное случайное чтение из всего массива, чтобы поддерживать в памяти весь массив. Первые элементы могут в своп уйти, а вы читате только последних 10.

и use Time::HiRes; он в стандартной поставке в нормальных дистрибутивах.

Кнопка вызова админа ()
P
На сайте с 08.03.2007
Offline
250
#4
netwind:
Кажется, лучше будет постоянное случайное чтение из всего массива, чтобы поддерживать в памяти весь массив. Первые элементы могут в своп уйти, а вы читате только последних 10.

и use Time::HiRes; он в стандартной поставке в нормальных дистрибутивах.

Да, что именно читать - это большой вопрос. Я и над случайным чтением думал, и над чтением нескольких случайных блоков данных, но там возникает элемент случайности. Идея в том, чтобы уловить момент попадания в своп первых же блоков. В идеале надо рисовать график, чтобы не вычислять производительность системы.

Time::HiRes использовать смысла нет - из-за случайных посторонних нагрузок на систему я 5 секунд выбрал, там миллисекундная точность не поможет.

Pilat добавил 15.03.2009 в 11:35

LineHost:
1800 MbOut of memory! когда на ноде изпользуется всего лишь 2 ГБ из 8 :)

И что этот результат значит? Наверно, что память вся реальная ?

LineHost
На сайте с 20.01.2007
Offline
339
#5

Раслабтесь, нормальные ноды обычно не уходит в своп. Точную проблему скажет только администратор ноды. График отработавшей год ноды. (Она уничтоженна, при первой перегрузке изчезнет.)

N
На сайте с 06.05.2007
Offline
419
#6

Pilat, случайности неслучайны. нужно читать в случайном порядке постепенно увеличивая диапазон этих случайных чисел. 1 секунда все же очень грубо.

P
На сайте с 08.03.2007
Offline
250
#7

Хорошо, вот другой скрипт. Читается 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;

}

N
На сайте с 06.05.2007
Offline
419
#8

Чето не очень. Но нужно проверять на практике. Возможно, даже так точность уже нормальная.

Во-первых, 10 случайных считываний кажутся слишком малым числом. Для такой принципиальной цели как выбор хостинга, стоит увеличить.

Во-вторых, чтение должно быть всего блока. Например, поиск в этой строке символа, которого нет изначально через функцию index. Иначе перл просто оперирует с указателями на блок ( вот это однозначно ляп)

LineHost
На сайте с 20.01.2007
Offline
339
#9
Pilat:

И что этот результат значит? Наверно, что память вся реальная ?

Видимо да. Но скорее всего то, что это не способ проверять качество VPS. Не память на данный момент проблема, а другие ресурсы.

А качество видно просто по первому заходу по SSH, а перед заказом - по цене ;)

P
На сайте с 08.03.2007
Offline
250
#10
netwind:
Например, поиск в этой строке символа, которого нет изначально через функцию index. Иначе перл просто оперирует с указателями на блок ( вот это однозначно ляп)

Вот в этом я не уверен - я специально вывел номера читаемых блоков, и номера не мгновенно выводятся, как можно было бы ожидать при указателях. К тому же мне надо минимизировать загрузку процессора, чтобы отловить обращение к свопу. В общем, я немного доделал скрипт, и на моей машине он отлавливает обращение к 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

LineHost:
Видимо да. Но скорее всего то, что это не способ проверять качество VPS. Не память на данный момент проблема, а другие ресурсы.
А качество видно просто по первому заходу по SSH, а перед заказом - по цене ;)

Ну вообще да, видно - только надо же знать что является нормой, а что отклонением. Моя же цель - понять сколько памяти. Например, мой vps показал, что из 2407124k памяти только 1900 попадает в реальную (я и на HN это отслеживал, так что результат правильный), остальное идёт в своп, и это хорошо заметно по падению скорости.

Хотя оверселлинг может быть заметен не сразу, так что практическая ценность моего скрипта сомнительна :( - только в тяжёлых случаях даст результат, который и так очевиден...

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий