Pull to refresh

Comments 20

Да видимо раньше когда ничего не работало все и лазили руками по /proc, сейчас конечно не нужден этот текстовый формат.

С одной стороны стороны да, но вот как с помощью современных обёрток получить в шелл скрипте использованное процессом процессорное время с точностью хотя бы до сотой доли секунды без чтения /proc/$PID/stat? У меня сейчас это используется в самописном плагине для munin.

Сейчас никак, но если в ядре появится что-то похожее на task-diag с бинарным форматом, то так же появится и пользовательская команда, которая будет выводить нужную для пользователя информацию с той же точностью, которую предоставляет ядро.
Наверняка, вам в вашем плагине нужно получать cputime для всех процессов в системе. А теперь задумайтесь, сколько это займет времени, если это делать из шел скрипта.

Я провел небольшой эксперимент. Запустил 10000 процессов и запустил следующую команду:

# ps ax | wc -l
10091

# time for i in /proc/*/stat; do cat $i > /dev/null; done
cat: /proc/net/stat: Is a directory

real 0m21.923s
user 0m2.326s
sys 0m19.934s

20 секунд на 50K процессов. Имхо, это очень много.

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


$ time for i in /proc/*/stat; do cat $i >/dev/null ; done
cat: /proc/net/stat: Is a directory

real    0m0,373s
user    0m0,238s
sys 0m0,156s
$ time for i in /proc/*/stat; do read STAT < $i; done
-bash: read: read error: 0: Is a directory

real    0m0,012s
user    0m0,002s
sys 0m0,011s

Во-вторых, мне не нужно мониторить все процессы. Сейчас проверил — у меня мониторится 5 конкретных процессов. В этой ситуации при том, что мой плагин написан аккуратно и не делает лишних форков, тратится на сбор данных пренебрежимо мало времени, считанные миллисекунды.


Не поймите неправильно. Я не считаю внедрение нового интерфейса вредным или ненужным — совсем наоборот! Я только приводил контраргумент к тезису "сейчас не бывает задач, для которых нужно читать напрямую из procfs".


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

Да, с шельным скриптом я не додумал, точне я забыл про команду read. Тут вы правы, можно сделать быстрее.

Про то что ваш скрипт станет немного медленнее из-за лишнего форка, тут вы просто свой скрипт перепишите на python или любом другом языке, который сможет напрямую работать с новым интерфейсом и все будет хорошо.
Дело вовсе не в том, насколько баш-скрипт будет «быстрее» или «медленнее».

Дело в том, что bash/grep/sed/awk и 5 минут вашего ЦЕННОГО времени — и задача чего-то там выщемить/отмониторить решена. Прямо тут, прямо сейчас. В 98% на этом можно остановится — ибо задача решена. Если по ходу видно, что надо бы сэкономить ресурсов — можно думать дальше.
Во-первых, текущий /proc еще долго никуда не денется, обратную совместимость никто ломать не даст. Даже если его когда-то решат выкинуть из ядра, то появится fuse файловая система, которая будет выглядеть как /proc.
Во-вторых, если вы говорите про grep, sed, awk и тп, то вы уже готовы запускать дополнительные процессы, а значит сможете запустить и дополнительную тулзу, которая выдаст вам нужные данные, полученные через новый интерфейс.
В-третьих, если мы идем чуть дальше и вместо shell начинаем использовать что-то вроде python, то с новым интерфейсом вам жить будет даже проще.
Во-первых, текущий /proc еще долго никуда не денется

Я вам только что доступно объяснил — почему.

мы идем чуть дальше

Несколько условно — идя в любимый барбершоп и дойдя до него, вы:

1. заходите вовнутрь

2. «идете чуть дальше» километра на полтора, затем возвращаетесь и уже тогда заходите вовнутрь

Вы предлагаете (2). Дело ваше — спорить не буду.

Как сухой остаток — те 2%, что остаются после 98%, тоже надо чем-то делать. И это хорошо, что инструмент и для этого тоже постепенно затачивают.
> Я вам только что доступно объяснил — почему.

Смените тон и прочтите еще раз коментарий.

> Вы предлагаете (2). Дело ваше — спорить не буду.

В вашем примере, я как раз выбираю первый вариант. А второй вариант — это то как сейчас работает ps или top. Сначала ядро данные о процессах выдает в текстовом виде, потому утилита ps декодирует их к бинарному виду, обрабатывает и выдает в другом текстовом виде.

По поводу количества процессов. Если у вас речь идет о десятках процессов, то действительно проблем нет и с текущим интерфейсом.


Я все же предлагаю сравнить производительность task_diag и procfs для большого количества процессов.


Для эксперимента, я опять запустил 10000 процессов. Давайте теперь посмотрим сколько будет выполняться приведенный вами скрипт и получение тех же данных через task-diag.


# time for i in /proc/*/stat; do read STAT < $i; done
-bash: read: read error: 0: Is a directory

