惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
Y
Y Combinator Blog
美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
S
SegmentFault 最新的问题
IT之家
IT之家
Recent Announcements
Recent Announcements
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
Martin Fowler
Martin Fowler
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
WordPress大学
WordPress大学
博客园 - Franky
L
LangChain Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
博客园 - 叶小钗
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
雷峰网
雷峰网
腾讯CDC
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Help Net Security
Help Net Security
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News and Events Feed by Topic
V2EX - 技术
V2EX - 技术
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Schneier on Security
Schneier on Security
博客园 - 聂微东
A
Arctic Wolf
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Exploit Database - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google DeepMind News
Google DeepMind News

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Автоскейлинг StarRocks в Kubernetes: как я довел его до предела
Александр Моисеев · 2026-05-29 · via Все публикации подряд на Хабре

Простой

7 мин

7.2K

Всем, привет! Это не глубокая техническая статья и не исследование. Тема просто не влезла в формат поста в моём Telegram-канале https://t.me/starrocks_selena, поэтому мы с вами тут. Это пятничный лёгкий длиннопост про автоскейлинг StarRocks. Без глубокого погружения в архитектуру, с мЭмами и несколькими наблюдениями из практики.

Проблематика

Представьте, 28 дней в месяц аналитический кластер/БД потребляет ресурсы равномерно. Регламентные отчеты, привычные дашборды, пересчеты витрин. В среднем около 60% ресурсов. И вот наступают самые тяжелые три дня месяца. Закрытие периода, массовые выгрузки, аналитики разом открывают отчеты. В этот момент кластеру нужно в разы больше мощности, чем обычно.

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

Долгое время эту задачу решали через сайзинг под пиковую нагрузку. Если расчет делал опытный архитектор, инженер или DBA, пики просто закладывались в конфигурацию. То, что большую часть времени серверы работают с низкой загрузкой, считалось платой за спокойный отчетный период. Особенно заметно это было с Exadata и похожими ПАК. Конфигурации фиксированы, шаг масштабирования крупный, поэтому нередко приходилось покупать больше ресурсов, чем требуется для повседневной нагрузки.

Режим Shared-data в StarRocks отчасти появился как раз для того чтобы эту проблему решить, полностью или частично.

StarRocks и K8s спешат на помощь

Классический режим StarRocks, shared-nothing, хранит данные на локальных дисках BE-узлов: каждый узел и хранит, и считает. Добавить узел — значит перенести на него tablets и выполнить rebalance. Это небыстрая операция.

Shared-data — это режим развертывания StarRocks, при котором у вас данные лежат на едином удаленном хранилище (S3-хранилище или HDFS), а вычислительные компоненты развернуты отдельно от хранения.

Вычислительные компоненты в Shared-data режиме называются Compute Node (CN). Сами по себе они stateless, так как предназначены только для вычислений. У CN есть локальный кэш, обычно на SSD или NVMe. В него попадают данные, прочитанные из S3-хранилища, поэтому повторные запросы выполняются быстрее, так как читать из S3-хранилища — это всегда доп. нагрузка на сеть и, соответственно, лишняя latency (больше/меньше зависит от пропускной способности сети и профиля запросов).

Работать StarRocks в K8s помогает StarRocks Operator. Это контроллер, который живет внутри Kubernetes и управляет StarRocks сам. Он вводит свой тип объекта StarRocksCluster: в нем описан весь кластер — роли (FE, BE, CN), число узлов, образы, ресурсы, хранилище, настройки. По этому описанию оператор разворачивает компоненты как StatefulSet, поднимает сервисы и конфигурации, раскатывает обновления и постоянно приводит кластер к заданному виду. Масштабировать руками не нужно, достаточно поменять описание. Для CN оператор берет на себя и автоскейл: по секции autoScalingPolicy он создает HPA, а при сокращении сначала корректно выводит ноду из кластера и только потом останавливает под. Но дальше, я подробней опишу механику.

И здесь две вещи складываются вместе. CN ничего не хранят, pod с CN поднимается и гасится за секунды, переносить на него нечего. А Kubernetes как раз умеет менять число подов под нагрузку. Stateless-вычисления над общим хранилищем плюс оркестратор, который добавляет и убирает поды. На этой связке и стоит автоскейлинг StarRocks.

StarRocks ничего не решает

Решает когда мастштабироваться, а когда нет не сам StarRocks. Решает Kubernetes, а точнее его встроенный автоскейлер, HPA (Horizontal Pod Autoscaler). Разворачивает и настраивает кластер оператор: служебная программа, которая ставит StarRocks и держит его в заданном виде. В настройках оператора мы один раз задаем параметры и границы: нод CN от 1 до 12, ориентир по загрузке 60%. Дальше оператор сам поднимает автоскейлер и привязывает его к группе CN, руками ничего трогать не нужно.

