Закон Литтла
Шаг 1 из 8
Три величины и одно равенство
Закон Литтла связывает три величины: L — сколько заявок в среднем находится в системе, λ — с какой интенсивностью они в неё поступают, W — сколько времени каждая в ней проводит. По любым двум вычисляется третья.
В 1954 году соотношение уже использовали как очевидное: у Кобхема оно приведено без доказательства. Доказательство предложил Джон Литтл в 1961 году; более простые позже дали Джуэлл, Эйлон и Стидем.
Шаг 2 из 8
L = λ × W
Формулировка: долгосрочное среднее количество заявок L в стационарной системе равно долгосрочной средней интенсивности входного потока λ, умноженной на среднее время пребывания заявки в системе W.
Десять заявок в секунду, каждая проводит в системе тридцать секунд — в системе в среднем триста заявок. Размерность сходится: заявок в секунду, умноженное на секунды, даёт заявки.
Связь не зависит ни от распределения поступления, ни от распределения обслуживания, ни от порядка обслуживания. Заявки приходят равномерно или залпами, обслуживаются по очереди, с конца или по приоритету — равенство выполняется одинаково. Числа обслуживающих приборов в нём тоже нет.
Этим закон отличается от остального аппарата теории массового обслуживания. Там, чтобы что-то посчитать, распределения нужно знать. Здесь достаточно двух измеренных средних.
little.ts// L = lambda * W const inSystem = arrivalsPerSecond * secondsInSystem;Вывод
10 /s × 30 s = 300 in the system at any moment no assumption about arrival pattern, service order or server count
Шаг 3 из 8
Любая из трёх по двум другим
Калькулятор справа. λ и W входят в произведение симметрично: удвоение интенсивности и удвоение времени пребывания дают один результат.
Само W ползунком не задаётся — оно складывается из ожидания и обслуживания. Поэтому сокращение времени обслуживания уменьшает и W, и L, и число обслуживающих приборов: λS падает вместе с S. Внешний сервис, наоборот, стал отвечать втрое дольше — выросли и W, и L, и счёт за инфраструктуру, хотя ни одна величина на нашей стороне не менялась.
Ожидание при этом остаётся входной величиной, и это не упрощение. Насколько сократится очередь оттого, что обслуживание ускорилось, закон Литтла не говорит — у него в условиях нет ни распределений, ни загрузки. Это предмет теории массового обслуживания, и на шаге про ограничения об этом сказано отдельно.
Исходные величины
Что из них следует
- Время пребывания W
- 30 с
- Заявок в системе L
- 300 шт.
- На обслуживании λS
- 100 шт.
- В очереди λWq
- 200 шт.
- Обслуживающих приборов
- 100 шт.
W = 20 + 10 = 30 с, и тогда L = λW = 300 заявок
Тот же закон на обслуживании: λS = 10 × 10 = 100. В очереди остальные 200.
Ожидающих больше, чем обслуживаемых: основная часть W приходится на ожидание, и сокращать нужно его.
Шаг 4 из 8
Длина очереди как разность
Закон применим не только к системе целиком, но и к любой её подсистеме. В классическом примере с банком очередь клиентов — одна подсистема, а каждый из кассиров — другая.
Применяем его дважды. Ко всей системе: λW, все заявки внутри. К обслуживанию: λS, где S — время обслуживания без ожидания. Разность — длина очереди.
Десять заявок в секунду, тридцать секунд пребывания, из них десять — обслуживание. В системе триста, на обслуживании сто, ожидают двести.
Отсюда правило для размера пула: считать по λS. Ожидающая заявка занимает место в очереди, а не обслуживающий прибор. Расчёт по λW даёт втрое больше машин, чем нужно работе.
У Брайана Гетца в «Java Concurrency in Practice» это записано как число потоков = ядра × целевая загрузка × (1 + время ожидания / время работы). Дробь в скобках — то же отношение ожидания к обслуживанию, из-за которого потоков требуется больше, чем ядер.
little.ts// The same law on a smaller box: service only. const inService = arrivalsPerSecond * serviceSeconds; const waiting = inSystem - inService; // The pool is sized by service: waiting items do not hold a worker. const workers = Math.ceil(inService / itemsPerWorker);Вывод
10 /s × 10 s = 100 being served, 200 waiting in the queue 100 / 1 item per worker = 100 workers
Шаг 5 из 8
Обратная подстановка: W = L / λ
Равенство, решённое относительно времени пребывания.
Так читают графики очереди. Число «сорок тысяч сообщений» само по себе не интерпретируется: это может быть рабочим состоянием, а может быть аварией. Разделив на интенсивность разбора — двести в секунду, — получаем двести секунд. Порог «глубина больше сорока тысяч» означает «заявка ждёт больше трёх минут».
Отсюда и практика настраивать алерт по возрасту самой старой заявки, а не по глубине очереди. Возраст — это W, та самая величина, о которой даётся обещание пользователю. Глубина без λ не интерпретируется: тысяча сообщений при интенсивности разбора десять тысяч в секунду — это одна десятая секунды, а сто сообщений при интенсивности одно в секунду — сто секунд.
little.ts// W = L / lambda — the same equality, solved for time. const secondsToDrain = queueDepth / drainedPerSecond;Вывод
40 000 messages / 200 per second = 200 s before the queue is empty alert threshold "depth > 40 000" == "the oldest message is 200 s old"
Шаг 6 из 8
Условия применимости
От системы требуется немного: стационарность и отсутствие вытесняющей многозадачности. Оба условия исключают переходные состояния, в том числе запуск и остановку.
Стационарность на практике проверяют так: на достаточно длинном окне из системы выходит столько же заявок, сколько в неё вошло. Если интенсивность входного потока выше пропускной способности, стационарности нет. Очередь растёт, W растёт вместе с ней, и среднего значения у него не существует. Равенство при этом не нарушается — оно показывает, что L растёт, — но предсказывать им нечего: считать надо разность между λ и пропускной способностью.
Пропускная способность выводится из тех же величин: число обслуживающих приборов, делённое на время обслуживания. Сто приборов по десять секунд дают ровно десять заявок в секунду. При λ = 10 загрузка стопроцентная, и любое отклонение даёт очередь, которая уже не рассасывается.
Окно наблюдения должно быть длинным относительно W. Для заявки длиной в минуту закон отвечает про десятки минут, а не про то, что происходило внутри одной.
Шаг 7 из 8
Чего закон не даёт
Все три величины — средние, причём долгосрочные. Из этого следуют три ограничения, и про все три регулярно забывают.
Из L = 300 не следует, что в системе всегда триста заявок. Это могут быть ровные триста, а могут — ноль половину суток и три тысячи в час пик. Пул, рассчитанный по среднему, пик не выдержит; поэтому в оценках появляется отдельный коэффициент неравномерности.
О разбросе закон тоже молчит. Среднее W в двадцать секунд совместимо с тем, что один процент заявок ждёт десять минут. Поэтому обещания пользователю формулируют в процентилях, а не в средних.
И он не отвечает, что станет с W при росте λ. Пропускная способность в десять заявок в секунду не означает, что девять — рабочий режим: с приближением загрузки к единице очередь растёт нелинейно. Это уже предмет теории массового обслуживания, и там без распределений не обойтись. Литтл даёт L при известном W; как изменится W при росте λ, он не говорит.
Шаг 8 из 8
Где он применяется
Три подстановки в одно равенство:
- число обслуживающих приборов — λS, делённое на то, сколько заявок держит один;
- длина очереди — λW − λS;
- время ожидания — L / λ.
За пределами теории массового обслуживания то же равенство известно под другими именами. В канбане оно записано как «время цикла = WIP / пропускная способность», а лимиты на незавершённую работу — способ удерживать L, чтобы не росло W.
Начинается всё не с формулы, а с границ системы: что считать системой, что в неё входит и что из неё выходит. Дальше умножение. В разборе про скрейпинг-джобы так считается размер пула воркеров.
Листать шаги можно стрелками ← и →.
Проверь себя
Поток джоб не изменился, но целевой API стал отвечать вдвое медленнее. Что произойдёт с числом джоб, находящихся в работе одновременно?
L = λW. Интенсивность не менялась, время пребывания выросло вдвое — значит вдвое выросло и число заявок в системе. Порядок обслуживания и распределение поступления на это не влияют.
В очереди двадцать тысяч сообщений, потребители разбирают тысячу в секунду. Сколько ждёт сообщение, пришедшее прямо сейчас?
W = L / λ: 20 000 / 1 000 = 20 секунд. Это среднее; насколько дольше ждёт невезучая заявка, закон не говорит.
Внутри системы в среднем триста единиц: сто обслуживаются, двести ждут. Сколько обслуживающих приборов нужно, если один держит одну единицу?
Двести ожидающих заявок занимают место в очереди, а не обслуживающие приборы. Пул считается по λS.
Отвечено 0 из 3