То нажмите l в окне atop, потом прощелкайте Enter до - Maximum lines for interface statistics и забивайте там нужное число, например - 10.
Thursday, 28 August 2014
Как починить падения Puppet DB от ошибок OOM killer?
Проявляется бага как:
В логе (/var/log/puppetdb/puppetdb-daemon.log ) при этом:
Warning: Error 400 on SERVER: Could not retrieve facts for ovz14.fastvps.ru: Failed to submit 'replace facts' command for ovzxxx.ru to PuppetDB at xxxxxx:8081: Connection refused - connect(2)
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Failed to submit 'replace facts' command for oxxxxs.ru to PuppetDB at xxxxx:8081: Connection refused - connect(2)
В логе (/var/log/puppetdb/puppetdb-daemon.log ) при этом:
# java.lang.OutOfMemoryError: Java heap space
# -XX:OnOutOfMemoryError="kill -9 %p"
# Executing /bin/sh -c "kill -9 15190"...
java.lang.OutOfMemoryError: Java heap space
Dumping heap to /var/log/puppetdb/puppetdb-oom.hprof ...
Heap dump file created [225222767 bytes in 1,713 secs]
Чиним, открываем конфиг: /etc/sysconfig/puppetdb и там заменяем Xmx192m на Xmx1024m.
Применяем:
/etc/init.d/puppetdb restart
Убеждаемся, что Java завелась с новым лимитом памяти:
ps aux|grep Xmx -i --color
puppetdb 29429 11.7 1.8 1654504 593832 ? Sl 11:35 0:26 /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java -XX:OnOutOfMemoryError=kill -9 %p -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/puppetdb/puppetdb-oom.hprof -Djava.security.egd=file:/dev/urandom -cp /usr/share/puppetdb/puppetdb.jar clojure.main -m com.puppetlabs.puppetdb.core services -c /etc/puppetdb/conf.d
Monday, 25 August 2014
perf trace - эффективная замена strace в ряде случаев!
perf trace /bin/echo "Php suxx"
0.000 ( 0.000 ms): ... [continued]: read()) = 0
Problems reading syscall 59(execve) information
0.288 ( 0.000 ms): ... [continued]: execve()) = 0
Php suxx
0.304 ( 0.001 ms): brk(brk: 0 ) = 9400320
0.320 ( 0.002 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -1309794304
0.329 ( 0.005 ms): access(filename: 140268025023360, mode: 4 ) = -1 ENOENT No such file or directory
0.337 ( 0.003 ms): open(filename: 140268025016833, flags: 0, mode: 1 ) = 3
0.340 ( 0.001 ms): fstat(fd: 3, statbuf: 140735595271856 ) = 0
0.343 ( 0.003 ms): mmap(addr: 0, len: 32186, prot: 1, flags: 2, fd: 3, off: 0 ) = -1309827072
0.345 ( 0.001 ms): close(fd: 3 ) = 0
0.355 ( 0.003 ms): open(filename: 140268027119178, flags: 0, mode: 0 ) = 3
0.357 ( 0.002 ms): read(fd: 3, buf: 140735595272280, count: 832 ) = 832
0.361 ( 0.001 ms): fstat(fd: 3, statbuf: 140735595271936 ) = 0
0.366 ( 0.003 ms): mmap(addr: 0, len: 3750152, prot: 5, flags: 2050, fd: 3, off: 0 ) = -1315766272
0.371 ( 0.004 ms): mprotect(start: 140268022771712, len: 2093056, prot: 0 ) = 0
0.376 ( 0.004 ms): mmap(addr: 140268024864768, len: 20480, prot: 3, flags: 2066, fd: 3, off: 1613824) = -1312055296
0.382 ( 0.003 ms): mmap(addr: 140268024885248, len: 18696, prot: 3, flags: 50, fd: 4294967295, off: 0) = -1312034816
0.386 ( 0.001 ms): close(fd: 3 ) = 0
0.396 ( 0.002 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -1309831168
0.401 ( 0.002 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -1309835264
0.405 ( 0.001 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -1309839360
0.407 ( 0.001 ms): arch_prctl(option: 4098, arg2: 140268027086592, arg3: 140268027080704, arg4: 34, arg5: 4294967295) = 0
0.459 ( 0.003 ms): mprotect(start: 140268024864768, len: 16384, prot: 1 ) = 0
0.467 ( 0.002 ms): mprotect(start: 140268027129856, len: 4096, prot: 1 ) = 0
0.472 ( 0.004 ms): munmap(addr: 140268027092992, len: 32186 ) = 0
0.531 ( 0.001 ms): brk(brk: 0 ) = 9400320
0.534 ( 0.002 ms): brk(brk: 9535488 ) = 9535488
0.545 ( 0.005 ms): open(filename: 140268022569584, flags: 0, mode: 140268024885264 ) = 3
0.547 ( 0.001 ms): fstat(fd: 3, statbuf: 140268024885312 ) = 0
0.552 ( 0.003 ms): mmap(addr: 0, len: 99158576, prot: 1, flags: 2, fd: 3, off: 0 ) = -1414926336
0.555 ( 0.001 ms): close(fd: 3 ) = 0
0.577 ( 0.001 ms): fstat(fd: 1, statbuf: 140735595273776 ) = 0
0.580 ( 0.002 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -1309798400
0.587 ( 0.004 ms): write(fd: 1, buf: 140268027121664, count: 9 ) = 9
0.592 ( 0.001 ms): close(fd: 1 ) = 0
0.596 ( 0.003 ms): munmap(addr: 140268027121664, len: 4096 ) = 0
0.599 ( 0.001 ms): close(fd: 2 ) = 0
0.602 ( 0.000 ms): exit_group(error_code: 0
Thursday, 14 August 2014
CPULIMIT, CPUUNITS и CPUS - детальное тестирование и описание параметров управляющих нагрузкой на CPU со стороне контейнеров OpenVZ
Выводы в самом конце - листайте :)
Тестовая среда: 2.6.32-042stab090.5, в контейнерах: Debian-7-x86_64 minimal. Процессор: 3.4 Ghz, число ядер: 8
На ноде выставлен режим максимальной частоты:
На машине 8 ядер
Два контейнера - 101 и 102, им по дефалту выдано: CPUUNITS="1000" CPUS/CPULIMIT не использованы.
Изучение поведения шедулера OpenVZ:
1) Запускаем stress --cpu 8 на первом контейнере:
2) Включаем ту же самую команду на второй машине (то есть теперь она включена на обоих). Получаем тоже самое:
open_vestat показывает следующее:
3) Меняем лимиты на 100:
И 10000:
Ничего при этом не меняется! Все ок, важно лишь отношение этих величин
4) Ставим неравные лимиты:
И сразу приоритет перешел к машине 101:
5) Теперь выдаем каждой машине ровно по 1 логическому ядру, тем самым ограничивая пиковую нагрузку на ядра:
Картина мгновенно меняется - ограничение на число ядер, которое может выедать машина включилось в действие.
Разделение как и прежде идеальное:
Мегагерцы также выдаются как и ранее:
6) Теперь выдаем каждой машине по 2 ядра:
Разделение продолжает быть идеальным:
Картина нагрузки следующая:
Для машины с 1 логическим процессором поидее поменяться нчиего не должно.
Ну в общем ничего и не поменялось:
Несмотря на наличие доступных ресурсов - машины обрезало строго по половине ядра.
И мегагерцы поменялись:
9) Срезаем нагрузку до 10:
10) отключаем один контейнер, второй оставляем с ограничнием в 10%:
11) Что будет если сделать --cpulimit 200 при выданном одном процессоре для контейнера? Да ничего плохого - больше 100% он не съест :)
12) Выдаем двум контейнера по два проца, но при этом жестко ограничиваем нагрузку 100% одного ядра:
В итоге каждая машина получит по 2 ядра, но по 1.7 Ghz (половина мощности ядра аппаратной ноды):
Схема нагрузки будет вот такая:
Схема нагрузки меняется мгновенно:
То ничего не поменяется, так как нету конкуренции за ресурс - у ноды достаточно ресурсов.
15) Устроим небольшой оверселл по ядрам:
16) Теперь рассмотрим интересный кейс - что будет какой контейнер позволит получить больше ресурсов. Контейнер с полным доступом к одному ядру или контейнер с двумя ядрами, но с лимитом суммарной нагрузки 50я % на каждое.
Но схема с полным доступом к одному ядру будет предпочтительнее при использовании ПО, которое плохо распараллеливается.
17) Рассмотрим кейс, когда контейнер с большим числом ядер получает меньший вес cpuunits, чем контейнер с меньшим числом ядер
Приоритет возьмет свое и вторая машина получи ресурсов больше:
18) Этот пункт я добавил уже после публикации статьи, он исследует кейс поведения, как поведут себя контейнеры с одинаковым CPUUNITS, но разным числом процессоров, выданных контейнеру:
Иными словами, довольно сложно дать приоритет контейнеру с 1 ядром, когда на ноде есть контейнеры с большим числом выданных ядер.
CPUS - задает число логичеcких процессоров, которые доступны контейнеру. Стоит понимать, что если выдать контейнеру 1 ядро, то его производительность будет жестко ограничена мощностью 1 ядра хост-сервера. Даже если на хост-серверер будут свободные ядра - контейнер их использовать не сможет. Это стоит учитывать всегда. Если данный параметр не указан или установлен в нуль - это означает, что контейнер может использовать все ядра хост-сервера.
Также стоит понимать, что логический процессор - это абстракция, в реальности процессы каждый раз выполняются на том ядре хост-сервера, у которого есть ресурсы.
Также параметр CPUS имеет важное значение при использовании параметра CPULIMIT.
CPULIMIT - задает максимальную суммарную нагрузку ядер контейнера. Максимально возможная нагрузка контейнера определяется так: N * 100, где N = числу ядер контейнера. То есть, если у контейнера 8 логических процессоров, то максимальное значение CPULIMIT может достигать 800.
В случае 1 процессора, выданного контейнеру, все просто - 50% означает 50% нагрузки на единственное ядро, то есть максимальная нагрузка на процессор ограничивается половиной ядра хост-сервера.
Если процессоров несколько, то все резко усложняется. Например, если задать CPULIMIT=100 для контейнера с двумя процессорами, то контейнер сможет нагружать каждое из выданных ему ядер не более чем на 50%.
Если же нужно полностью дать контейнеру, скажем, 4 ядра, то ему нужно выдать (4*100) CPULIMIT 400.
Именно этот параметр отображается внутри контейнера как частота виртуального процессора (Mhz /proc/cpuinfo). Частота рассчитывается вот так: HWN_FREQ * CPULIMIT / (100 * N_CPU), где N_CPU - число процессоров, выданных контейнеру. А HWN_FREQ - тактовая максимальная частота 1 ядра ноды. Например, в случае, когда у контейнера 2 ядра и CPULIMIT=100 мы получим: 1/2 HWN_FREQ (1.7 Ghz для моей тестовой ноды с процессором 3.4Ghz)
Лимит этот жесткий, то есть если на аппаратной ноде есть ресурсы, контейнер их не получит. Стоит обращать на это внимание!
CPUUNITS - задает отношение выделяемого процессорного времени одному контейнеру к другому. То есть, если задать для двух контейнеров 100 и 200, то второй получит вдвое больше ресурсов. CPUUNITS идеально работает когда контейнеру выдано 1 ядро. Но в случае многопроцессорных контейнеров и серьезной нагрузки на аппаратную ноду эти отношения перестают выполняться честно и второй контейнер будет получать больше ресурсов, чем первый, но не в два раза. Это объясняется особенности шедулера CFQ. Поэтому с разделением ресурсов между контейнерами с большим числом логических процессоров есть довольно серьезные проблемы.
Кого заинтересовала тулза open_vestat - могу поделиться, это скрипт обвязка cgroup на Perl, считает потребление cpu/blkio.time/blkio.sectors и отрисовывает топ10 грузящих контейнеров.
Тестовая среда: 2.6.32-042stab090.5, в контейнерах: Debian-7-x86_64 minimal. Процессор: 3.4 Ghz, число ядер: 8
На ноде выставлен режим максимальной частоты:
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
На машине 8 ядер
Два контейнера - 101 и 102, им по дефалту выдано: CPUUNITS="1000" CPUS/CPULIMIT не использованы.
Изучение поведения шедулера OpenVZ:
1) Запускаем stress --cpu 8 на первом контейнере:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]То есть машина получила все доступные ресурсы.
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
2) Включаем ту же самую команду на второй машине (то есть теперь она включена на обоих). Получаем тоже самое:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]Но теперь каждый контейнер грузит отдельно ядро не более чем на 50%.
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
open_vestat показывает следующее:
101: cpu: 50.1 %
102: cpu: 49.8 %
3) Меняем лимиты на 100:
vzctl set 101 --cpuunits 100 --save; vzctl set 102 --cpuunits 100 --save;
И 10000:
vzctl set 101 --cpuunits 10000 --save; vzctl set 102 --cpuunits 10000 --save;
Ничего при этом не меняется! Все ок, важно лишь отношение этих величин
4) Ставим неравные лимиты:
vzctl set 101 --cpuunits 100 --save; vzctl set 102 --cpuunits 200 --save;
И сразу приоритет перешел к машине 101:
101: cpu: 37.2 %Схема нагрузки на процы ноды:
102: cpu: 62.7 %
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5) Теперь выдаем каждой машине ровно по 1 логическому ядру, тем самым ограничивая пиковую нагрузку на ядра:
vzctl set 101 --cpus 1 --cpuunits 1000 --save; vzctl set 102 --cpuunits 1000 --cpus 1 --save;
Картина мгновенно меняется - ограничение на число ядер, которое может выедать машина включилось в действие.
1 [ 0.0%]
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [ 0.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5 [ 0.0%]
6 [| 0.7%]
7 [ 0.0%]
8 [ 0.0%]
Разделение как и прежде идеальное:
101: cpu: 49.8 %
102: cpu: 49.8 %
Мегагерцы также выдаются как и ранее:
vzctl exec 101 "cat /proc/cpuinfo|grep Mhz -i"; vzctl exec 102 "cat /proc/cpuinfo|grep Mhz -i";
cpu MHz : 3401.000
cpu MHz : 3401.000
6) Теперь выдаем каждой машине по 2 ядра:
vzctl set 101 --cpus 2 --cpuunits 1000 --save; vzctl set 102 --cpuunits 1000 --cpus 2 --save;
Разделение продолжает быть идеальным:
101: cpu: 49.8 %
102: cpu: 49.8 %
Картина нагрузки следующая:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]7) Вводим параметр cpulimit.
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [|| 1.3%]
5 [ 0.0%]
6 [ 0.0%]
7 [ 0.0%]
8 [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||99.3%]
Для машины с 1 логическим процессором поидее поменяться нчиего не должно.
vzctl set 101 --cpus 1 --cpulimit 100 --save; vzctl set 102 --cpulimit 100 --cpus 1 --save;
Ну в общем ничего и не поменялось:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]8) Срезаем пиковую нагрузку до 50:
2 [ 0.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [ 0.0%]
5 [ 0.0%]
6 [ 0.0%]
7 [ 0.0%]
8 [| 0.7%]
vzctl set 101 --cpus 1 --cpulimit 50 --save; vzctl set 102 --cpulimit 50 --cpus 1 --save;
Несмотря на наличие доступных ресурсов - машины обрезало строго по половине ядра.
1 [||||||||||||||||||||||||||||||| 49.3%]
2 [ 0.0%]
3 [||||||||||||||||||||||||||||||| 49.7%]
4 [ 0.0%]
5 [ 0.0%]
6 [ 0.0%]
7 [ 0.0%]
8 [| 1.3%]
И мегагерцы поменялись:
vzctl exec 101 "cat /proc/cpuinfo|grep Mhz -i"; vzctl exec 102 "cat /proc/cpuinfo|grep Mhz -i";
cpu MHz : 1700.500
cpu MHz : 1700.500
9) Срезаем нагрузку до 10:
vzctl set 101 --cpus 1 --cpulimit 10 --save; vzctl set 102 --cpulimit 10 --cpus 1 --save;И тут все работает идеально.
1 [||||||| 9.9%]
5 [ 0.0%]
2 [ 0.0%]
6 [ 0.0%]
3 [ 0.0%]
7 [ 0.0%]
4 [||||||| 10.5%]
8 [| 0.7%]
10) отключаем один контейнер, второй оставляем с ограничнием в 10%:
1 [||||||| 9.9%]И тут все ок!
5 [|| 1.3%]
2 [ 0.0%]
6 [ 0.0%]
3 [ 0.0%]
7 [ 0.0%]
4 [ 0.0%]
8 [ 0.0%]
11) Что будет если сделать --cpulimit 200 при выданном одном процессоре для контейнера? Да ничего плохого - больше 100% он не съест :)
1 [ 0.0%]
5 [| 0.7%]
2 [ 0.0%]
6 [ 0.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [ 0.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [ 0.0%]
12) Выдаем двум контейнера по два проца, но при этом жестко ограничиваем нагрузку 100% одного ядра:
vzctl set 101 --cpus 2 --cpulimit 100 --save; vzctl set 102 --cpulimit 100 --cpus 2 --save;
В итоге каждая машина получит по 2 ядра, но по 1.7 Ghz (половина мощности ядра аппаратной ноды):
vzctl exec 101 "cat /proc/cpuinfo|grep Mhz -i"; vzctl exec 102 "cat /proc/cpuinfo|grep Mhz -i";
cpu MHz : 1700.500
cpu MHz : 1700.500
cpu MHz : 1700.500
cpu MHz : 1700.500
Схема нагрузки будет вот такая:
1 [ 0.0%]13) Выдаем полную нагрузку по обоим ядрам:
5 [| 0.7%]
2 [ 0.0%]
6 [ 0.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [ 0.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [ 0.0%]
vzctl set 101 --cpus 2 --cpulimit 200 --save; vzctl set 102 --cpulimit 200 --cpus 2 --save;
Схема нагрузки меняется мгновенно:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]14) А если дать одному контейнеру приоритет в два раза:
5 [|| 1.3%]
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [ 0.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [ 0.0%]
4 [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||99.3%]
8 [ 0.0%]
vzctl set 101 --cpus 2 --cpulimit 200 --cpuunits 100 --save; vzctl set 102 --cpulimit 200 --cpus 2 --cpuunits 200 --save;
То ничего не поменяется, так как нету конкуренции за ресурс - у ноды достаточно ресурсов.
15) Устроим небольшой оверселл по ядрам:
set 101 --cpus 6 --cpulimit 600 --cpuunits 100 --save; vzctl set 102 --cpulimit 600 --cpus 6 --cpuunits 200 --save;
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]И при этом процессор поделится 1 к 2:
5 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||99.3%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
102: cpu: 66.5 %
101: cpu: 33.3 %
16) Теперь рассмотрим интересный кейс - что будет какой контейнер позволит получить больше ресурсов. Контейнер с полным доступом к одному ядру или контейнер с двумя ядрами, но с лимитом суммарной нагрузки 50я % на каждое.
vzctl set 101 --cpus 2 --cpulimit 100 --cpuunits 100 --save; vzctl set 102 --cpulimit 100 --cpus 1 --cpuunits 100 --save;Разделение при этом будет следующее:
1 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
5 [ 0.0%]
2 [ 0.0%]
6 [ 0.0%]
3 [ 0.0%]
7 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [ 0.0%]
8 [|| 1.3%]
102: cpu: 49.8 %
101: cpu: 49.8 %
Но схема с полным доступом к одному ядру будет предпочтительнее при использовании ПО, которое плохо распараллеливается.
17) Рассмотрим кейс, когда контейнер с большим числом ядер получает меньший вес cpuunits, чем контейнер с меньшим числом ядер
vzctl set 101 --cpus 10 --cpulimit 1000 --cpuunits 100 --save; vzctl set 102 --cpulimit 500 --cpus 5 --cpuunits 200 --save;Получим полную прогрузку машины:
1 [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||97.4%]
5 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
2 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
6 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
3 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
7 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
4 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
8 [||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]
Приоритет возьмет свое и вторая машина получи ресурсов больше:
101: cpu: 43.4 %Но тут нельзя сказать, что получит она ресурсов вдвое больше.
102: cpu: 56.4 %
18) Этот пункт я добавил уже после публикации статьи, он исследует кейс поведения, как поведут себя контейнеры с одинаковым CPUUNITS, но разным числом процессоров, выданных контейнеру:
vzctl set 101 --cpus 8 --cpulimit 800 --cpuunits 100 --save; vzctl set 102 --cpulimit 200 --cpus 2 --cpuunits 100 --save;А поведут они себя вот так (для чистоты эксперимента я запустил по 16 потоков утилиты stress в контейнерах):
101: cpu: 75.0 %То есть, контейнер, которому дали большую процессорную мощность получит приоритет в 3-4 раза, как и ожидается. Но стоит обратить внимание, что очень сложно выдать приоритет контейнеру, у которого меньше ресурсов даже силами CPUUNITS.
102: cpu: 24.8 %
Иными словами, довольно сложно дать приоритет контейнеру с 1 ядром, когда на ноде есть контейнеры с большим числом выданных ядер.
CPUS
Также стоит понимать, что логический процессор - это абстракция, в реальности процессы каждый раз выполняются на том ядре хост-сервера, у которого есть ресурсы.
Также параметр CPUS имеет важное значение при использовании параметра CPULIMIT.
CPULIMIT
В случае 1 процессора, выданного контейнеру, все просто - 50% означает 50% нагрузки на единственное ядро, то есть максимальная нагрузка на процессор ограничивается половиной ядра хост-сервера.
Если процессоров несколько, то все резко усложняется. Например, если задать CPULIMIT=100 для контейнера с двумя процессорами, то контейнер сможет нагружать каждое из выданных ему ядер не более чем на 50%.
Если же нужно полностью дать контейнеру, скажем, 4 ядра, то ему нужно выдать (4*100) CPULIMIT 400.
Именно этот параметр отображается внутри контейнера как частота виртуального процессора (Mhz /proc/cpuinfo). Частота рассчитывается вот так: HWN_FREQ * CPULIMIT / (100 * N_CPU), где N_CPU - число процессоров, выданных контейнеру. А HWN_FREQ - тактовая максимальная частота 1 ядра ноды. Например, в случае, когда у контейнера 2 ядра и CPULIMIT=100 мы получим: 1/2 HWN_FREQ (1.7 Ghz для моей тестовой ноды с процессором 3.4Ghz)
Лимит этот жесткий, то есть если на аппаратной ноде есть ресурсы, контейнер их не получит. Стоит обращать на это внимание!
CPUUNITS
Кого заинтересовала тулза open_vestat - могу поделиться, это скрипт обвязка cgroup на Perl, считает потребление cpu/blkio.time/blkio.sectors и отрисовывает топ10 грузящих контейнеров.
Tuesday, 12 August 2014
Монтирование /tmp на OpenVZ контейнерах в tmpfs
Самое интересное, что монтирование /tmp и прочих специализированных файловых систем осуществляет вовсе не нода, как можно подумать изначально. А сам контейнер. Поэтому в /etc/fstab в контейнере нужно прописать следующую строку:
Все смонтируется ок:
В OpenVZ нигде /etc/fstab не обрабатывается, поэтому можно делать не боясь, что конфигурация будет сброшена:
К сожалению, сам OpenVZ глобально управлять этим не умеет, а хотелось бы, поэтому прошу в баг трекер: https://bugzilla.openvz.org/show_bug.cgi?id=3040 и плюсуем таску :)
tmpfs /tmp tmpfs size=512m 0 0И после этого сделать команду:
mount /tmpИли перезапустить контейнер.
Все смонтируется ок:
cat /proc/mounts|grep 6617|grep '/tmp'А память в пределах tmpfs будет обсчитываться в контексте счетчика physpages контейнера и не требует дополнительных ограничителей.
tmpfs /vz/root/6617/tmp tmpfs rw,relatime,size=524288k,nr_inodes=153600 0 0
В OpenVZ нигде /etc/fstab не обрабатывается, поэтому можно делать не боясь, что конфигурация будет сброшена:
grep -HiR 'fstab' /etc/vz/dists/*|wc -l
0
К сожалению, сам OpenVZ глобально управлять этим не умеет, а хотелось бы, поэтому прошу в баг трекер: https://bugzilla.openvz.org/show_bug.cgi?id=3040 и плюсуем таску :)
Как выполнить MySQL запрос внутри OpenVZ контейнера на Debian
mysql -udebian-sys-maint --socket /vz/root/7431/var/run/mysqld/mysqld.sock --password=`cat /vz/root/7431/etc/mysql/debian.cnf|grep password |tail -n 1|awk '{print $3}'` -e "show processlist"
Monday, 11 August 2014
Подсчитать объем сетевых tcp буферов используемых VPS на OpenVZ
cat /proc/user_beancounters |egrep 'tcp(snd|rcv)buf'| perl -e 'my$rcv=0; my $snd=0; for(<>){my @data=split/\s+/; if ($data[1] eq 'tcprcvbuf') { $rcv+=$data[2] } else { $snd+=$data[2]}}; $snd=int $snd/1024**2; $rcv=int $rcv/1024**2; print "snd buffers: $snd MB rcv buffer: $rcv MB\n"'
snd buffers: 538 MB rcv buffer: 306 MB
snd buffers: 538 MB rcv buffer: 306 MB
Monday, 4 August 2014
Использование suexec на CentOS 5 в собственных целях
Готовим окружение:
Кладем вот туда вот такой код:
Меняем права:
Входим под апачем:
И получаем желаемое:
cd /var/www
mkdir /var/www/username
chown username:username /var/www/username
vim /var/www/username/suxx.sh
Кладем вот туда вот такой код:
#!/bin/bash
echo "suxx";
/usr/bin/id
Меняем права:
chown mamonov:mamonov /var/www/username/suxx.sh
chmod +x /var/www/username/suxx.sh
Входим под апачем:
cd /var/www/username
su apache -s /bin/bash
suexec username username suxx.sh
И получаем желаемое:
bash-3.2$ id
uid=48(apache) gid=48(apache) группы=48(apache)
bash-3.2$ suexec mamonov mamonov suxx.sh
suxx
uid=501(mamonov) gid=501(username) groups=501(username)
Рекомендую книгу: Сеть. Как устроен и как работает Интернет
Потрясающее произведение, которое открывает структуру сети Интернет с самого крупного масштаба. Здесь не будет описаний протоколов, тут не будет ничего про марки используемых оптических кабелей и ни слова настройке роутеров. Тут будет самое важное - описание того, что же на самом деле представляет собой Интернет.
Если для Вас сеть - нечто непонятно, работающее с помощью магии облако - эта книга для Вас. Вы сразу же поймете гениальную простоту архитектуры Интернета.
Это книга о людях и компаниях, которые создали Интернет. Тут объяснены причины успеха ИНтернета и причины его появления.
Если AMX-IX, DE-IX, Sprint, Cogent, Equnix, BGP - для Вас пустые слова, то эта книга для Вас.
Купить можно в Буквоеде (Спб) либо Озоне: http://www.ozon.ru/context/detail/id/26326082/ (на единственный идиотский отзыв призываю не обращать внимания).
А также Вы можете подписаться на Твиттер автора: https://twitter.com/ajblum
Если для Вас сеть - нечто непонятно, работающее с помощью магии облако - эта книга для Вас. Вы сразу же поймете гениальную простоту архитектуры Интернета.
Это книга о людях и компаниях, которые создали Интернет. Тут объяснены причины успеха ИНтернета и причины его появления.
Если AMX-IX, DE-IX, Sprint, Cogent, Equnix, BGP - для Вас пустые слова, то эта книга для Вас.
Купить можно в Буквоеде (Спб) либо Озоне: http://www.ozon.ru/context/detail/id/26326082/ (на единственный идиотский отзыв призываю не обращать внимания).
А также Вы можете подписаться на Твиттер автора: https://twitter.com/ajblum
Saturday, 2 August 2014
Subscribe to:
Posts
(
Atom
)