Обновить
128K+

Высоконагруженные системы *

Методы получения высокой производительности систем

192,76
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

HikariCP в проде: три раза, когда пул соединений уронил сервис, и почему maximumPoolSize тут был ни при чём

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели6.6K

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

Горел. Ещё как.

Это продолжение того же разбора, но на слой выше — про HikariCP, дефолтный пул соединений в Spring Boot. Тот самый, который «просто работает», пока не перестаёт. Проекты те же, что и в статье про миграцию и в статье про PostgreSQL: банковская система после переезда с Oracle (терабайт, 70+ таблиц, 500–3000 RPS на чтение и 50–300 на запись в пике) и enterprise-платформа на Java/Spring, где PostgreSQL жил под Hibernate. Разные команды, разные нагрузки, но сюжет один: сервис встаёт, в логах Connection is not available, и первое, что делает любой человек, — лезет крутить maximumPoolSize. И почти всегда делает хуже.

Это не туториал «как настроить HikariCP за 10 строк». Таких на Хабре хватает, и половина из них сводится к «поставьте пул побольше». Здесь — список мест, где у нас всё ломалось, в порядке от «это все знают, но всё равно наступают» до «поняли только в проде под нагрузкой».

Если вы сейчас живёте на HikariCP — читайте как чеклист. Если уже прошли через это — сверьте, сколько совпало.

Дисклеймер: проекты под NDA, названия, точные объёмы и часть деталей изменены. Порядок величин, конфиги и сами инциденты — настоящие.

Читать далее

Новости

Бэкап, из которого ни разу не восстанавливались — это не бэкап

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели6.9K

Бэкап, который ни разу не проверяли восстановлением, может не помочь в момент аварии. В статье разберём, где чаще всего ломаются схемы резервного копирования: от пустых копий и неверного RTO до отсутствующих ролей, секретов и инфраструктурных зависимостей.

Узнать больше

Миллионы товаров и миллисекунды: как устроен специализированный движок каталога

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели6.7K

Что происходит, если строить каталог на миллионах товаров не вокруг PostgreSQL и Elasticsearch, а вокруг mmap, собственных индексов и zero-allocation JSON? Разбираю архитектуру, компромиссы и реальные результаты на работающем агрегаторе: около 50 000 RPS и миллисекундные ответы.

Читать далее

Сайзинг RAM и vCPU для локальной языковой модели: считаем стартовый размер VM

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели7.1K

Сайзинг RAM и vCPU для локальной языковой модели начинается с конкретных весов и профиля запросов. Исходные требования self-hosted LLM включают длину входа и ответа, конкурентность, рантайм и схему offload. Расчёт по размеру весов и формуле KV-кэша даёт стартовую конфигурацию, а прогретый тест показывает реальное потребление памяти и точку, где CPU перестаёт помогать.

Читать далее

Укрощение зоопарка сервисов: как системный подход одной команды повышает надёжность и скорость разработки

Уровень сложностиПростой
Время на прочтение16 мин
Охват и читатели10K

Как определить, на чём сфокусироваться, если в компании множество вызовов: техдолг, неоптимальная архитектура и проблемы надёжности?

Привет, Хабр! Я — Иван Нещадин, работаю тимлидом в компании Авито. Сейчас я руковожу двумя командами Arch и Bridge. В этой статье по мотивам доклада для TeamLeadConf я расскажу, как в Авито мы создали SWAT-команду, которая быстро решает самые проблемные задачи и живёт между миров платформы и продукта. Также подробно опишу, как снижаем хаос в архитектуре и улучшаем надёжность.

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

Читать далее

Сервера: распределяем нагрузку

Уровень сложностиСредний
Время на прочтение15 мин
Охват и читатели7K

«Просто арендую сервер помощнее». Так я думал, когда пет-проект внезапно оброс людьми.

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

Я изучил, как похожие проблемы решают крупные компании, и применил эти принципы на практике.

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

Читать далее

Short Polling vs Long Polling vs WebSocket: сравнение в SCADA-системах

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели6K

WebSocket принято считать очевидным выбором, когда сервер должен постоянно отправлять клиенту свежие данные. Но что произойдёт, если вместо обычного веб-приложения у нас SCADA, а клиентов становится 1000?

