Datadog научила питоновский профилировщик дружить с asyncio
Главная засада в профилировании asyncio: любая таска выглядит как отдельный стек, и время, утопленное в запрос к Cassandra, повисает в вакууме — какой именно путь в приложении его породил, не ясно вообще. В Datadog решили так: профилировщик смотрит, кто кого ждёт, собирает дерево зависимостей и, идя от листьев, накладывает фреймы родителей поверх фреймов детей. Флеймграфы кода, раздробленного на таски, и обычных корутин внутри одной таски теперь выходят плюс-минус одинаковые. А если таска живёт дольше своего создателя, время капает создателю, пока он крутится, а потом — тому, кто её ждёт.
Плата за это нехилая: к цене на поток добавляется O(n_tasks), а на серверах задач до фига, так что адаптивный сэмплинг местами проседал до минимума — одна выборка в секунду. Резервуарное сэмплирование команда отвергла: для дерева нужны метаданные всех задач.
Оверхед срезали в три шага: выкинули C++ исключения из пути сэмплирования (около 15%), интернировали строки с именами функций и файлов (ещё около 25%), поменяли process_vm_readv на memcpy с обработчиком сигнала, чтобы восстанавливаться после ошибок памяти (около 50% для синхронного кода). Суммарно на сервисах с выкаченными изменениями оверхед просел больше чем на 60%. В проде профилировщик выловил бесконечный цикл в библиотеке pylzstring — её потом починили в апстриме — и внутреннюю библиотеку, которая клепала здоровенные debug-строки при логгере уровня INFO. Отдельно ИИ-агент через MCP и Dynamic Instrumentation оптимизировал функции на NumPy и срезал CPU в них на 15–30%. Всё это есть в свежих версиях ddtrace. Автор замечает, что похожий подход принят в Tachyon, профилировщике CPython 3.15, но сравнений не делает — как и абсолютных цифр по оверхеду.
Источник: datadoghq.com
👉 About Python
Post #3255
102