Работает все на простом цикле. Рядом крутится metrics-server (в k3s он есть сразу) и каждые 15 секунд снимает загрузку CPU с каждой ноды. Автоскейлер берет эти цифры, усредняет по всем CN и сравнивает с ориентиром 60%.

Если среднее ушло выше 60%, то нод не хватает, и он добавляет новые, по паре за раз, чтобы быстро снять пик. Сколько добавить, считается так: текущее число нод умножается на то, во сколько раз загрузка выше верхней планки. Загрузка под 200% при цели 60% — значит, нужно примерно втрое больше нод, чтобы та же работа размазалась до спокойных 60% на каждую.

Если упало среднее надолго ниже 60%, то лишние ноды убираются по одной. Тут автоскейлер действует осмотрительней: сначала ждет около минуты и только потом начинает сворачивать. Без этой паузы кластер скакал бы числом нод на каждом коротком затишье.

Включается это в одном блоке описания кластера, секция CN (добавил описание каждого параметра):

starRocksCnSpec:                  # секция compute-нод (CN) в описании кластера
  # replicas здесь НЕ указываем: фиксированное число спорит с автоскейлом — количеством нод рулит HPA
  requests:                       
    cpu: 1                        #   1 ядро в брони; именно от requests считается % загрузки
    memory: 3Gi                   #   3 GiB памяти в брони
  limits:                         
    cpu: 2                        #   максимум 2 ядра на под
    memory: 6Gi                   #   максимум 6 GiB памяти
  autoScalingPolicy:             
    minReplicas: 1                # ниже одной ноды не опускаемся
    maxReplicas: 5                # выше пяти не поднимаемся — верх коридора
    hpaPolicy:                    
      metrics:                    # показатель, по которому скейлим
        - type: Resource          #   ресурсная метрика самого пода (CPU/память)
          resource:
            name: cpu             #   смотрим на CPU
            target:
              type: Utilization         #   считаем в процентах от requests
              averageUtilization: 60    #   цель: средний CPU по всем CN держать около 60%
      behavior:                   # скорость и осторожность реакции
        scaleUp:                  # как растем под нагрузкой
          policies:
            - type: Pods          #   шаг считаем в подах
              value: 2            #   добавляем по 2 пода
              periodSeconds: 15   #   каждые 15с, пока CPU выше цели — быстро снять пик
        scaleDown:                # как сворачиваемся на спаде
          stabilizationWindowSeconds: 60   # ждем минуту низкой нагрузки, чтобы не мигать числом нод
          policies:
            - type: Pods          #   шаг в подах
              value: 1            #   убираем по 1 поду
              periodSeconds: 30   #   не чаще раза в 30с

А в чем тогда экономия?

Вопрос всплывает почти сразу: какая экономия, если под расширение все равно надо держать ресурсы зарезервированными? Идея пришла из облаков, и там все сходится: оплата по факту, pay-as-you-go. Если поды растут, то облако поднимает виртуалки, нагрузка ушла виртуалки гасятся, в счете остаются только часы, что машины реально работали.

На локальной инфраструктуре у заказчика все зависит от того, что еще живет в кластере. Если на k8s крутится один только StarRocks, экономия действительно сомнительная: машины под пик из пяти CN все равно должны стоять, иначе новым подам некуда разворачиваться, и как говорится в простое они просто простаивают.

Другое дело, если общий кластер компании, где рядом живут десятки систем, разнесенных по namespace со своими квотами. Железо там берут под совокупный пик, и он меньше суммы отдельных пиков: разные нагрузки взлетают в разное время. StarRocks занял пять CN на свои три дня в месяц, а в остальные дни эти ресурсы забирают соседи: ночные батчи, отчетность другого отдела, dev-стенды. Автоскейл экономит здесь заметнее: одно и то же железо успевает поработать на разных проектах.

А работает ли автоскейлинг у StarRocks?

Да, работает. Быстро покажу, что видно при настроенном автоскейлинге:

Шаг 1. До запуска запросов:

Шаг 2. Нормальная работа, работает один CN:

Шаг 3. Автоскейлинг, до 5 CN:

Шаг 4: Остановка и полный цикл:

Мне показалось, что будет круто исследовать пограничный случай и посмотреть, что будет с запросами в БД, когда автоскейлинг съест все доступные ресурсы.

Стенд и данные

k3s, 3 ноды, суммарно ~24 vCPU и ~93 GB.

Selena 2.0.7 (это наш дистрибутив, взял его, потому что он под k8s-инфраструктуру уже готов). Данные — coffee.sales: 2 097 152 строки продаж кофе по шести городам. Это мой старый датасет, я его часто показываю в разных демосценариях.

Перед прогоном я командой cordon запретил Kubernetes ставить новые поды на control-plane-ноду, поэтому новые CN поднимаются только на двух рабочих нодах. Так я, во-первых, не нагружаю управляющий слой кластера (apiserver и etcd), во-вторых, заранее знаю предел: два воркера — это примерно 16 ядер, и автоскейл упрется именно в них.