Был собран тестовый стенд с OpenPLC, Modbus TCP и ASP.NET Core. Сравнивались Short Polling, Long Polling и WebSocket при 1, 10, 30, 50, 100, 500 и 1000 одновременных клиентах.

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

Читать далее

Экспериментальный антивирусный сканер на основе эвристики: опыт разработки

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели5.6K

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

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

Мне давно было интересно другое: что, если строить детект не вокруг вопроса «знаем ли мы этот файл?», а вокруг вопроса «насколько поведение и структура этого файла характерны для вредоносной программы?»

Так появился экспериментальный проект HAV — Heuristic AntiVirus. Это не коммерческий продукт и не попытка заменить существующие решения. Это исследовательский эксперимент, цель которого — проверить, насколько далеко можно продвинуться в обнаружении вредоносного ПО с помощью статического и динамического анализа, статистики и эвристических моделей. Репозиторий проекта опубликован в открытом доступе.

Читать далее

PostgreSQL и временные таблицы. Часть 2: почему 1024 счётчиков бывает мало

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели8.1K

В 2023 году мы писали о временных таблицах в PostgreSQL и о том, как перенести их на RAM-диск. Это помогло: в наших измерениях доля ext4 в профиле процессора упала с 13,5% до 1,6%, и про диск мы с тех пор не вспоминали. Однако создание, очистка и удаление временных таблиц остались обычным DDL — с изменениями системного каталога и сильными блокировками, которые держатся до конца транзакции. Оказалось, что это отдельная цена, и платить её приходится в самых неожиданных местах.

На одном сервере активные бэкенды периодически застревали в ожиданиях LWLock:LockManager. На другом отставала логическая репликация и накапливался WAL. Выглядело это совершенно по-разному, а разбираться в обоих случаях пришлось в одном и том же: в том, что происходит в PostgreSQL, когда временные таблицы создаются и очищаются тысячами. Начнём с блокировок — там обнаружился массив из 1024 счётчиков, который занимает четыре килобайта, не настраивается и не менялся с 2011 года, и выяснилось, что временные таблицы одной сессии могут лишать обычные запросы всех остальных сессий быстрого пути получения блокировок.

Читать далее

Prometheus и VictoriaMetrics: почему одни и те же метрики могут занимать в 139 раз больше места

Уровень сложностиПростой
Время на прочтение23 мин
Охват и читатели5.9K

Меня зовут Стас Погоржельский, я технологический евангелист VK Cloud и последние месяцы гоняю Prometheus и VictoriaMetrics на одном стенде, чтобы понять, сколько на самом деле стоит одна точка метрики на диске.

Обе системы делают одно и то же: принимают миллионы точек в минуту, хранят их месяцами и быстро отдают в алерты и дашборды. Обе сжимают точку до байтов и долей байта. Именно эти байты, умноженные на миллиарды точек в сутки, превращаются в счёт за диск. Ошибка в расчёте цены сэмпла заканчивается переполненным диском под мониторингом, урезанным retention или незапланированным расходом.

Когда место под метрики кончается, первым на планёрке звучит «сменим движок». Публичные бенчмарки подталкивают к тому же: Флант показывает, что Prom++, форк Prometheus, тратит памяти в 7,8 раза меньше Prometheus v2 (разбор на Habr), VictoriaMetrics показывает трёхкратную экономию диска против Grafana Mimir (бенчмарк VictoriaMetrics, замер вендора, 2022 год).

На моём стенде картина оказалась сложнее. В Prometheus 3.13 и VictoriaMetrics 1.149 ушёл один и тот же набор: 2,88 млн сэмплов, шесть профилей данных, один генератор с фиксированным seed. Внутри одного движка цена сэмпла различалась в 139 раз у VictoriaMetrics и в 12,8 раза у Prometheus. Между движками на одних данных разрыв доходил до 30,7 раза на шести профилях и до 34,3 раза в опыте с точностью. На равномерно случайных float64 движки менялись местами. Один лишний знак после запятой поднимал цену сэмпла у Prometheus в восемь раз, у VictoriaMetrics на 12%.

Читать далее

