Обновить
128K+

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

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

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

Устанавливаем Digital Q.DataBase 18.2 на РЕД ОС 8: PostgreSQL, MS SQL и Oracle в одной СУБД

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

Привет, Хабр!

Меня зовут Жуйков Андрей, занимаюсь развитием и продвижением СУБД Digital Q.DataBase.

Сегодня для многих организаций импортозамещения СУБД - уже практическая задача, которую необходимо решать без остановки бизнес-процессов и без многомесячной переработки прикладных систем. Одним из ключевых требований при выборе новой платформы становится возможность сохранить существующую прикладную логику и минимизировать объем изменений в коде приложений.

В этой статье я покажу, как установить Digital Q.DataBase 18.2 на РЕД ОС 8.0.3, познакомлю с новой архитектурой СУБД и продемонстрирую подключение к каждому из поддерживаемых диалектов.

Читать далее

Новости

Не подавать холодным! Прогрев JVM перед запуском трафика

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

Всем привет! Меня зовут Александр, я бэкенд-инженер в Банки.ру.

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

Дальше расскажу, что мы видели на графиках, какие версии проверили и отбросили, что происходит внутри JVM в первые минуты жизни процесса и что мы сделали.

Читать далее

Что там с trait upcasting: год спустя

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

Приветствую. В Rust есть целый класс костылей, который лежит буквально в каждом крейте с API на dyn старше пары лет. Методы вида as_super, as_debug, into_dyn_display.

Крутанёшь поиск по большим репозиториям на GitHub, найдёшь такое тысячами. Каждый делает одну и ту же тупую вещь: возвращает тот же самый &self, только под нужным трейт-объектом. Встроенно очевидная операция, которую больше десяти лет не могли завезти в язык.

С Rust 1.86 (3 апреля 2025) все эти костыли стали не нужны. Trait upcasting наконец стабилизирован: &dyn Sub спокойно кастится в &dyn Super, если trait Sub: Super. Причём стабилизировали не с первого раза. В конце 2023-го фичу мерджили, потом откатывали из-за двух багов в соундности, потом чинили, потом снова находили баги. Только к весне 2025 получилось выкатить окончательно.

Прошёл год стабильной жизни с фичей, экосистема переварила, паттерны поменялись. Разберём: как расширили vtable под эту штуку (спойлер: ещё в 2021-м, за четыре года до самой стабилизации), сколько багов в соундности нашли на nightly и в чём была суть, почему dyn MyAny: Any теперь одна из самых частых идиом, и почему Vec<Box<dyn Sub>> в Vec<Box<dyn Super>> всё равно не летит.

Читать далее

Приложение простояло 918 мс, а сборщик мусора отработал за одну: разбираемся, куда ушло остальное

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

Секундная пауза в Java‑приложении легко выглядит как проблема сборщика мусора, хотя сам GC может отработать за миллисекунду.

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

Читать далее

Как за 5 недель построить рекомендательную систему в TravelTech: Kafka и MongoDB вместо Feature Store

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

Привет! Меня зовут Кристина, я MLOps-инженер в Туту. Занимаюсь тем, что помогаю рекомендательным системам добраться до прода со всеми компромиссами, горящими дедлайнами и новыми идеями. 

Эта статья — про один из таких запусков.

В идеальном ML-мире запуск рекомендаций выглядит примерно так: полгода проектируют хранилище признаков (Feature Store), настраивают, откуда и как берутся данные, гоняют тяжёлые расчёты фичей и моделей, а отдельная команда следит, не деградирует ли модель из‑за изменений в данных. 

В реальном бизнесе у тебя есть 5 недель до старта высокого сезона, два инженера, DS и задача: сделать так, чтобы пользователь, который купил билет, сразу увидел релевантный отель. Рассказываем, как мы собрали работающую RecSys v1 на привычном стеке: Kafka, MongoDB, ClickHouse. При этом мы сознательно отказались от перфекционизма ради скорости.

Инженерный вызов здесь не в масштабе и не в алгоритмах, а в контексте. Cross-sell в travel — это не «похожие товары». 

Пример

Пользователь купил билет Москва → Сочи на 10–17 июля: значит, нужно показать отели именно в Сочи, именно на эти даты. 

