2.7

2.7 Теория очередей

Обзор и мотивация

Теория очередей это математическое изучение линий ожидания. Это звучит как странное соответствие для книги об инженерных метриках программного обеспечения, пока вы не заметите, насколько большая часть конвейера доставки на самом деле является очередью: пулл-реквест, ждущий рецензента, коммит, ждущий исполнителя CI, заявка, ждущая, чтобы её взяли, сообщение клиентской поддержки, ждущее ответа. Тема 2.4 уже ввела нагрузку потока и время потока и показала, что перегрузка потока создания ценности резко замедляет доставку, а темы 2.5 и 2.6 показали, что большая часть времени доставки это время ожидания, а не время работы. Теория очередей это лежащая в основе математика, объясняющая, почему всё это верно, а не просто наблюдаемый паттерн.

Единственный самый полезный результат это закон Литтла, теорема, доказанная исследователем операций Джоном Литтлом в 1961 году: среднее число элементов в стабильной системе равно среднему темпу, с которым элементы прибывают, умноженному на среднее время, которое каждый элемент проводит в системе. Тема 2.4 уже использовала этот результат под собственными названиями Flow Framework, нагрузка потока равна темпу поступления, умноженному на время потока. В более широком словаре этой книги это также читается как незавершённая работа (тема 2.5), равная темпу поступления новой работы, умноженному на время цикла (тема 2.6). Это не эмпирическое правило и не корреляция, наблюдаемая в неких исследованиях. Это доказательство, верное для любой стабильной очереди, независимо от того, что эта очередь обрабатывает или как она решает, над чем работать дальше.

Для крупной команды эта общность и есть смысл. Закон Литтла даёт вам проверку здравого смысла, работающую идентично, является ли очередь канбан-доской, брокером сообщений или общим конвейером CI. Если ваша измеренная незавершённая работа, темп поступления и время цикла примерно не удовлетворяют уравнению, одно из ваших трёх чисел неверно, обычно из-за непоследовательного определения того, что считается «в процессе» или «прибывшим». Корпоративные и государственные организации управляют десятками таких очередей одновременно, общими пулами ревью кода, общими тестовыми средами, общими советами утверждения, и закон Литтла самый дешёвый доступный инструмент для обнаружения плохого определения метрики, прежде чем оно приведёт к плохому решению о кадрах или процессе.

Ключевые принципы

  • Закон Литтла это доказательство, а не эвристика. Незавершённая работа равна темпу поступления, умноженному на время цикла, для любой стабильной очереди, и это быстрая проверка того, внутренне ли согласованы ваши метрики доставки.
  • Утилизация не масштабируется линейно со временем ожидания. По мере приближения общего ресурса к полной утилизации задержка очереди растёт резко, а не постепенно. Ресурс, работающий при занятости 95%, часто ждёт во много раз дольше, чем ресурс при 80%, а не просто «немного хуже».
  • Среднее значение очереди скрывает её худший случай. Сообщение только среднего времени ожидания скрывает долгий болезненный хвост около полной мощности, именно то, против чего предупреждает тема 1.6, когда речь идёт об использовании перцентилей вместо средних.
  • То, как определена очередь, можно подделать так же легко, как и любую другую метрику. Считается ли что-то «прибывшим», «в процессе» или «обслуженным» это выбор, и его можно настроить, чтобы приукрасить дашборд, не меняя того, что на самом деле происходит с работой.
  • Конвейер обычно является очередью очередей. Конвейер доставки связывает несколько этапов вместе, и самый медленный этап задаёт темп для всей цепочки независимо от того, насколько быстро работают остальные.

Рекомендации

Используйте закон Литтла, чтобы проверить ваши собственные числа, прежде чем им доверять

Возьмите измеренную среднюю незавершённую работу вашей команды, её средний темп поступления новых элементов в неделю и её среднее время цикла и проверьте, примерно ли незавершённая работа равна темпу поступления, умноженному на время цикла. Когда это не так, не предполагайте, что теория неверна. Ищите фактическую причину: граница этапа, подсчитанная непоследовательно, работа, которая сидит «заблокированной», но всё ещё считается в процессе, или темп поступления, измеренный за иное окно, чем время цикла. Эта единственная проверка улавливает больше плохого инструментирования, чем большинство команд находят любым другим способом.

Отслеживайте утилизацию напрямую для каждого общего ресурса с ограниченной мощностью

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