real    0m0.657s
user    0m0.138s
sys 0m0.515s

А теперь получим cputime через task_diag:


# time ./task_diag_all all -x  -q

real    0m0.041s
user    0m0.000s
sys 0m0.039s

Для понимания, вот пример данных, которые мы получаем через task_diag:


# ./task_diag_all one -x -p 1
Start getting information about 1
pid     1 tgid     1 ppid     0 sid     1 pgid     1 comm systemd
minflt:      8658
cminflt:  8320191
majflt:        78
cmajflt:      670
utime:        155
stime:       3704
cutime:      5201
cstime:     16716
threads:        1
НаверноеЗПТ интересно было бы узнать, насколько быстрее был бы вывод, если бы использовались бинарные данные напрямую, и если бы не требовалось три системных вызова.

Попытки создать такой интерфейс уже были. В 2004 пробовали использовать netlink движок.

В Solaris было как раз так, как вы мечтаете. Открываешь /proc, а там вместо текстовичков — бинарные файлы. В результате эти файлы, кажется, даже ps с top'ом не читали — обращались напрямую к ядру с запросами.
Про какие бы новые фишки в Linux мы не говорили, всегда кто-то скажет, что в Солярис все это было. Остается только один вопрос: «Почему не стало соляриса?». Судя по всему, это была ОС, которая сильно обогнала свое время.
Про какие бы новые фишки в Linux мы не говорили, всегда кто-то скажет, что в Солярис все это было.

Я не идеализирую Солярис, если вы об этом. Да и поработать под соляркой мне довелось недолго. Но да, это была прекрасно вылизанная, устойчивая и надежная операционная система с кучей продвинутых фишечек.
Почему ее не стало — вопрос настолько же провокационный, насколько и дурацкий. Но я вам попытаюсь ответить — так, как вижу со своей колокольни.

Поддержка коммерческой ОСи в актуальном состоянии — это большие расходы. Очень большие расходы. И эти расходы должны компенсироваться. Другими словами, ОСь должна приносить доход.
Очевидно, у фирмы SUN накопилось множество проблем, и разработка соляриса перестала быть прибыльной. Плюс активизировались конкуренты и заняли ниши, в которых раньше господствовал Сан. Оборудование на базе Интела стало дешевым, Линукс — несмотря на легкую топорность — все-таки оказался вполне работоспособным решением, и солярка умерла. Это бизнес.

К чести SUN, они сделали весьма многое, чтобы сохранить солярис. Проект OpenSolaris и портирование на архитектуру Intel — это по сути попытка сделать из солярки открытую операционную систему. Но — не срослось. Трижды тьфу на Оракл.

Судя по всему, это была ОС, которая сильно обогнала свое время.

Я бы не сказал, что она обогнала свое время. Скорее, это был продукт своего времени, но максимально вылизанный и хорошо продуманный. По крайней мере, такое впечатление он производил на неискушенного меня. :)
Извините, но абсурднее идеи представить сложно.
Зачем вы хотите из файловой системы proc читать бинарные данные? Читайте прямо из ядра.
Это долгая история, изначально мы использовали netlink сокеты, но потом пришли к тому, что к транзакционному файлу в /proc/. На самом деле в /proc достаточно много бинарных файлов: /dev/mem/, /dev/kmem, /proc/pid/pagemap, etc. В чем абсурдность идеи? Как вы бы это сделали?

А как это читать напрямую из ядра? Какие в линуксе еще есть способы получения информации о процессах? К примеру как их получает top/htop? Тормозов как описано в статье в htop я не замечал.

Спрашиваю, потому что не знаю, если знаете то просветите.

htop читается /proc. Вы можете это легко проверить, запустишь strace -fo htop.strace -s 1024 htop. Вы тормозов не видите, потому что у вас процессов мало. В критических ситуациях на больших серверах это становится реальной проблемой.

Не совсем понял из поста, вы хотите дополнить procfs ещё одним endpoint'ом с бинарным интерфейсом, или избавиться от plain text файлов?
Если первое — флаг вам в руки, новый производительный бинарный интерфейс для утилит — это, наверное, хорошо.
Если второе — как справедливо писали выше, иногда из какого-нибудь скрипта или приложения нужно просто заглянуть во вполне конкретный файл и достать кусочек информации, не всем нужно парсить полную информацию обо всём дереве процессов, поэтому удалять plain text не очень хорошо.
А поддерживать два более-менее одинаковых интерфейса в ядре — накладно. Думаю, что в том числе и из-за этого ваше предложение буксует столько времени. Правда, как это решить я тоже не знаю.
Речь идет о первом варианте, обратную совместимость никто не отменял. В будущем, генерацию этих файлов из ядра можно будет перенести в user-space, что-то вроде fuse файловой системы, но тут надо еще думать.

И вы совершенно правы, вопрос о поддержке двух интерфейсов регулярно возникает. Сейчас код написан так, что большая его часть шарится между procfs и task_diag.
Sign up to leave a comment.