1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
r/outside

A subreddit for Outside, a free-to-play MMORPG with 7 billion+ active players.
🔥9😁9🤮1💩1🤡1
21💩2🤡1🤨1😐1
😁62🤔1🎉1
#meme про метрическую систему мер (точнее, отсутствие таковой)
😁26🤯1
#prog

А ещё, так как форк открытый, это и #amazingopensource
Тут Флант Prometheus форкнули переписали с кучей оптимизаций. Пост на Хабре большой с кучей подробностей + провели сравнение с VictoriaMetrics. Сам я ещё, естественно, не успел попробовать, но выглядит многообещающе

Если подобным образом проанализировать все лейблы на реальных данных, получится, что:

- 32,7 % из них имеют всего одно возможное значение, например true или 0;
- 60 % — от 2 до 255 значений, то есть укладываются в 1 байт;
- 7,3 % — от 256 до 5275 значений;
- 0 % — больше 65 535 значений.

Это значит, что все возможные значения укладываются в два байта.

Мы решили хранить все ID (#0, #1, #2 и т. д.) не в четырёхбайтных значениях, а как два бита, указывающие количество байт, в которые укладывается число, плюс значение.

Это дало нам очередной выигрыш по памяти — теперь весь labelset для 1 миллиона метрик стал занимать 30 МБ. Это в 30 раз лучше стартовых 762 МБ.
. . .
Оптимальное хранение строк дало приличный выигрыш и в индексе. Если раньше в нём были строки и хэш-таблицы, которые не особенно оптимально хранятся в памяти, то в нашей реализации есть ID, которые выдаются по порядку. Это позволяет хранить в кэше четырехбайтные числа uint32 и заменить хэш-таблицы на sparse-векторы и Bitset.

В итоге основным потребителем памяти у нас стали точки. Prometheus хранит их достаточно компактно: он использует Gorilla Encoding и битовые операции. Это не значит, что оптимизировать нечего, но для этого надо внимательно посмотреть на данные.
. . .
Оказалось, что уникальных последовательностей временных меток всего 10 % от миллиона. Эта оптимизация позволила выиграть 55,5 % по памяти просто за счёт дедупликации.
. . .
После всех преобразований мы получили выигрыш по хранению точек почти в три раза: изначальные 787,72 МБ превратились в 283,9 МБ. При этом чем больше данных и серий, тем лучше срабатывает наша оптимизация. Если на одном миллионе метрик мы выиграли по хранению точек в 2,7 раза, то на трёх миллионах это будет уже три с небольшим раза.
. . .
В процессе работы Prometheus пишет WAL. Мы оптимизировали журнал предзаписи примерно в 19 раз. Изначальные 6,2 ГБ без сжатия в Prometheus v2 для 1 миллиона метрик превратились в 153 МБ в Deckhouse Prom++.

Deckhouse Prom++: мы добавили плюсы к Prometheus и сократили потребление памяти в 7,8 раза
https://habr.com/ru/companies/flant/articles/878282/
+
Deckhouse Prom++
https://github.com/deckhouse/prompp/

Чат: @prom_plus_plus
❤‍🔥14🔥5👎1
#music

Буквально любимый трек в One finger death punch. Жаль, что в игре урезанная версия.

https://jessevalentinemusic.bandcamp.com/track/shaolin-warrior
1👎1🤔1
#prog #article

Shrinking your code review

It's an unfortunate reality, but one of the few things we know about software quality is that lines of code is positive correlated with bugs, <...>. Code review faces a similar challenge: the larger a patch you're reviewing, the less effective your code review is
<...>
Fundamentally there's only two ways to get smaller reviews: write less code or split your changes up across multiple reviews. I'm not going to focus on writing less code, a great much about has been written about this topic. Instead I'm going to focus on how to split up your changes.

Набор практических советов на тему того, как уменьшать размер кода для ревью.
👍9🤔1
Forwarded from шитпостинг.
AI всех заменит или удалит
🎉18🤣10😢9😭3🫡3😁1
#meme про процессорные архитектуры
😁28👎4🤣3💩2🥴1
🧠 Как 3 вечера анализа и оптимизаций дали минус 1 CPU и +40% к скорости ответов API

👀 Всё началось с того, что я случайно (ну как случайно, проблема была всегда, просто я первый задался вопросом - "почему?") заметил, что один Python-сервис на staging потребляет до 2.5 CPU.
Для сравнения — весь namespace потребляет около 6 CPU. То есть один сервис ест почти половину ресурсов. И это при том, что это не какой-то нагруженные сервис, это синхронный API-сервис, да еще и без нагрузки, это же staging.

Стало интересно — а что там внутри вообще так жрёт?

📦 Запустил профайлинг CPU через Pyroscope и… понеслось.

UI у Pyroscope меня не устроил — флеймграфы красивые, но неудобные для глубокого анализа.
📥 Поэтому я выгрузил дамп как pprof файл и открыл его через go tool pprof.
Так мне удобнее, быстрее и информативнее.

📊 Профилирование показало несколько важных узких мест:

🧱 Проблема №1: конвертация данных из MySQL

Самое "жирное" место — conversion.pyMySQLConverter.row_to_python.
Это код, который конвертирует строки из БД в Python-объекты на каждый запрос.

Наиболее затратные конвертации:
- _DECIMAL_to_python
- _INT_to_python
- _JSON_to_python
- _DATETIME_to_python
- _STRING_to_python

Решение:

📌 Использовал C extension у mysql-connector-python
Официальная документация: https://dev.mysql.com/doc/connector-python/en/connector-python-cext.html

📉 Результат:
- Минус 1 CPU
- До +40% ускорение некоторых endpoint’ов

🧠 Проблема №2: неэффективный Python-код

Пример: функция change_type, которая:
- делает кучу проверок в логике
- использует неэффективные структуры данных, например, list для поиска вместо set / dict
- обрабатывает сразу множество возможных вариантов логики, в зависимости от входных данных

Решение:

📌 Переписал участок без изменения бизнес-логики:
- заменил структуры данных
- добавил ранние выходы
- убрал дублирующиеся проверки

📌 Cognitive complexity снизилась, временная сложность — тоже. Производительность выросла.

⚠️ Проблема №3: код, который не нужен, но работает

Профайлинг показал, что куча ресурсов уходит на код, который вообще не должен уже как год использоваться. Но код активно выполняется. WTF!?

🤷‍♂️ Функции вызываются, результат — пустой, но код исполняется. Причём часто и тяжело.

Решение:

📌 Удалил мёртвый код, обновил импорты, подчистил зависимости.
📌 Поднял вопрос о полной деактивации этого кода и мы таки это сделали — ресурсы можно использовать лучше.

🐘 Проблема №4: Импорты. Много. Дорого.

Во время анализа я наткнулся на ещё одну тихую, но дорогую проблему — огромные ресурсы уходят на фазу импорта модулей в Python.

Конкретно — на _find_and_load, часть механизма импорта, который занимается поиском, загрузкой и инициализацией модулей.

📌 Почему это важно?
- Импорты выполняются на каждый старт сервиса.
- Чем жирнее и зависимее ваши модули, тем дольше и тяжелее проходит импорт.
- Это не всегда очевидно, но можно видеть в профайлинге: _find_and_load, _find_and_load_unlocked, _load_unlocked – вот это всё.

📊 У нас в сервисе модулей реально много.
Многое из них – просто "свалены в кучу", где-то грузятся тяжёлые зависимости. Да и сложная структура проекта вынуждает иметь большое количество импортов.
И, как итог, CPU тратится на то, что можно было бы стремиться избежать.

Что с этим делать:
- Разделять модули по функциональности.
- Отложенные импорты (lazy import) – практика может применяться (но есть нюансы), если модуль нужен только в конкретной функции.
- Минимизировать зависимости и импорт только того, что действительно нужно.
- Следить за импортами в __init__.py — именно они могут тянуть за собой пол кодовой базы.

Следующий шаг: memory профайлинг. Pyroscope в нашей инфрастуктуре такое не умеет и нужно приседать, но надеюсь дойдут руки и до RAM.
👏12🤡5👍21