Отделяйте темп поступления, темп успеха, темп отказа и темп пропуска

Сопротивляйтесь сворачиванию всего, что покидает очередь, в единственное число «пропускной способности» или «темпа обслуживания». Отслеживайте четыре вещи отдельно: насколько быстро прибывает работа, сколько из неё успешно завершается, сколько проваливается и нуждается в переделке, и сколько заброшено или тихо отброшено до того, как кто-либо его завершит. Конвейер, выглядящий быстрым, потому что его темп пропуска тихо вырос, на самом деле не доставляет больше, и только отслеживание этих четырёх темпов отдельно покажет вам это.

Моделируйте многоэтапные конвейеры как очередь очередей

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

Устанавливайте лимиты кадров и НЗР с учётом утилизации, а не только пропускной способности

Когда вы решаете, сколько рецензентов или исполнителей CI нужно команде, не подгоняйте мощность точно под средний темп поступления. Очередь, работающая в среднем при 100% утилизации, на практике имеет фактически бесконечное время ожидания, потому что реальные прибытия неравномерны, а не идеально гладки. Сознательно планируйте запас и относитесь к «наши рецензенты почти всегда заняты» как к предупреждающему знаку о грядущих временах ожидания, а не как к доказательству эффективного распределения ресурсов.

Компромиссы: плюсы и минусы

ПодходПлюсыМинусы
Отсутствие формальной модели очереди, кадры по интуицииБыстро начать; никакого нового словаря для командыПоследовательно недооценивает, насколько резко взрывается время ожидания около полной мощности
Закон Литтла как проверка здравого смысла на существующих метрикахДёшево, не требует нового инструментария, быстро улавливает плохие определенияПроверяет только согласованность, сама по себе не диагностирует причину
Полная симуляция очереди (распределения прибытий, несколько серверов)Самое точное предсказание поведения времени ожидания под нагрузкойТребует настоящего статистического навыка и обслуживания, которое большинство команд не поддержит
Отслеживание утилизации на общих ресурсах без более глубокого моделированияПросто, действенно, улавливает единственную крупнейшую причину неконтролируемого времени ожиданияНичего не говорит о том, почему утилизация высока или что делать с лежащей в основе причиной

Центральное напряжение: строгость против принятия. Полная симуляция очереди даёт самый точный ответ, но почти никакая инженерная команда не построит и не будет поддерживать её, а модель, которой никто не доверяет и не обновляет, хуже отсутствия модели. Закон Литтла и базовое отслеживание утилизации жертвуют некоторой точностью, но не требуют специализированного статистического навыка и напрямую вписываются в метрики, которые команда уже собирает для тем с 2.4 по 2.6. По умолчанию используйте эти дешёвые доступные для принятия проверки и резервируйте полную симуляцию для редкого случая, когда единственный общий ресурс, большой флот CI, специализированный пул ревью, достаточно дорог, чтобы оправдать инвестицию.

Вопросы для обсуждения в команде

  1. Удовлетворяют ли наша измеренная незавершённая работа, темп поступления и время цикла на самом деле закону Литтла, и если нет, то почему? Это единственная самая быстрая доступная диагностика плохого определения метрики. Пройдите через фактические числа вместе, и если уравнение примерно не выполняется, проследите несоответствие до конкретной несогласованности определения, а не отвергайте проверку.

  2. Какие общие ресурсы в нашем конвейере доставки работают близко к полной утилизации, и действительно ли мы знаем их число утилизации? Большинство команд могут назвать ресурс, который «всегда ощущается занятым», но никогда не измеряли его утилизацию напрямую. Определите два-три самых ограниченных общих ресурса и получите реальное число для каждого.

  3. Смешиваем ли мы успех, отказ и пропуск в одно число пропускной способности, и что бы мы увидели, если бы разделили их? Единственный подсчёт «завершённых элементов» может расти, даже когда качество падает или работа тихо заброшена. Пересчитайте пропускную способность недавнего периода как три отдельных числа и обсудите, что раскрывает разделение, которое скрывало смешанное число.

  4. Где в нашем конвейере настоящее узкое место, самый медленный этап, задающий темп для всего, что ниже по течению от него? Команды часто инвестируют в ускорение этапа, который проще всего улучшить, а не того, который фактически ограничивает общую пропускную способность. Определите этап с худшей комбинацией высокой утилизации и высокого темпа отказа или пропуска.

  5. Если бы мы добавили мощности к нашему самому ограниченному общему ресурсу, действительно ли улучшилось бы время ожидания, или спрос просто расширился бы, чтобы его заполнить? Этот вопрос отделяет настоящий дефицит мощности от проблемы спроса, и ответ меняет, является ли правильным исправлением больше персонала, лимит НЗР или изменение того, как работа приоритизируется до входа в очередь.

  6. Переопределяли ли мы когда-либо то, что считается «в процессе» или «прибывшим», так, что дашборд выглядел лучше, не меняя того, что на самом деле происходило с работой? Стоит спросить это честно и конкретно, с реальными примерами за последний год, а не относиться к этому как к гипотетической заботе.