Как защитить платежный API от двойных списаний с помощью идемпотентности

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели9.7K

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

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

Читать гайд

Шаблоны против статической рефлексии в C++: пять операций, две реализации и дедупликация, которая не стоит памяти

Уровень сложностиСложный
Время на прочтение26 мин
Охват и читатели8.6K

Одна и та же операция — дедупликация списка типов — написана двумя способами: на шаблонах и на статической рефлексии из C++26. Обе реализации живут в одном дереве и проверены на идентичность результата, поэтому их можно честно вычесть друг из друга. Получилось так: шаблонная версия съедает 7,9 ГиБ памяти компилятора там, где рефлексивная не съедает ничего измеримого — ±21 МиБ на 32-кратном диапазоне размеров. А по времени обе квадратичны, и рефлексия выигрывает всего пятую часть. Разбираю, откуда берётся такая асимметрия, и заодно пять компиляторных стен, в которые упираешься по дороге, — включая sizeof…, который молча возвращает неверное число.

Читать далее

Я прогнал топ VRAM-калькуляторов для LLM — все ошибаются в одном и том же

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели8.1K

Наивная формула «веса + KV < VRAM» промахивается по двум причинам, и обе стоят денег. Первая: движок (vLLM, SGLang, TensorRT-LLM) резервирует почти всю память под свой пул ещё до того, как вы посчитали KV — поэтому ответ «сколько запросов влезет» всегда мимо, в сторону «влезет», а потом OOM под нагрузкой. Вторая, которую в уме не посчитать: на DeepSeek-V2-Lite обычная формула завышает KV в 7–11 раз, и промах уже в обратную сторону — зря откажетесь ставить модель.

Я прогнал топ VRAM-калькуляторов из выдачи Google, показал на скриншотах, где ломается каждый (даже лучший), сверил числа с живым vLLM на A100/H100 — расхождение ~1% — и собрал ridgepoint: калькулятор, который считает как движок, а не как учебник. Ставится локально (pip install ridgepoint), GPU не нужен.

Сколько реально влезет

Ближайшие события

PostgreSQL против Exadata: 250 тыс. TPS и 2,6 млн NOPM

Время на прочтение22 мин
Охват и читатели7.8K

Сколько ни улучшай PostgreSQL, сколько ни отчитывайся о реальных историях внедрения, архитектурный потолок от этого никуда не исчезает: есть класс задач, где дальнейшее развитие в рамках традиционной архектуры объективно затрудняется. 

Именно здесь появляется Tantor Polar — распределенная СУБД с разделением вычислений и хранения и 100% совместимостью с PostgreSQL. На ее основе построена машина баз данных Tantor XData Gen3, объединяющая мощные вычислительные узлы, высокопроизводительное общее хранилище и высокоскоростную сеть c RDMA в единую систему. В этой статье мы покажем, что эта архитектура дает на практике — рассмотрим устройство синергично работающих программных и аппаратных модулей позволяющих достичь высоких показателей в популярных нагрузочных фреймворках, таких как TPC‑B (250 тыс. TPS) и TPC‑C (2,6 млн NOPM). 

Читать далее

Как на ровном месте сэкономить 1000+ ядер, или Куда на самом деле уходили 80% CPU

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели14K

Всем привет, меня зовут Миша, и я бэкенд‑разработчик в платформе Яндекс Еды. Я уже рассказывал, как мы анализировали наш PHP‑монолит и вынесли из него процессинг заказов, и с тех пор роль этого легаси заметно уменьшилась. Заодно туда стали писать гораздо меньше нового кода, релизы стали реже, и он спокойненько себе работал, не привлекая лишнего внимания. 

Так оно бы и продолжалось, но тут случилась повышенная нагрузка и необходимость зарезервировать побольше мощностей для беспроблемной обработки повышенного спроса. Монолит справился на отлично, но самое интересное случилось потом: возвращая выделение ресурсов к прежним значениям, я случайно обратил внимание, что RPS в пиковые вечерние часы как‑то подозрительно совпадает с количеством ядер CPU, выделенных на весь монолит.