Коллаборативная фильтрация без контекста поездки — «похожие пользователи → похожие отели» — не знает ни город, ни даты, ни то, что заказ только что оплачен и его ещё нет в DWH. 

Нужен подход, где контекст конкретной поездки — куда, когда, с кем — задаётся явно до ранжирования.

«Правильный» путь —  Feature Store и полноценная ML-платформа, занял бы 4–6 месяцев. Бизнесу нужно было проверить гипотезу на живом трафике. Мы собрали v1 на том, что уже работало в проде, с некоторыми компромиссами и без иллюзий насчёт идеальной архитектуры. 

Читать далее

HLS Lazy Muxing 2.0 Как срезать 80% CPU и не остановить запись архива

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

Если кто то, когда-либо занимался видеопотоками поверх интернета, т.е использовал классический медиасервер работающий по принципу RTSP to HLS (или ему подобные протоколы) тогда он знает какие проблемы возникают. Для примера возьмем двух гигантов, Flussonic и Wowza. В документации Flussonic`a есть четкие аппаратные характеристики при которых ЦП начнет долбиться в сотку: 250 камер с битрейтом 2 Мбит/c, на Xeon E3-1230v5 3.4 GHz + 32 GB RAM. У Wowza же четких примеров нет, но если немного «экстраполировать», то у нее на том же железе около 350-400 камер с битрейтом 2 Мбит/c, загружают процессор на сотку. Давайте внесу оговорку: я понимаю, что указанное железо довольно старое. Но 80% малого и среднего бизнеса на +/- таком работают, я имею ввиду тех, кто не пользуется облачной инфраструктурой или не арендует железо в ДЦ. Так вот, казалось бы, ну такая вот нагрузка, что с ней поделать? Проблема в том, что в моменте эти потоки никто не смотрит. Условный «охранник» залипает в телефоне, пьет кофе – а сервак 24/7 продолжает нарезать сырые кадры в HLS-сегменты и писать архив, грея серверную. Банальное расходование ресурсов в пустую, когда они не нужны. А в наш век стоимости на железо – стоит беспокоиться о таких вещах.

Решение на поверхности, и многие о нем знают – режим On Demand (по запросам). Нет зрителей – тушим камеру.  Есть зритель – отдаем HLS-поток. Казалось бы, все идеально, вопрос решен, расходимся. Но тут вылезает главная проблема классического On Demand - как только зрителей нет, соответственно камера потушена, запись архива не ведется. Для любой системы безопасности – это новомодный «ред флаг».

Читать далее

5 ошибок в NetworkPolicy, из‑за которых ваши политики ничего не блокируют

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

NetworkPolicy могут выглядеть корректно, применяться без ошибок и при этом оставлять кластер открытым там, где вы уверены в изоляции.

Разберём пять типичных ошибок — от CNI без поддержки политик до неверных селекторов — и покажем, как проверять правила реальным трафиком, а не по наличию объектов в API.

Читать далее

Как восстановить KRaft-кворум после потери большинства контроллеров

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

Представьте себе баг-репорт: все шесть подов в статусе 1/1 Running, Readiness зелёный, kafka-agent на брокерах отдаёт 204. А кластер мёртв: оператор бесконечно крутит реконсайл и валится в TimeoutException: Timed out waiting for a node assignment. Call: describeMetadataQuorum. Если зайти на том контроллера, можно увидеть, что __cluster_metadata-0/quorum-state: leaderId выставлен, а appliedOffset в 0. Ни одна запись метаданных не применена. JVM живые, raft-лог на диске растёт, и при этом ни один под не написал в stdout ни строки следующие восемь часов. Это не выдумка, а реальный баг-репорт Strimzi от 25 мая 2026, и к нему мы ещё вернёмся.

В Kafka 4.x больше нет привычного «запасного выходa» в виде ZooKeeper: метаданные переехали внутрь самой Kafka (KRaft), и если кворум контроллеров теряет большинство, чинить уже приходится сам кластер Kafka, а не внешний сервис. 

Раньше чтобы с этим справиться в Kafka существовал ZooKeeper, отдельная система со своими инструментами, ансамблем и культурой восстановления. В версии  4.x его нет, и в документации от процедуры остался только линк на 3.9. Метаданные переехали внутрь самой Kafka (KRaft), и если кворум контроллеров теряет большинство, чинить уже приходится сам кластер Kafka, а не внешний сервис.

В этой статье расскажем, что делать в такой ситуации и как восстанавливать этот кворум, чтобы не случилось ситуации, описанной выше.

Читать далее

Добавили потоков, стало медленнее: разбираемся с ложным разделением кеш‑линии

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

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

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

Читать далее

Запросы с ANY: когда PostgreSQL дольше планирует, чем выполняет

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

Когда речь заходит об оптимизации запросов в PostgreSQL, разработчики, как правило, сосредотачиваются на времени выполнения: индексы, планы запросов, настройки памяти и так далее. Время планирования остаётся в тени. А зря! Планировщик работает перед каждым выполнением запроса. Для OLTP-нагрузки с короткими транзакциями накладные расходы на планирование могут составлять значительную долю от общего времени ответа. Для запросов с большими IN-списками и высоким statistics_target планирование может занимать сотни миллисекунд, тогда как само выполнение укладывается в миллисекунды. Поэтому ускорение планировщика не менее важно, чем ускорение выполнения.

Читать далее

Будет ли self-hosted LLM производительнее, чем модель во внешнем контуре: сравниваем GLM, Claude и GPT

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

Меня зовут Влад, я фуллстек-разработчик в Selectel. Есть распространенное мнение, что для серьезной агентской разработки хорошо подходят только коммерческие модели вроде Claude и ChatGPT, а open-source модели всегда остаются на вторых ролях. В реальном корпоративном проекте выбор устроен сложнее: в первую очередь думаешь, что можно модели передать, а уже потом — какую модель использовать.

В моих сценариях внешние модели я использую для ресерча и AI-ассиста на данных, за которые можно не переживать, а задачи с закрытым кодом или внутренней документацией выполняются с self-hosted GLM внутри управляемого контура. В статье расскажу, как harness делает такой внутренний контур практически применимым и как оптимизировать итоговый процесс в гибридном режиме.

Читать далее

Ошибка в расчёте скидки, которую не видно глазами: проверяем ответ API по документации, когда автотестов нет

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

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

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

Читать далее

nginx -s reload может не применить конфиг

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

Пока идёт бинарный апгрейд nginx, systemctl reload nginx не применяет конфиг так, как вы думаете: в лучшем случае к половине процессов сервера, в худшем — вообще никуда. Код возврата ноль в обоих случаях, в error.log пусто. Что именно у вас — решает одна строчка в юните: -s reload бьёт по pid-файлу, а он после USR2 принадлежит новому мастеру; kill -s HUP $MAINPID бьёт по старому, а тот конфиг вообще не перечитывает, и это описано в документации nginx — в разделе про обновление исполняемого файла, куда по другому поводу не заходят.

Это первая из пяти проверок. Я взял пять ходовых утверждений про reload в nginx, померил каждое на стенде — и получил результаты по обе стороны: три подтвердились, два развалились. Развалившиеся оказались интереснее.

Не работают ровно те страшилки, что про слушающий сокет: listen ... reuseport бесшовность не ломает (inode’ы сокетов до и после reload одни и те же — их держит мастер, а не воркер), паузы в accept при reload не существует вовсе (msleep(100) стоит ПЕРЕД QUIT), а значит и арифметика про переполнение backlog на reload — про нагрузку, а не про reload.

Зато подтвердилось то, о чём почти не пишут. keepalive_min_timeout оставляет уходящего воркера в живых, и тот обслуживает запросы, которых в момент reload ещё не существовало — по старому конфигу. А ngx_close_idle_connections не различает направление соединения, поэтому каждый reload сбрасывает пул keepalive к бэкендам — и с 1.29.7 это касается всех, у кого есть блок upstream: пул там включён по умолчанию, 32 соединения на воркер.

Правило из первой части — «соединение, открытое до reload, нового конфига не увидит» — приходится переформулировать: держится старого конфига не соединение, а процесс.

В конце — Traefik, у которого reload’а нет вовсе, и который умеет не применить конфиг своим способом: кольцевой буфер на одно сообщение и двухсекундный дроссель.

nginx release-1.31.3, traefik v3.7.10, все опыты в репозитории, запуск одной командой.

Читать далее

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

Пишем терабайты видео на диск в Go и не даем ОС сожрать всю память

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

Выкатили мы первый релиз в прод (100 камер), обрадовали клиентов, начали работать. Прошел где-то час, полетели алерты. Залезаю на сервак, смотрю htop – а там свободно 100 метров ОЗУ. Пу-пу-пу-пу. Нужно внести уточнение что боевой сервер имел 32 гига озу. Ожидаемое поведение было то что процессор отдыхает, сетевуха переваривает трафик, озу 250-300 МБ, диски нагружены не сильно. Так что, когда видишь такие цифры в htop, начинаешь винить себя и свои кривые руки, написавшие это "Г". Но все же решили пойти в Гугл, чатгпт и тому подобное. Благо, ответ нашелся быстро, и посыпать голову пеплом перестали.

Код оказался не вообще не причем, память сожрал сам Линукс. Если когда-нибудь вы писали тонны данных на диск, я думаю вы уже поняли в чем дело. Есть такой «невидимый враг» как страничный кэш (Page Cache). Вот именно он и был корнем этой проблемы.

Как работает страничный кеш и что с ним делать?

Когда ваша функция, которая должна писать данные на диск пишет данные, на самом деле она не пишет их на диск. Она пишет их в ОЗУ. Логика ядра Линукса проста и банальна, и она направленна на ускорение «отзывчивости» системы, всю суть можно объяснить так: «О, только что записали сотню гигабайт данных, наверное, скоро понадобится эти данные прочитать. Оставлю-ка я их в кеше, пользователь будет рад что так быстро смог их прочитать.» И так гигабайт за гигабайтом, пока в сервере не кончится физическая память.

Типичное решение проблемы – пишем скрипт, который раз в час делает echo 3 > /proc/sys/vm/drop_caches. Ну а кто-то просто забивает и позволяет системе убивать случайные процессы через OOM Killer. Но мы же пишем отказоустойчивую штуку. Нам такое не подходит. Задача объяснить ядру ОС, что наши fMP4 сегменты видеоархива — это write-only мусор на небольшое количество времени (т.к если клиент не хочет долго хранить записи, то архив чистится, а если хочет – мы отправляем архив после N времени хранения в S3, а локальную копию тоже чистим). Так что все должно работать по принципу – записал и забыл.

Читать далее

ИИ-агенты заговорили на языке OpenTelemetry: два сигнала от MCP и Otel

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

Вызов инструмента ИИ-агентом легко теряется между моделью, MCP-клиентом, сервером и внешним API. В конце июля сразу два события показали, каким способом индустрия собирается решать эту проблему. Новая спецификация MCP закрепила передачу W3C Trace Context и начала выводить собственный механизм логирования из протокола в пользу OpenTelemetry. Одновременно сообщество OpenTelemetry назвало наблюдаемость ИИ-агентов одним из следующих направлений развития проекта. Разбираемся, что уже стало частью стандартов, что пока остаётся дорожной картой и почему эти события стоит рассматривать вместе.

Читать далее

Как потеря 17% сессий запустила цепную реакцию в инфраструктуре Discord

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

25 марта 2026 года голосовая и видеосвязь Discord перестала нормально работать для большинства пользователей. Причиной стал не один большой сбой, а цепочка событий: изменение конфигурации Kubernetes привело к потере части пользовательских сессий, затем система столкнулась с лавиной переподключений и новыми узкими местами в инфраструктуре.

В статье команда Discord разбирает этот инцидент изнутри: как 17% остановленных сессий запустили каскадный отказ, почему механизмы восстановления сами стали источником нагрузки и какие архитектурные изменения помогли сделать систему устойчивее.

Читать разбор

Снапшоты дедуплицирующей файловой системы на LSM-дереве: опыт TATLIN.BACKUP

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

Привет, Хабр! Меня зовут Александр Черепанов, я руковожу группой в команде Data Path TATLIN.BACKUP.

Мы уже писали в блоге про наше хранилище. Сначала про то, как с нуля делали дедуплицирующую файловую систему: чанки, FastCDC, протокол T-BOOST. Потом про то, что такое снапшоты, зачем они нужны и как мы их устроили на уровне архитектуры: экстенты, файл как список их идентификаторов, выбор Mark-and-Sweep вместо подсчета ссылок для сборки мусора. С тех пор снапшоты уже почти год в проде, и, судя по отзывам, работают неплохо.

Эта статья принципиально другая. Мы достанем отвертку и залезем внутрь: разберемся, на чем технически строятся снапшоты, как мы их сделали поверх RocksDB, при чем тут LSM-дерево и Bloom-фильтр размером с системный диск ноутбука.

Читать далее

Как добиться 8 Гбит/с видеотрафика на одном ядре CPU в Go

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

Предисловие

Есть небольшой побочный профиль, которым я занимаюсь – ретрансляция сырых потоков RTSP, в HLS. По сути задача простая, чтобы любой простой юзер мог увидеть картинку со своих камер, не пользуясь проприетарным облачным ПО от производителя камер. Во-первых, это много денег, т.к многие клиенты хотят хранить достаточно долго записи с камер. Во-вторых, почти у всех производителей камер разное ПО, и это тупо не удобно иметь 10 разных приложений и/или порталов, где это все можно посмотреть. Ну и в-третьих мало где есть интеграции с ИИ (что для моих клиентов, критически важно). Даже если эта интеграция есть, она либо узкоспециализирована, либо опять-таки проприетарна, либо стоит много денег, а иногда и все это вместе. Решение - использование сырых RTSP потоков, их поддерживают и отдают 90% всех камер на рынке.

Так вот, схема была достаточно проста: несколько камер, простой бэк, выдаем на едином ресурсе для клиентов картинку по HLS, используя плеер hls.js. Всех все устраивало, всем все нравилось. Быстро, просто, удобно и не дорого. Тесты работали идеально, клиенты довольны. С каждым был чат, куда выдавали ссылку на просмотр, а также был общий чат со всеми клиентами – где обсуждались вопросы подключения, финансовые ну и прочее. И вот настает момент Х, кто-то по ошибке скидывает в общий чат ссылку…и конец. По ссылке кликнул видимо весь чат, 3 минуты, полетели алерты в боте, алярм, ахтунг, тревога. Смотрим железо, сервер в ауте, ООМ, все потоки отвалились. Через 20 минут чат разрывался от гневных сообщений, о неработоспособности у всех. Занавес.

Читать далее

ggrebalance: Часть 3. Выполнение ребаланса

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

В статье рассматривается исполнительная часть утилиты ggrebalance: механизм физического перемещения primary- и mirror-сегментов между хостами кластера Greengage DB (open-source форк Greenplum), устройство конечного автомата ребаланса, отслеживание статусов операций, обработка сбоев и реентерабельность, откат перемещений, а также практические рекомендации по эксплуатации и итоговое сравнение с альтернативными инструментами.

Читать далее

nginx не умеет reload. Он умеет fork

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

Деплой делает nginx -s reload. Команда возвращает ноль, nginx -T показывает новый конфиг, в error.log ровно одна строка — reconfiguring. А keep-alive соединение, открытое секундой раньше, в этот момент закрывается.

Само по себе это не ошибка: сервер вправе закрыть простаивающий keep-alive когда угодно. Ошибку даёт гонка — FIN уходит в тот момент, когда клиент уже записал в сокет следующий запрос. Идемпотентный он повторит, POST — нет.

Разбор по исходникам на фиксированных тегах: nginx release-1.31.3, httpd 2.4.68, traefik v3.7.10, плюс замер всех четырёх (с HAProxy) на одном стенде в одном прогоне. Выясняется, что мастер nginx конфиг не перечитывает вообще: он строит новый цикл целиком и форкает новых воркеров, а старым остаётся ровно то, что у них было. Apache приходит к тому же контракту через счётчик поколений, HAProxy — через замену процесса. А у одного из четырёх второй запрос в том же самом сокете возвращает уже новый конфиг — и причина не та, о которой вы подумали.

Внутри: почему документация nginx сама создаёт половину недоразумения; почему WebSocket и SSE не попадают под ngx_close_idle_connections и держат старого воркера сколько угодно долго, а HTTP/2 попадает всегда и получает GOAWAY; как сигнал родителя у Apache доезжает до конкретного соединения через пять звеньев; и таблица из двенадцати клеток, в которой четыре реализации расходятся ровно в одной.

Со стендом (один docker build, один docker run), полными выводами ps и тремя claims-*.tsv, где каждое утверждение о коде проверяется скриптом.

Читать далее
1
23 ...