Отраслевой взгляд

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

Малый бизнес. Команде малого бизнеса редко нужно что-то более изощрённое, чем отслеживание утилизации на одном-двух по-настоящему общих ресурсах, часто единственном рецензенте или единственном конвейере развёртывания, и наблюдение за точкой, где «обычно доступен» тихо становится «обычно узким местом». Таблицы достаточно; выделенный инструментарий не нужен в этом масштабе.

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

Государство. Многоагентские и мультивендорные программы доставки часто маршрутизируют работу через общие советы утверждения, общие процессы аккредитации безопасности и общие тестовые среды, которые ни одна отдельная команда не контролирует и не может изменить размер самостоятельно. Анализ очередей этих общих шлюзов, темп поступления, мощность, утилизация, часто самое ясное доступное доказательство для бизнес-кейса на добавление мощности или изменение того, как работа пакетируется до достижения шлюза.

Примеры

Корпорация. Внутренняя платформенная команда провайдера облачной инфраструктуры заметила, что время выполнения для изменений (тема 2.10) ползло вверх у каждой продуктовой команды, зависящей от её общего флота CI, даже несмотря на то что ни одна отдельная команда не меняла то, как она работает. Анализ утилизации обнаружил, что флот работал выше 90% занятости в основные часы, далеко за точкой, где теория очередей предсказывает, что время ожидания растёт резко, а не постепенно. Платформенная команда добавила мощность CI и ввела политику справедливого распределения планирования, чтобы всплеск активности ни одной отдельной команды не мог монополизировать очередь. Медианное время ожидания CI упало более чем вдвое в течение месяца, доказательство того, что узким местом всё это время была общая невидимая очередь.

Государство. Команда цифровых услуг национального агентства по выдаче разрешений отслеживала обработку заявлений как единственное число пропускной способности «дел закрыто в неделю» в течение двух лет, и это число выглядело стабильным. Более пристальный анализ, разделивший это число на одобренные дела, отклонённые и заброшенные заявителями после долгих задержек, обнаружил, что темп отказа от заявлений почти утроился за тот же период, в то время как одобрения оставались плоскими. Закон Литтла, применённый к очереди работников по делам, показал, что незавершённая работа выросла далеко за пределы того, что подразумевало заявленное средним время обработки команды, означая, что дела тихо накапливались в статусе, не считавшемся «ожидающим». Агентство реструктурировало свои определения отслеживания дел, чтобы честно считать каждое открытое дело, и добавило мощность работников по делам, рассчитанную на удержание утилизации ниже 85%, теперь отслеживаемую как постоянную операционную цель наряду с числом пропускной способности.

Бизнес-кейс: мотивация, ROI и TCO

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

Полная стоимость принятия по-настоящему низкая. Закону Литтла и отслеживанию утилизации не нужен новый инструментарий сверх того, что темы с 2.4 по 2.6 уже просят вас собирать: темп поступления, незавершённая работа и время цикла. Инвестиция в основном аналитическая дисциплина, проверка чисел друг против друга и периодический обзор утилизации на общих ресурсах, прежде чем они станут следующей необъяснённой регрессией времени выполнения организации.

