Пироскоп — это программное обеспечение, которое позволяет вам непрерывно Профиль вашего кода для отладки проблем с производительностью до строки кода. Благодаря нескольким строкам кода это сделает следующее:
Агент пироскопа
- Опросы трассировки стека каждые 0,01 секунды, чтобы увидеть, какие функции потребляют ресурсы
- Пакеты, которые данные на 10-е годы и отправляют его на сервер пироскопа
Пироскоп сервера
- Получает данные из агента пироскопа и обрабатывает его, чтобы сохраняться эффективно
- Предварительные агрегаты профилирования данных для быстрого запроса, когда данные должны быть получены
Эффективность хранения
Задача с непрерывным профилированием заключается в том, что если вы просто принимаете частые куски данных профилирования, сжимаете его и храните его где-то, он становится:
- Слишком много данных для хранения эффективно
- Слишком много данных, чтобы запросить быстро
Мы решаем эти проблемы:
- Используя комбинацию попыток и деревьев для эффективного сжимания данных
- Используя сегментные деревья для возврата запросов для любого временного интерфейса данных в O (log n) vs o (n) сложность времени
Шаг 1: Поворот данных профилирования в дерево
Самый простой способ представления данных профилирования находится в списке строки, каждый из которых представляет собой трассировку стека и несколько раз, когда этот конкретный трассировку стека был замечен во время сеанса профилирования:
server.py;fast_function;work 2 server.py;slow_function;work 8
Первая очевидная вещь, которую мы делаем, мы превращаем эти данные в дерево. Удобно, что это представление также позволяет легко создавать фламфии.
Сжатие следов стека на деревья экономит пространство на повторных элементах. Используя деревья, мы идем от того, чтобы хранить общие пути, такие как net/http.request
В БД несколько раз приходилось только хранить его 1 раз и сохранить ссылку на место, в котором он находится. Это довольно стандартно с библиотеками профилирования, поскольку его самые низкие подвесные фрукты, когда речь идет о оптимизации хранения с данными профилирования.
Шаг 2: Добавление попыток хранить индивидуальные символы более эффективно
Так что теперь, когда мы сжали данные сырого профилирования, преобразуя в дерево, многие узлы в этом сжатом дереве содержат символы, которые также разделяют повторные элементы с другими узлами. Например:
net/http.request;net/io.read 100 samples net/http.request;net/io.write 200 samples
Пока net/http.request
, Net/io.read
и Net/io.write
Функции отличаются они разделяют один и тот же общий предком Net/
Отказ
Каждая из этих строк может быть сериализована с помощью префикса дерева следующим образом. Это означает, что вместо того, чтобы хранить те же префиксы несколько раз, теперь мы можем просто хранить их один раз в TRIE и получить доступ к ним, сохраняя указатель на их позицию в памяти:
В этом основном примере мы экономите ~ 80% пространства, проходящих от 39 байтов до 8 байтов. Как правило, имена символов намного дольше и по мере роста числа символов, требования к хранению растут логарифмически, а не линейно.
Шаг 1 + 2: Объединение деревьев с попытками
В конце концов, используя дерево для сжимания данных сырого профилирования, а затем использование попыток сжать символы, мы получаем следующие суммы хранения для нашего простого примера:
| data type | bytes | |---------------------|-------| | raw data | 93 | | tree | 58 | | tree + trie | 10 |
Как вы можете видеть, это 9x улучшение для довольно тривиального корпуса. В реальных сценариях сжатия фактор сжатия становится намного больше.
Шаг 3: Оптимизация для быстрого читания, используя сегментные деревья
Теперь, когда у нас есть способ эффективно хранить данные на следующую проблему, которая возникает, — это то, как мы запрашиваем ее эффективно. То, как мы решаем эту проблему, представляют собой предварительно агрегирующие данные профилирования и хранят его в специальном дереве сегмента.
Каждый агент Pyrocpope 10S отправляет кусок профилирования данных на сервер, Whuch записывает данные в БД с соответствующим временем. Вы заметите, что каждая запись происходит один раз, но реплицируется несколько раз.
Каждый слой представляет временную блоку более крупных блоков, поэтому в этом случае для каждых двух разных блоков 10-х годов создается один разряд 20-х годов. Это значит прочитать данные более эффективными (подробнее о том, что через секунду) Отказ
Поверните считываться от O (n) до O (log n)
Если вы не используете сегментные деревья и просто напишите данные в 10 секундных кусках. Сложность времени для чтения становится функцией того, сколько 10s единиц запроса просит. Если вы хотите 1 год данных, вам придется затем объединить 3154 000 деревьев, представляющих данные профилирования. Используя сегментные деревья, вы можете эффективно уменьшить объем операций слияния от O (n) до O (log n).
Помогите нам добавить больше профилистов
Мы провели много времени по решению этой проблемы хранения/запроса, потому что мы хотели сделать программное обеспечение, которое может сделать действительно непрерывный профилирование в производстве, не вызывая слишком много накладных расходов.
В то время как пироскоп в настоящее время поддерживает 4 языка, мы хотели бы добавить больше.
Любой производитель отбора проб, который может экспортировать данные в «RAW», связанный выше, может стать агентом профилирования с пироскопом. Мы бы любили вашу помощь, построенные профилистами для других языков!
Если вы хотите помочь вносят вклад или нуждаетесь в помощи настройки пироскопа, как вы можете добраться до нас:
- Присоединяйтесь к нашему Расслабиться
- Установите время, чтобы встретиться с нами здесь
- Написать проблема
- Следуйте за нами на Твиттер
Оригинал: «https://dev.to/ryan_perry_aa806d7a49198e/o-log-n-makes-continuous-profiling-possible-in-production-1377»