Автоскейл CN включается прямо в описании кластера: requests 2 ядра / 4 GiB, limits 3 ядра / 6 GiB, коридор 1–12 нод, цель по CPU — 60%. Оператор по этому описанию сам создал HPA и подключил его к группе CN.

Покой: один CN, CPU у нуля, потолок коридора 12 нод. Мониторинг Prometheus и Grafana

Покой: один CN, CPU у нуля, потолок коридора 12 нод. Мониторинг Prometheus и Grafana

Сам тест

Генерация нагрузки состояло из двух частей.

  1. 64 параллельных дашборд-запроса по coffee.sales (выручка по городам, топ позиций, средний чек) без пауз.

  2. 80 CPU-тяжелых запросов с математикой (pow/sin/cos/sqrt/ln) по всем двум миллионам строк.

Пока есть запас, скейлинг работает

Под первой нагрузкой CN рос ступенями: 1 → 3 → 6. И латентность при этом падала — примерно с 1000 до 350 мс. Больше нод, та же работа размазывается по ним, каждый запрос отвечает быстрее. Ровно то, ради чего автоскейл и нужен.

Потолок

Дальше пошла тяжелая нагрузка. CPU уперся в ~117% при цели 60%, и HPA поднял число нод до 12 (максимума). Но на два воркера поместилось только шесть CN, по ~2.5 ядра каждый. Остальные шесть повисли в Pending с понятной причиной:

FailedScheduling: 0/3 nodes are available: 1 node(s) were unschedulable, 2 Insufficient cpu.

Автоскейлер хочет двенадцать нод, а получает шесть. Расширяться некуда: свободные ядра кончились, новые поды не на что поставить. На графике это видно одним кадром — current упирается в 6, desired уходит к 12, а разрыв между ними и есть потолок.

Рост current 1→6, desired дорос до 12, шесть нод в Pending, CPU застрял выше цели 60%, QPS до ~500/с.

Рост current 1→6, desired дорос до 12, шесть нод в Pending, CPU застрял выше цели 60%, QPS до ~500/с.

Что стало с запросами?

Я взял audit-лог: в нем записана длительность каждого запроса.

Картина оказалась очень интересной. Обычный запрос остался быстрым: и до пика, и на потолке половина запросов отвечала примерно за 130–150 мс. Замедлились только самые тяжелые. До пика даже редкие медленные укладывались в ~0.8 с, а на потолке растянулись до ~2 с (самый долгий 2.6 с); средняя по всем запросам выросла с 0.24 до 0.63 с.

Причина тут простая: новых нод нет, процессора на всех разом не хватает. Легкие запросы проскакивают, тяжелые встают в очередь и ждут свободный CN. Мой probe гонял как раз тяжелый запрос, поэтому и показывал 1.5–2.5 с, он попадал в эту медленную группу.

Ошибок при этом почти не было ,а тут кстати дашборд меня чуть не обманул. Счетчик ошибок рос до ~170 в секунду (видно на графике), и сначала я решил, что запросы отваливаются. В логе оказалось другое: почти все это select $$ это служебный пинг, который mysql-клиент шлет на каждом подключении, а StarRocks его не понимает и отклоняет. Больше соединений под нагрузкой больше таких отказов, вот счетчик и реагировал на нагрузку.

А как только я снял нагрузку, probe снова отвечал за ~30 мс, CPU упал к нулю, и кластер свернул лишние CN обратно к одному. Замедление держалось ровно пока не хватало нод, и ушло вместе с нагрузкой.

Вывод по тесту

Автоскейл CN эластичен ровно до предела самого кластера. Пока на узлах есть свободные ядра, он добавляет ноды и держит latancy в норме. Кончились ядра (у нас было два воркера, 16 ядер) — задержка упирается в потолок: HPA продолжает просить ноды (хочет 12), а ставить их некуда, поды висят в Pending, и CPU так и стоит выше цели.

Важно, КАК это проявляется. Не падениями и не ошибками. Успешность запросов держится. Проявляется ростом задержки у тяжелых запросов: они встают в очередь за свободным узлом, а обычные запросы при этом отвечают как раньше.

Отсюда три практических вывода:

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

  2. По-настоящему бесконечная эластичность появляется, только когда эластичны и сами ноды связка HPA и Cluster Autoscaler в облаке добавляет виртуалки под Pending-поды; на своем железе автоскейл экономит ресурсы между пиками, отдавая их соседям по кластеру, но не создает их сверх имеющихся.

  3. Все что видите на графиках дашборда лучше перепроверить другими средствами.

Чтобы не пропустить:

🔹Подписывайтесь на этот блог на Habr

🔹Между статьями — новости StarRocks в Telegram-канале @starrocks_selena (https://t.me/starrocks_selena)