← All posts tagged Python

fillest
хуйлоад Python gunicorn ? вебобляди нагрузил тут, значит, одну опердень, прикрутил zero downtime деплой. И тут, думаю, а дай-ка как раз заодно проверю, работает ли заявленная плавная перезагрузка воркеров у аппликейшен-сервака под нагрузкой. Написано ведь, что плавная по HUP, но мы же знаем как люди пишут софт, верно? Кочегарю тест, делаю sudo killall -v --signal HUP -r 'gunicorn: master.*huemoe', и что же я вижу? А вижу я мешок лиловых хуёв — d.maxfile.ro Как видно, секунд на 20 (двадцать) gunicorn перестаёт отвечать. К этому времени проц уже был плотно загружен, но чтоб на 20 секунд задуматься — никак не похоже это на то, что он сначала мол прогружает новые воркеры, а потом гасит старые.

В связи с этим вопрос, тестил ли кто-нибудь uWSGI в этом плане?
fillest
байтоебля log Python профайлер навыжимал тактов почти до упора, ня! И не зря — измерения перестали дребезжать.
Получилось завернуть весь луп в 'with nogil', а в 'with gil' — только необходимые места. В результате, в полную параллельность отправилось всё кроме непосредственно доставания стектрейсов.

В процессе, нашёл годный способ спать по интервалу с разумно-минимальным оверхедом: stackoverflow.com

На картинке результат профайлинга vtune'ом моего профайлера (с отключённым слипом). Оставшееся красное дрочево это неизбежный (без сатанинских обрядов) GIL и почти треть это двойной вызов clock_gettime (успокаивающее соотношение, кстати, это же два сраных даже не сисколла а vDSO; но реализацией GIL'а разочарован, он очень тяжеловесный). clock_gettime нужен для отладки латенси итераций и буден отключаемым.

Не знаю, понял ли кто чего, но вот держите для компенсации эфиопский джаз

fillest
profile Python пеарюсь работа perf Прокачал профайлер из #2772368, на пикрилейтеде подопытный кот и фрагмент его МРТ.

Писечка в том, что теперь оно группирует семплы по стектрейсам, и когда, например, в коде куча запросов к бд, в топ будет вылезать не совокупный схлопнутый recv сокета, по которому не понятно, какой именно запрос тормозил, а разные recv'ы по трейсам от конкретных запросов.

Эдакий недоflame graph, но у flame graph неудобный тулчейн, и я до сих пор не пойму, зачем видеть все лишние семплы, а не top N.

Mood: Lewis Parker — Communications (Feat. Jehst)

fillest
profile work Python perf nolife И тут же, с помощью #2772368 почти без боли отладили проблему с производительностью в продакшене. Прохладительная история:

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

Многие в таких ситуациях начинают искать по коду, что бы соптимизировать. Конечно, есть горстка хрупких эвристик, с помощью которых иногда можно быстро сузить поиск, но это, скорее, запутывает, поэтому следует запомнить и взять в привычку один метод — если сходу или за условные 15 минут не удаётся выявить точную ясную и полную логику проблемы, дальше продолжать бессмысленно и вредно, и необходимо воспользоваться специальными инструментами. Профайлером.

Ситуацию осложняет, однако, традиционное для индус-трии отсутствие вменяемых инструментов (почти для чего-либо вообще). То они тупо не работают, то не хватает функционала, то имеют грабительские цены (и работают ещё хуже), то установка или уровень удобства вызывает бешенство, и так далее. На этом многие ловят баттхёрт и возвращаются к отлаживанию по положению звёзд и кофейной гуще. Но, если ты у мамки настоящий инженер™, ты должен сохранять буддийское спокойствие и или заколотить-таки гвоздь подручным микроскопом, или быстренько™ сделать свой инструмент.

Long story short, запилил подходящий профайлер, посекундно выводящий, какие места в коде были самими горячими. В итоге, время процессора оказалось неожиданно тонко размазано по разным участкам цикла. На первый взгляд, это озадачивает, но всё логично — все манипуляции в этом цикле хавают примерно одинаковое время — затык в "языке" (интерпретаторе, стдлибе и т.п.). Но не только — если даже максимум вымазаться байтами, если поток логов ещё вырастет, оно может опять начать упираться в ядро. Собрали вече, решили, что эффективнее начать с распараллеливания, но это уже другая история.

Мораль — если тормозит, учитесь профайлить и профайлите без особых раздумий. Даже если окажется что-то "ожидаемое" или "очевидное" (я, кстати, ожидал увидеть другое, в данном случае), время будет потрачено не зря.

fillest
code debug profile draft Python
Семплирующий профайлер тут сочинил для рентгена змеедемонов в продакшене.

Для такого кота:
def main ():
	while True:
		time.sleep(0.2)
		time.sleep(0.3)
		time.sleep(0.5)
main()

высирает посекундно такое (пока текстом в лог, потом с уеб-мордой):
2015-03-03 23:52:29,849UTC INFO  collector_new.py:aggreg:49  ---
@@@ thread 140081144379200
49.7% ('perstam/sampler_new.py', 96, 'main') time.sleep(0.5)
28.9% ('perstam/sampler_new.py', 95, 'main') time.sleep(0.3)
21.4% ('perstam/sampler_new.py', 94, 'main') time.sleep(0.2)
2015-03-03 23:52:30,851UTC INFO  collector_new.py:aggreg:49  ---
@@@ thread 140081144379200
48.7% ('perstam/sampler_new.py', 96, 'main') time.sleep(0.5)
31.6% ('perstam/sampler_new.py', 95, 'main') time.sleep(0.3)
19.8% ('perstam/sampler_new.py', 94, 'main') time.sleep(0.2)