Антипаттерны и ловушки

  • Подгонка мощности общего ресурса точно под его средний темп поступления: гарантирует высокую утилизацию и неконтролируемые времена ожидания всякий раз, когда спрос даже кратковременно неравномерен.
  • Сообщение только среднего времени ожидания, никогда перцентиля: скрывает долгий хвост, имеющий наибольшее значение для людей, ожидающих в нём.
  • Смешивание успеха, отказа и пропуска в одно число пропускной способности: вектор манипулирования в сердце этой темы. Команда под давлением может заставить пропускную способность выглядеть здоровой, тихо позволяя темпу пропуска расти, заброшенные заявки, тихо отброшенные запросы, работа, никогда не засчитанная как отказ. Страховка отслеживать темп поступления, успеха, отказа и пропуска как четыре отдельных видимых числа, та же дисциплина, которую тема 1.2 требует для каждой метрики в этой книге, так что растущий темп пропуска не может спрятаться за плоской диаграммой пропускной способности.
  • Отношение к «наши люди всегда заняты» как к комплименту: это симптом высокой утилизации, главной причины долгих непредсказуемых времён ожидания.
  • Переопределение «в процессе», чтобы тихо сжать незавершённую работу: перемещает работу в неучтённое состояние, «заблокировано», «на паузе», не меняя того, сколько времени занимает её завершение, и ломает проверку закона Литтла, которая иначе бы это поймала.
  • Предположение, что модель очереди не нуждается в обслуживании после построения: паттерны прибытия и мощность постоянно меняются, а устаревшая модель производит уверенно неверные предсказания.

Модель зрелости

  • Уровень 1, Инициация: Ни одна очередь не измеряется явно; время ожидания обсуждается анекдотически как «вещи ощущаются медленными».
  • Уровень 2, Развитие: Темп поступления, незавершённая работа и время цикла отслеживаются хотя бы для одного конвейера, но никогда не проверяются против закона Литтла или утилизации на общих ресурсах.
  • Уровень 3, Стандартизация: Закон Литтла это рутинная проверка согласованности по конвейерам доставки, а утилизация явно отслеживается для самых значимых общих ресурсов.
  • Уровень 4, Управление: Темпы успеха, отказа и пропуска отслеживаются отдельно для каждой значимой очереди, а решения о мощности используют цели утилизации, а не только средний спрос.
  • Уровень 5, Оркестрация: Организация моделирует свои основные конвейеры как очереди очередей, систематически выявляет настоящие узкие места и может указать на конкретные изменения мощности или процесса, сделанные благодаря анализу очередей, с измеренным улучшением времени ожидания, чтобы это показать.

Идеи для обсуждения

  1. Выберите один из наших конвейеров доставки и проверьте, удовлетворяют ли его числа сегодня закону Литтла.
  2. Назовите единственный общий ресурс в нашей организации, с которым большинство людей согласились бы, что он «всегда занят», и найдите его фактическое число утилизации.
  3. Как бы выглядела наша диаграмма пропускной способности, если бы мы разделили её на темпы успеха, отказа и пропуска за прошлый квартал?
  4. Если бы нам нужно было добавить мощность ровно к одному общему ресурсу в этом году, какому именно, и какое доказательство бы это оправдало?

Основные выводы

  • Закон Литтла, незавершённая работа равна темпу поступления, умноженному на время цикла, это доказательство, а не эвристика, и это самая дешёвая доступная проверка того, внутренне ли согласованы ваши метрики доставки.
  • Время ожидания растёт резко, а не постепенно, по мере приближения утилизации к полной мощности. Относитесь к «всегда занят» как к предупреждающему знаку, а не комплименту.
  • Отслеживайте темп поступления, темп успеха, темп отказа и темп пропуска отдельно; их смешение в одно число пропускной способности центральный вектор манипулирования этой темы.
  • Моделируйте многоэтапный конвейер как очередь очередей и инвестируйте в этап с худшей комбинацией высокой утилизации и высокого темпа отказа или пропуска, а не в этап, который проще всего улучшить.
  • Предпочитайте дешёвые доступные для принятия проверки, закон Литтла и отслеживание утилизации, полной симуляции очереди, которую мало какие команды поддержат.

Источники и дальнейшее чтение

  • Little, John D. C. “A Proof for the Queuing Formula: L = λW.” Operations Research, 1961.
  • Kleinrock, Leonard. Queueing Systems, Volume 1: Theory. Wiley-Interscience, 1975.
  • Wescott, Bob. The Every Computer Performance Book: How to Avoid and Solve Performance Problems on the Computer Systems You Work With. CreateSpace Independent Publishing Platform, 2013.
  • Reinertsen, Donald G. The Principles of Product Development Flow: Second Generation Lean Product Development. Celeritas Publishing, 2009.
  • Vacanti, Daniel S. Actionable Agile Metrics for Predictability. Actionable Agile Press, 2015.