Количество выделенных ядер, конечно, ещё ничего не означает, поэтому я полез смотреть реальное потребление процессорного времени, сложив CPU usage по всем подам. С помощью нехитрой арифметики я обнаружил, что 100% загрузки одного ядра приходятся на 2,5 RPS. Какое‑то время я находился в состоянии глубокого изумления, после чего решил, что это никуда не годится, и отправился в увлекательное приключение на 20 минут. 

Немного спойлеров: дело оказалось далеко не только в PHP. 

Читать далее

PostgreSQL в проде: блокировки, bloat и ночные пересчёты. Три инцидента и как их чинили

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели6K

В прошлой статье я рассказывал, как мы перевозили терабайт банковской базы с Oracle на PostgreSQL без даунтайма. Там был раздел про производительность, и в комментариях несколько человек спросили примерно одно и то же: «а что конкретно вы дебажили и как?».

Это продолжение. Три инцидента из двух разных проектов — банковской системы после миграции и enterprise-платформы на Java/Spring, где PostgreSQL жил под Hibernate. Разные домены, разные команды, но сюжет один: запрос, который вчера работал, сегодня не работает, а EXPLAIN показывает, что всё хорошо.

Если вы пришли в PostgreSQL из Oracle или из мира, где база — это «то, куда ORM пишет», три четверти статьи будут про вещи, о существовании которых вы не подозревали. Я тоже не подозревал.

Дисклеймер: проекты под NDA, названия, объёмы и часть деталей изменены. Порядок величин и сами инциденты — настоящие.

Читать далее

Кэши, режимы нагрузки и ловушка среднего, или Почему storage-бенчмарки врут

Время на прочтение10 мин
Охват и читатели8.2K

Представьте, разработчики добавили прозрачное шифрование в файловую систему, собрали ядро и прогнали Fio — пропускная способность не изменилась. Однако после раскатки на продакшен производительность резко упала. Дело не в том, что бенчмарк ошибся: он честно измерил предел быстродействия жесткого диска, а накладные расходы на шифрование остались скрыты за дисковыми задержками. Так и возникает одна из самых типичных ошибок storage-бенчмаркинга.

Хранение до сих пор кажется многим инженерам простой подсистемой: файловая система, блочное устройство, метрика throughput. На практике это одна из самых коварных частей стека — с иерархией памяти в 4–8 порядков разницы между самой быстрой и самой медленной операцией, слоями виртуализации (LVM, программные RAID, NFS) и переключениями контекста между ядром и user-space.

Чтобы разобраться, как корректно измерять производительность систем хранения, обратимся к докладу Эреза Цадока, профессора Университета Стони-Брук, возглавляющего Лабораторию файловых систем и хранения данных.

Все подробности — под катом.

Читать далее

Записки оптимизатора 1С (ч.19). Как настройка Huge Pages в Linux влияет на устойчивость работы Postgres

Время на прочтение9 мин
Охват и читатели64K

Продолжаем исследовать настройки памяти в Postgres и сегодня поговорим о связке настроек в ОС и СУБД. Речь пойдет о связке hugepages (Linux) и shared_buffers (Postgres).

Триггером для исследования послужила реальная жизненная ситуация у нашего клиента на поддержке производительности его ИТ-системы. Однажды утром…поступило обращение, что Postgres перестал запускаться вроде бы без видимых на то предпосылок: «мамой клянусь, ничего не делали с базой».

Читать далее

Kafka Connect без магии: как переносить данные и не писать еще один сервис

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели9.9K

Привет, бойцы, вы готовы победить перенос данных?

Есть задача: перенести данные из PostgreSQL в Kafka. Первая мысль: написать небольшой сервис.

Он будет выполнять SELECT, превращать строки в сообщения и отправлять их через Kafka Producer. На схеме все выглядит почти безобидно:

Читать далее

Как пережить резкий рост нагрузки в Kubernetes без надежды только на автоскейлинг

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели7.2K

Автоскейлинг часто воспринимают как страховку от любых всплесков нагрузки: вырос CPU — появились новые поды. Но в реальных системах между перегрузкой и запуском дополнительных ресурсов есть критический промежуток, когда база уже может исчерпать соединения, а пользователи начнут получать ошибки.

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

Разобрать подход
1
23 ...