Смело гуглим горизонтальное масштабирование и смотрим на верхние ссылки:
Почему? Они все время "забывают" вам сказать, какой сервер стоит масштабировать... И какой точно нет!
Ага, значит гуглим какой сервер масштабировать и... Вот поэтому была написана эта статья.
Не, ну смешно! Сами ж сказали, что ждали минуту.
Сказали, но есть нюанс...
Например, зададимся вопросом: если крепкий студент за минуту на дубе считает любимых ворон -- сколько их за минуту обкашляют десять студентов? ОКай, 10 студентов обслужат 10 дубов за минуту. Тем самым, 10 студентов, ожидая минуту, всего потеряли 10 минут рабочего времени.
Они тупо стояли и ждали. А могли бы считать ворон.
Нет, погодите! Хоть десять, хоть двадцать студентов, но мои «Водолазные» Челябинского завода четко показывают, что прошла всего лишь минута.
Все правильно, часы часам рознь! Именно в ней и скрывается суть Масштабирования.
И если апгрейднуть студента ходулями, он сможет считать быстрее! Тем самым, за ту же минуту, высокий студент нам обслужит два дуба!
Смотрите:
И все больше и больше желающих:
Так, что сервер уже не может!
Что делать? Расширять производство! Т.е. масштабировать сервер.
Но не очень спешите, пока не увидели:
Ой! Их тут целая банда?!
Да, ребята, в реальной жизни за фронт сервером прячется тазик товарищей! И чтобы не скучно, они ездят на базу:
Вот теперь можно и масштабировать!
Раз Server не справляется с Client-ами, самое время стартануть десяточку дополнительных инстансов...
Гмм, а если не будет толку? Вдруг фронт Server не успевает, потому что его тормозит Server L? Или Server R2??
Ай, чтобы долго не мучаться, мы сейчас стартанем по десяточке ВСЕХ дополнительных.
Шарик, ты балбес!
Ой, так нельзя. Поздравляю, Шарик, ты балбес! Добавить всех по десяточке -- верный способ слить деньги (AWS, Azure, GCP… все они аплодируют стоя).
Так, а что делать?
Все очень просто:
Стараемся сделать получше. Мощнее. Изящнее!
Ускорить в несколько раз компонент и доказать слова тестами.
Вот только бизнес... А Бизнес, ребята, работает только весь сразу! Весь сразу бизнес, включая вашу зарплату, должен в общем итоге сгенерировать прибыль.
Постоянно имейте в виду, что мы масштабируем сервисы ради потребностей бизнеса! Мы не масштабируем, если нет выхлопа. Точка.
Конечно, никто не спорит, что есть множество разных решений, заметно ускорящих (или замедлящих) определенную часть бизнеса в некотором узком контексте. Но смысл имеет только результат реального использования.
Смотрите, даже ДЕСЯТИКРАТНОЕ ускорение "какого-то компонента" просто никто не заметит, если раньше там набегало лишние 10 секунд за сутки, а теперь стала только одна. Это практически бесполезно. А время и деньги уже потрачены...
Так что же, нет смысла стараться?!
Ради этого места реального бизнеса АБСОЛЮТНО нет смысла стараться. Хуже дурака -- только дурак с инициативой!
Нет смысла стараться нигде, кроме узкого места (bottleneck). Но развальцуете бизнесу bottleneck -- он сразу пойдет веселее!
Тут самое время напомнить один из лучших фрагментов книги Gene Kim, Kevin Behr, George Spafford "The Phoenix Project":
“Let me tell you a story. Decades ago, there used to be a guy named Mark. He was the supervisor for that first work center, right down there by that desk. Those racks hold the folders for incoming jobs. Isn’t it amazing that those folders look exactly like they did back then?
“At any rate,” he continues, “one day I see Mark picking up a folder to start some job. I ask him, ‘On what basis did you choose that job, versus any of the others?’ “And you know what he tells me? He says, ‘It’s a job that requires this work center first. And we’re open.’” He shakes his head incredulously. “I could hardly believe it. I tell him, ‘Your station is just the first of twenty operations. You don’t factor the availability of any of the other nineteen stations in your decision?’ And he replies, ‘Well, no. This is the way I’ve done it for twenty years.’” He laughs. “I suppose to him, it sounds like a reasonable way to pick which job to perform. He’s keeping the first station busy, and it’s similar to first-in, first-out scheduling. But of course, now everyone knows that you don’t release work based on the availability of the first station. Instead, it should be based on the tempo of how quickly the bottleneck resource can consume the work.” I just stare at him blankly. He continues, “Because of how Mark was releasing work, inventory kept piling up in front of our bottleneck, and jobs were never finished on time. Every day was an emergency. For years, we were awarded Best Customer of the Year from our air freight shipment company, because we were overnighting thousands of pounds of finished goods to angry customers almost every week.” He pauses and then says emphatically, “Eliyahu M. Goldratt, who created the Theory of Constraints, showed us how any improvements made anywhere besides the bottleneck are an illusion. Astonishing, but true! Any improvement made after the bottleneck is useless, because it will always remain starved, waiting for work from the bottleneck. And any improvements made before the bottleneck merely results in more inventory piling up at the bottleneck.” He continues, “In our case, our bottleneck was a heat treat oven, just like in Goldratt’s novel, The Goal. We also had paint-curing booths that later became constraints, too. By the time we froze the release of all new jobs, you couldn’t even see the bottleneck work centers because they were surrounded by huge piles of inventory. Even from up here!” |
Шикарная аналогия!
Если ваша работа -- конвейер, а его узкое место печь, то:
Запускаем demoscale, передавая 100
сообщений от одного клиента C
одному серверу S
:
$ demoscale one 100 C/1/0 S/1/50 #CmdName NumMsg Time RPS one{1,1} 100 6.613s 15.121 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 1 0.000s ->S 1 0.050s 100 15.121 0.000s 0.000s 0.066s 15.139 [100 0 0]% |
Как можно видеть, сервер справился за 6.613
секунды.
Для простоты положим, что:
6.6
секунды.
100
тугриков (15.2
тугрика в секунду).
80
тугриков на сервер (12.1
туг/сек).
3.0
туг/сек -- неплохо по нынешним временам!
Но нам все равно мало. Давайте удвоим количество инстансов сервера, чтобы быстрее пришла сотня тугриков:
$ demoscale one 100 C/1/0 S/2/50 one{1,2} 100 6.636s 15.070 C 1 0.000s ->S 2 0.050s 100 15.070 0.000s 0.000s 0.066s 30.162 [100 0 0]% |
Опа!
6.6
секунды. Как так?!
100
тугриков.
160
, т.к. серверов стало два (AWS, Azure, GCP… хищно осклабились).
9.1
туг/сек!!!
Шарик... Ты меня понял!
Но беда не приходит одна. Прямо щас на один бедный сервер навалятся два клиента:
$ demoscale one 100 C/2/0 S/1/50 one{2,1} 100 6.639s 15.062 C 2 0.000s ->S 1 0.050s 100 15.062 0.000s 0.066s 0.066s 15.068 [1 99 0]% |
Гы! А ведь хуже не стало.
Один сервер, 6.6
секунды, сотня сообщений -- прибыль есть! Те же самые 3.0
туг/сек.
Ладно, раз уж есть два клиента, давайте подложим два сервера:
$ demoscale one 100 C/2/0 S/2/50 one{2,2} 100 3.331s 30.020 C 2 0.000s ->S 2 0.050s 100 30.022 0.000s 0.000s 0.067s 30.042 [100 0 0]% |
Ага!
3.3
секунды -- в два раза меньше!
100
тугриков -- 30.3
туг/сек.
80
тугриков, т.к. два сервера в два раза меньше работали -- 24.2
туг/сек.
6.1
туг/сек -- развальцевали!
Не, ну вдумайтесь еще раз: хоть дополнительный сервер и удваивает наши расходы (бухгалтерия пьет валидол), но доходы все кроют с запасом!!!
И да, мы удвоили прибыли AWS, Azure, GCP… но никто не в обиде. Win-win situation.
ОКай, хорошо. А теперь объясните мне каждый вариант. Как-то все неожиданно.
50
синхронный сообщений. Их последовательно обрабатывает один сервер. Это узкое место -- его нужно расширить!
Ну как, реальные. Использовать мы будем demoscale -- специально написанную мною программу. Ее особенности в том, что:
demoscale
запускает потоки (threads, а точней goroutines). Т.е. demoscale
-- это просто процесс, в котором инстансы клиентов/серверов моделируются потоками.
demoscale
моделирует только синхронные сообщения. Т.е. каждый поток клиента ожидает ответ сервера перед тем, как отправить следующее.
demoscale
содержит несколько готовых конфигураций серверов: one
, list
, tree
, rhomb
и wshape
. Но при желании, вы можете легко добавить собственную.
Name/NumInst/Slp
(например, S1/2/30
), где:
Name
-- имя сервера (S1
).
NumInst
-- количество инстансов (2
).
Slp
-- время задержки в миллисекундах (30
).
Три сервера друг за другом. RPS каждого сервера ограничивается предыдущим (requests per second, пропускная способность).
Первый запуск:
$ demoscale list 400 C/8/0 S1/1/30 S2/1/40 S3/1/50 #CmdName NumMsg Time RPS list{8,1,1,1} 400 70.203s 5.698 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S1 1 0.030s 400 5.698 0.818s 0.345s 0.175s 5.698 [1 2 97]% S2 1 0.040s 400 5.701 0.000s 0.000s 0.127s 7.849 [100 0 0]% S3 1 0.050s 400 5.706 0.000s 0.000s 0.064s 15.643 [100 0 0]% |
Мы видим, что:
8
инстансов клиента и по 1
инстансу каждого сервера.
400
сообщений. Т.е. каждый из 8
клиентов отправил по 50
.
70.203
секунды.
5.698
(=400/70.203
).
5.698
, 5.701
и 5.706
соответственно.
5.698
, 7.849
и 15.643
.
[1 2 97]
, [100 0 0]
и [100 0 0]
. Т.е. 97%
времени очередь первого сервера S1
была целиком заполнена. А его ненулевое время Wait1 (0.818
) говорит нам о том, что кто-то стоял и вне очереди.
3
дополнительных инстанса. Куда бы мы их добавили?
Ну, ответ очевиден: единственная забитая очередь -- это очередь первого сервера. На бедный инстанс навалилось восемь хулиганов!
Добавляем:
$ demoscale list 400 C/8/0 S1/2/30 S2/1/40 S3/1/50 list{8,2,1,1} 400 52.989s 7.549 C 8 0.000s ->S1 2 0.030s 400 7.549 0.511s 0.262s 0.265s 7.557 [1 0 99]% S2 1 0.040s 400 7.555 0.000s 0.069s 0.132s 7.555 [48 52 0]% S3 1 0.050s 400 7.563 0.000s 0.000s 0.069s 14.499 [100 0 0]% |
О! 52.989
секунды вместо 70.203
-- это уже хорошо. Это 75%
, что меньше на четверть.
Что дальше?
Формально говоря, красная очередь [1 0 99]
первого сервера нам четко показывает, что он все еще bottleneck. Но! Очередь второго сервера [48 52 0]
вдруг пожелтела -- самое время пристально на него взглянуть.
RPS(W) второго сервера 7.555
, а у первого -- 7.557
, т.е. S1
может работать чуть-чуть быстрее S2
. Две тысячные секунды конечно ничтожная мелочь, но для нашего обучения пусть это станет сигналом.
Итак, раз S2
самый медленный, давайте ему поможем:
$ demoscale list 400 C/8/0 S1/2/30 S2/2/40 S3/1/50 list{8,2,2,1} 400 36.293s 11.021 C 8 0.000s ->S1 2 0.030s 400 11.021 0.342s 0.175s 0.180s 11.117 [3 1 96]% S2 2 0.040s 400 11.035 0.000s 0.000s 0.132s 15.177 [100 0 0]% S3 1 0.050s 400 11.053 0.000s 0.000s 0.069s 14.505 [100 0 0]% |
Не зря потратились! 36.293
секунды выглядят еще лучше.
Но остался еще один инстанс -- куда бы его воткнуть? Правильно, ставим на красное!
$ demoscale list 400 C/8/0 S1/3/30 S2/2/40 S3/1/50 list{8,3,2,1} 400 25.867s 15.463 C 8 0.000s ->S1 3 0.030s 400 15.463 0.185s 0.127s 0.193s 15.547 [1 1 98]% S2 2 0.040s 400 15.489 0.000s 0.001s 0.129s 15.558 [98 2 0]% S3 1 0.050s 400 15.525 0.000s 0.001s 0.064s 15.574 [99 1 0]% |
25.867
секунды!!! У Шарика будет фоторужье.
А теперь и не страшно всТупить на путь наименьшего сопротивления: ща тупо докинем по инстансу каждому серверу:
$ demoscale list 400 C/8/0 S1/2/30 S2/2/40 S3/2/50 list{8,2,2,2} 400 36.293s 11.021 C 8 0.000s ->S1 2 0.030s 400 11.021 0.340s 0.180s 0.181s 11.036 [1 0 99]% S2 2 0.040s 400 11.034 0.000s 0.000s 0.133s 15.054 [100 0 0]% S3 2 0.050s 400 11.052 0.000s 0.000s 0.069s 28.896 [100 0 0]% |
36.293
секунды -- считай то же самое, что и у list{8,2,2,1}
. Но тот не использует лишний инстанс!
Хотя ничего удивительного: дополнительный инстанс S3
поднял его RPS(W) с 14.505
до 28.896
, но в этом нет никакого смысла, т.к. всех ограничивает S1
(значением возле 11
).
А, чуть не забыл!
Вам конечно же интересно взглянуть, как оно там внутри... Не интересно? А я все равно расскажу!
Короче, есть тут секретный ключ -msg
, выводящий содержимое сообщений. Его можно использовать так:
$ demoscale -msg list 16 C/8/0 S1/2/30 S2/2/40 S3/2/50 1713042911010 > C[2] -> S1 0 1713042911027 > S1[0] -> S2 1713042911043 > S2[0] -> S3 1713042911108 < S3[1] 0 1713042911140 < S2[0] 0 1713042911173 < S1[0] 0 ... 1713042912352 > C[4] -> S1 1 1713042912373 > S1[0] -> S2 1713042912394 > S2[0] -> S3 1713042912458 < S3[1] 8 1713042912500 < S2[0] 8 1713042912527 < S1[0] 8 |
Ну и что мы тут видим? А все просто как грабли:
1713042911010
второй инстанс клиента C[2]
отправил серверу S1
запрос номер 0
.
1713042911027
инстанс S1[0]
отправил S2
запрос.
1713042911043
инстанс S2[0]
отправил S3
запрос.
1713042911108
инстанс S3[1]
отправил ответ номер 0
.
1713042911140
инстанс S2[0]
отправил ответ номер 0
.
1713042911173
инстанс S1[0]
отправил ответ номер 0
.
Например, даже Печкин вам скажет, что время обработки сообщения = время ожидания + время работы. А по цифрам выходит, что RPS не зависит от Wait1 и Wait2...
Так не бывает!
Гы, а вы сами взгляните на тайминги.
Те же три сервера, но фронт ближе к бэкам. Как следствие, SL
уже не ограничивает SR
, т.к. не вызывает.
Первый запуск:
$ demoscale tree 400 C/8/0 S/1/30 SL/1/40 SR/1/50 #CmdName NumMsg Time RPS tree{8,1,1,1} 400 71.168s 5.621 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 5.621 0.829s 0.352s 0.178s 5.621 [1 0 99]% SL 1 0.040s 400 5.629 0.000s 0.000s 0.064s 15.617 [100 0 0]% SR 1 0.050s 400 5.628 0.000s 0.000s 0.065s 15.314 [100 0 0]% |
71.168
секунды, все очень похоже. Но посмотрите на Work:
list tree 0.175s 0.178s 0.127s 0.064s 0.064s 0.065s |
Время обработки сообщения первыми и последними серверами практически не отличается. Но у S2
к нему добавилось S3
, а у SL
, конечно же, не добавилось.
Ну и нам давно интересно, чем же чудит рантайм Go. ОКай, обратите внимание, что Slp серверов SL
и SR
было задано как 0.040
и 0.050
соответственно. Но время работы Work у них идентично: 0.064
и 0.065
. Так быть не должно!
Наш следующий шаг? Да тут без вариантов:
$ demoscale tree 400 C/8/0 S/2/30 SL/1/40 SR/1/50 tree{8,2,1,1} 400 38.780s 10.315 C 8 0.000s ->S 2 0.030s 400 10.315 0.371s 0.192s 0.193s 10.355 [1 0 99]% SL 1 0.040s 400 10.345 0.000s 0.000s 0.064s 15.619 [100 0 0]% SR 1 0.050s 400 10.344 0.000s 0.001s 0.065s 15.268 [99 1 0]% |
Ого! Сразу стало 38.780
секунды, т.е. 54%
. Резкое облегчение!
Оно и понятно, если сравнить RPS(W) первых запусков:
list tree 5.698 5.621 7.849 15.617 15.643 15.314 |
5.698
сервера S1
-- мы сразу упремся в 7.849
.
S
ограничивается 15.314
, что в ДВА РАЗА быстрее!
Те же самые три сервера с полностью идентичными настройками... Но масштабирование конфигурации tree
сразу приносит на 37%
больше дохода!!! Просто так, на ровном месте.
Точнее, не верю, что вы могли это убедительно показать Шарику. Или Печкину. Короче, дево псам.
Итак, еще раз: выньте сервер из гмм... глубины!
Тащите поближе к фронту -- быстрее забегает. А если возможно, используйте параллельный вызов -- станет СОВСЕМ хорошо!
Гут. Вы пока думайте, а мы пойдем дальше:
$ demoscale tree 400 C/8/0 S/3/30 SL/1/40 SR/1/50 tree{8,3,1,1} 400 26.309s 15.204 C 8 0.000s ->S 3 0.030s 400 15.204 0.188s 0.128s 0.196s 15.309 [2 1 97]% SL 1 0.040s 400 15.271 0.000s 0.001s 0.064s 15.702 [99 1 0]% SR 1 0.050s 400 15.268 0.000s 0.003s 0.065s 15.343 [96 4 0]% |
26.309
секунды на всего пяти инстансах! Прекрасно, просто прекрасно.
К тому же отметим практически одинаковый RPS(W): 15.309
, 15.702
и 15.343
. Значит дальше их расширять надо всех сразу, а у нас только инстанс в запасе. Ну ладно, потратим:
$ demoscale tree 400 C/8/0 S/4/30 SL/1/40 SR/1/50 tree{8,4,1,1} 400 26.145s 15.299 C 8 0.000s ->S 4 0.030s 400 15.299 0.127s 0.128s 0.260s 15.363 [2 0 98]% SL 1 0.040s 400 15.370 0.000s 0.001s 0.064s 15.718 [99 1 0]% SR 1 0.050s 400 15.368 0.000s 0.067s 0.065s 15.370 [1 95 4]% |
О, желтенькая пошла!
Мы смогли перегрузить SR
, но вообще-то геморрой не стоит свеч: 26.145
секунды вместо 26.309
-- это менее одного процента. А вот 6
инстансов вместо 5
-- это плюс 20
процентов затрат!
Лучше бы Шарику взяли пива. Не пьет? А мы и не заставляем.
Четыре сервера, но один отдувается за двоих. Как это часто бывает в жизни.
Стартуем:
$ demoscale rhomb 400 C/8/0 S/1/30 SL/1/40 SR/1/45 SM/1/50 #CmdName NumMsg Time RPS rhomb{8,1,1,1,1} 400 121.242s 3.299 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 3.299 1.446s 0.596s 0.303s 3.299 [1 1 98]% SL 1 0.040s 400 3.304 0.000s 0.000s 0.128s 7.838 [100 0 0]% SR 1 0.045s 400 3.304 0.000s 0.000s 0.127s 7.845 [100 0 0]% SM 1 0.050s 800 6.604 0.000s 0.000s 0.064s 15.654 [100 0 0]% |
121.242
секунды не шутка! Ну так это ж на четверых.
И сразу отметим 800
сообщений у среднего сервера. Он же последний: SM
. И конечно же в два раза больше RPS: 6.604
.
Наконец-то вы видите, зачем вообще были эти колонки: да, там бывают другие значения! Не похожие на остальных.
RPS(W)? С ним тоже непросто: 15.654
было рассчитано на 800
сообщений, а не 400
. И если, как мы привыкли, вы хотите сравнить его с остальными -- смело делите на два! Получается 7.827
, что не так далеко от товарищей.
Гмм, все эти хитрые 6.604
, 15.654
... Неудобно же сравнивать! Почему б не нормировать всех по 400
? Мой строгий друг, имей терпенье! Не вдруг приходит объясненье...
А пока добросим инстанс куда следует:
$ demoscale rhomb 400 C/8/0 S/2/30 SL/1/40 SR/1/45 SM/1/50 rhomb{8,2,1,1,1} 400 82.042s 4.876 C 8 0.000s ->S 2 0.030s 400 4.876 0.773s 0.402s 0.409s 4.890 [2 0 98]% SL 1 0.040s 400 4.886 0.000s 0.022s 0.194s 5.157 [89 11 0]% SR 1 0.045s 400 4.885 0.000s 0.005s 0.138s 7.243 [97 3 0]% SM 1 0.050s 800 9.763 0.000s 0.029s 0.069s 14.481 [71 29 0]% |
82.042
секунды, 68%
-- не худший вариант.
Добавим красному:
$ demoscale rhomb 400 C/8/0 S/3/30 SL/1/40 SR/1/45 SM/1/50 rhomb{8,3,1,1,1} 400 54.341s 7.361 C 8 0.000s ->S 3 0.030s 400 7.361 0.384s 0.262s 0.404s 7.428 [4 0 96]% SL 1 0.040s 400 7.384 0.000s 0.003s 0.135s 7.431 [98 2 0]% SR 1 0.045s 400 7.384 0.000s 0.069s 0.135s 7.428 [49 51 0]% SM 1 0.050s 800 14.750 0.000s 0.001s 0.067s 14.888 [98 2 0]% |
О! И красному зашло, и желтых стало меньше.
Но нормированный RPS(W) теперь практически одинаковый: 7.428
, 7.431
, 7.428
и 7.444
-- если сыпать, то всем!
А у нас только инстанс в запасе, и его не хотелось бы проморгать. Не жалко? Бросаю:
$ demoscale rhomb 400 C/8/0 S/4/30 SL/1/40 SR/1/45 SM/1/50 rhomb{8,4,1,1,1} 400 53.830s 7.431 C 8 0.000s ->S 4 0.030s 400 7.431 0.260s 0.265s 0.534s 7.489 [2 0 98]% SL 1 0.040s 400 7.455 0.000s 0.135s 0.134s 7.489 [1 98 1]% SR 1 0.045s 400 7.455 0.000s 0.069s 0.133s 7.494 [49 51 0]% SM 1 0.050s 800 14.890 0.000s 0.001s 0.067s 15.013 [99 1 0]% |
53.830
секунды вместо 54.341
, один процент выигрыша. Лучше Шарик нам снова проставится!
Группа пяти серверов, которую пользуют с двух сторон сразу! Нездоровая ситуация...
Но наиболее близкая к бизнесу, где ваши серверы одновременно эксплуатируются и другими, не совсем очевидными способами.
Задаем 800
сообщений на 16
инстансов клиента и любуемся:
$ demoscale wshape 800 C/16/0 SL/1/30 SR/1/35 SL2/1/40 SM/1/55 SR2/1/45 #CmdName NumMsg Time RPS wshape{16,1,1,1,1,1} 800 85.176s 9.392 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 16 0.000s ->SL 1 0.030s 400 4.708 0.800s 0.391s 0.208s 4.817 [7 3 90]% ->SR 1 0.035s 400 4.696 0.623s 0.348s 0.207s 4.830 [14 9 77]% SL2 1 0.040s 400 4.715 0.000s 0.000s 0.068s 14.669 [100 0 0]% SM 1 0.055s 800 9.406 0.000s 0.001s 0.073s 13.701 [99 1 0]% SR2 1 0.045s 400 4.703 0.000s 0.000s 0.069s 14.545 [100 0 0]% |
Это 85.176
секунды для начала. Просто запомним.
Что еще интересного?
Например, сервер SR
, правая точка входа, сразу же в желтой зоне! Ну, эсеры -- они такие.
Продолжим, и пусть в этот раз у нас будет 5
новых инстансов. Ну, чтобы тупо удвоиться и сравнить. Но сначала накинем по инстансу первым товарищам:
$ demoscale wshape 800 C/16/0 SL/2/30 SR/2/35 SL2/1/40 SM/1/55 SR2/1/45 wshape{16,2,2,1,1,1} 800 65.222s 12.266 C 16 0.000s ->SL 2 0.030s 400 6.153 0.601s 0.299s 0.313s 6.380 [7 2 91]% ->SR 2 0.035s 400 6.133 0.446s 0.284s 0.314s 6.376 [11 4 85]% SL2 1 0.040s 400 6.165 0.000s 0.000s 0.066s 15.203 [100 0 0]% SM 1 0.055s 800 12.289 0.000s 0.109s 0.079s 12.580 [6 55 39]% SR2 1 0.045s 400 6.145 0.000s 0.000s 0.066s 15.170 [100 0 0]% |
65.222
секунды -- во-первых, это красиво. А еще 77%
-- изящно, но многовато!
Так, а что это там пожелтело в самом центре скульптурной группы? Ага, это товарищ SM
с его 12.580
RPS(W). Делите надвое такие заявления: 6.290
-- это меньше всех остальных. Ща и ему поможем:
$ demoscale wshape 800 C/16/0 SL/2/30 SR/2/35 SL2/1/40 SM/2/55 SR2/1/45 wshape{16,2,2,1,2,1} 800 44.407s 18.015 C 16 0.000s ->SL 2 0.030s 400 9.008 0.123s 0.130s 0.207s 9.656 [39 5 56]% ->SR 2 0.035s 400 9.044 0.510s 0.189s 0.211s 9.490 [13 3 84]% SL2 1 0.040s 400 9.030 0.000s 0.000s 0.065s 15.409 [100 0 0]% SM 2 0.055s 800 18.033 0.000s 0.001s 0.079s 25.203 [98 2 0]% SR2 1 0.045s 400 9.070 0.000s 0.001s 0.065s 15.463 [99 1 0]% |
Ну вот, полегчало.
Но теперь напустили на линии фронта... Не бойтесь, ребята! У нас тут как раз завалялось два инстанса:
$ demoscale wshape 800 C/16/0 SL/3/30 SR/3/35 SL2/1/40 SM/2/55 SR2/1/45 wshape{16,3,3,1,2,1} 800 33.638s 23.783 C 16 0.000s ->SL 3 0.030s 400 11.967 0.221s 0.152s 0.239s 12.553 [9 1 90]% ->SR 3 0.035s 400 11.891 0.183s 0.135s 0.240s 12.523 [17 5 78]% SL2 1 0.040s 400 12.013 0.000s 0.002s 0.063s 15.883 [98 2 0]% SM 2 0.055s 800 23.870 0.000s 0.032s 0.080s 24.973 [44 35 21]% SR2 1 0.045s 400 11.936 0.000s 0.001s 0.063s 15.769 [99 1 0]% |
33.638
секунды -- непревзойденный результат! Ну, тупо не будет лучше:
$ demoscale wshape 800 C/16/0 SL/2/30 SR/2/35 SL2/2/40 SM/2/55 SR2/2/45 wshape{16,2,2,2,2,2} 800 44.166s 18.114 C 16 0.000s ->SL 2 0.030s 400 9.057 0.216s 0.160s 0.205s 9.736 [25 5 70]% ->SR 2 0.035s 400 9.098 0.491s 0.194s 0.208s 9.612 [11 2 87]% SL2 2 0.040s 400 9.083 0.000s 0.000s 0.065s 30.662 [100 0 0]% SM 2 0.055s 800 18.131 0.000s 0.002s 0.077s 26.002 [97 3 0]% SR2 2 0.045s 400 9.124 0.000s 0.000s 0.066s 30.379 [100 0 0]% |
Как можно видеть, это практически wshape{16,2,2,1,2,1}
, но с двумя лишними инстансами. Вы правы, они лишние, т.к. SL2
и SR2
прекрасно справлялись с нагрузкой.
ОКай, все хорошо и ясно, но почему же мы все-таки не нормируем RPS под одинаковое количество сообщений? А потому, что, вообще говоря, наши серверы может дергать и кто-то другой! Да еще где-нибудь в середине... Тем самым критически важно увидеть первичные данные.
У нас с самого начала была какая-то тактика, и мы ее придерживались.
Первый пункт тактики -- понимание Модели Конвейера:
1
инстанс сервера имеет Work 0.066s
, то его RPS(W) равен 15.152
(=1/0.066
). А 2
инстанса покажут 30.303
(=2/0.066
).
20%
, не более (вместо двукратного роста). А три инстанса такого сервера, по факту, хуже одного!
Та же фраза справедлива и для серверов:
Отличная идея! Просто прекрасная, с технической точки зрения.
Вот только средние менеджеры Больших Организаций ни в коем случае не заинтересованы в уменьшении своих расходов: меньше бюджет отдела, меньше людей в команде -- это потеря Власти! На это никто не пойдет.
demoscale -- это демонстрационная программа для изучения горизонтального масштабирования. Она написана на Go и легко адаптируется под ваши нужды.
Подробное описание и примеры использования уже приводились выше, а здесь будет краткая справка.
При вызове без параметров (или с неправильными параметрами) она выдает подсказку:
$ demoscale Usage: demoscale one 8 C/4/0 S/1/50 demoscale list 16 C/8/0 S1/1/30 S2/1/40 S3/1/50 demoscale tree 16 C/8/0 S/1/30 SL/1/40 SR/1/50 demoscale rhomb 16 C/8/0 S/1/30 SL/1/40 SR/1/45 SM/1/50 demoscale wshape 32 C/16/0 SL/1/30 SR/1/35 SL2/1/40 SM/1/55 SR2/1/45 demoscale one all demoscale list all demoscale tree all demoscale rhomb all demoscale wshape all demoscale other |
Таким образом, у нас есть два способа вызова каждой конфигурации:
demoscale Cmd NumMsg ClnArg SrvArg [SrvArg2 ...]
demoscale Cmd all
Cmd
-- имя встроенной конфигурации серверов: one
, list
, tree
, rhomb
или wshape
.
NumMsg
-- общее количество сообщений. Каждый инстанс клиента отправит свою часть.
ClnArg
-- параметры клиента.
SrvArg
-- параметры сервера.
ClnArg
и SrvArg
задаются одним и тем же выражением Name/NumInst/Slp
(например, S/1/50
), где:
Name
-- имя сервера (S
).
NumInst
-- количество инстансов (1
).
Slp
-- время задержки в миллисекундах (50
).
В любом случае, результат будет выглядеть следующим образом:
#CmdName NumMsg Time RPS wshape{16,1,1,1,1,1} 32 3.296s 9.709 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 16 0.000s ->SL 1 0.030s 16 4.854 0.481s 0.370s 0.206s 4.854 [7 6 87]% ->SR 1 0.035s 16 4.886 0.475s 0.340s 0.203s 4.918 [14 7 79]% SL2 1 0.040s 16 5.116 0.000s 0.000s 0.063s 15.760 [100 0 0]% SM 1 0.055s 32 9.894 0.000s 0.003s 0.075s 13.406 [97 3 0]% SR2 1 0.045s 16 5.089 0.000s 0.000s 0.069s 14.510 [100 0 0]% |
Где:
CmdName
-- имя конфигурации с набором инстансов.
NumMsg
-- количество сообщений.
Time
-- общее время работы клиентов.
RPS
-- реальный RPS (requests per second, пропускная способность).
Name
-- имя клиента или сервера.
NumInst
-- количество инстансов.
Slp
-- время задержки.
Wait1
-- время ожидания сообщения до очереди (поле MsgStats.Wait1
).
Wait2
-- время ожидания сообщения в очереди (поле MsgStats.Wait2
).
Work
-- время обработки сообщения (поле MsgStats.Work
).
RPS(W)
-- максимально возможный RPS сервера, рассчитанный по Work и NumInst.
[E NE F]
-- проценты загруженности очереди: Empty, NotEmpty, Full.
Но обратите внимание: рандомизация задержки ответа плюс непредсказуемость рантайма Go могут заметно повлиять на результат! Если видите "что-то не то" -- повторите еще пару раз. Так скажем, 5%
туды-сюды можно смело игнорировать.
Всего один сервер.
$ demoscale one all #CmdName NumMsg Time RPS one{1,1} 200 13.177s 15.178 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 1 0.000s ->S 1 0.050s 200 15.178 0.000s 0.000s 0.066s 15.186 [100 0 0]% one{1,2} 200 13.152s 15.207 C 1 0.000s ->S 2 0.050s 200 15.207 0.000s 0.000s 0.066s 30.420 [100 0 0]% one{2,1} 200 13.202s 15.149 C 2 0.000s ->S 1 0.050s 200 15.149 0.000s 0.066s 0.066s 15.152 [1 99 0]% one{2,2} 200 6.917s 28.913 C 2 0.000s ->S 2 0.050s 200 28.913 0.000s 0.000s 0.069s 29.013 [100 0 0]% #46.4488344s |
$ demoscale++ one all #CmdName NumMsg Time RPS one{1,1} 200 12.795s 15.631 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 1 0.000s ->S 1 0.050s 200 15.632 0.000s 0.000s 0.064s 15.662 [100 0 0]% one{1,2} 200 12.657s 15.802 C 1 0.000s ->S 2 0.050s 200 15.803 0.000s 0.000s 0.063s 31.679 [100 0 0]% one{2,1} 200 12.629s 15.836 C 2 0.000s ->S 1 0.050s 200 15.837 0.000s 0.063s 0.063s 15.843 [1 99 0]% one{2,2} 200 6.339s 31.549 C 2 0.000s ->S 2 0.050s 200 31.554 0.000s 0.000s 0.063s 31.613 [100 0 0]% #44.423s |
Три сервера друг за другом.
$ demoscale list all #CmdName NumMsg Time RPS list{8,1,1,1} 400 71.251s 5.614 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S1 1 0.030s 400 5.614 0.852s 0.354s 0.178s 5.614 [0 1 99]% S2 1 0.040s 400 5.618 0.000s 0.000s 0.130s 7.707 [100 0 0]% S3 1 0.050s 400 5.622 0.000s 0.000s 0.065s 15.299 [100 0 0]% list{8,2,1,1} 400 53.420s 7.488 C 8 0.000s ->S1 2 0.030s 400 7.488 0.515s 0.265s 0.267s 7.496 [0 1 99]% S2 1 0.040s 400 7.494 0.000s 0.070s 0.133s 7.495 [47 53 0]% S3 1 0.050s 400 7.503 0.000s 0.000s 0.069s 14.489 [100 0 0]% list{8,2,2,1} 400 36.644s 10.916 C 8 0.000s ->S1 2 0.030s 400 10.916 0.347s 0.178s 0.182s 11.011 [2 1 97]% S2 2 0.040s 400 10.930 0.000s 0.000s 0.132s 15.100 [100 0 0]% S3 1 0.050s 400 10.949 0.000s 0.000s 0.069s 14.404 [100 0 0]% list{8,2,2,2} 400 35.686s 11.209 C 8 0.000s ->S1 2 0.030s 400 11.209 0.335s 0.173s 0.178s 11.224 [2 2 96]% S2 2 0.040s 400 11.224 0.000s 0.000s 0.129s 15.453 [100 0 0]% S3 2 0.050s 400 11.244 0.000s 0.000s 0.065s 30.578 [100 0 0]% list{8,3,1,1} 400 53.520s 7.474 C 8 0.000s ->S1 3 0.030s 400 7.474 0.394s 0.265s 0.401s 7.491 [1 0 99]% S2 1 0.040s 400 7.481 0.000s 0.203s 0.134s 7.481 [0 48 52]% S3 1 0.050s 400 7.489 0.000s 0.000s 0.069s 14.403 [100 0 0]% list{8,3,2,1} 400 26.347s 15.182 C 8 0.000s ->S1 3 0.030s 400 15.182 0.192s 0.129s 0.197s 15.248 [1 1 98]% S2 2 0.040s 400 15.210 0.000s 0.002s 0.131s 15.262 [97 3 0]% S3 1 0.050s 400 15.248 0.000s 0.002s 0.065s 15.277 [98 2 0]% #4m36.8695941s |
$ demoscale++ list all #CmdName NumMsg Time RPS list{8,1,1,1} 400 67.612s 5.916 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S1 1 0.030s 400 5.916 0.799s 0.332s 0.169s 5.917 [1 1 98]% S2 1 0.040s 400 5.919 0.000s 0.000s 0.121s 8.233 [100 0 0]% S3 1 0.050s 400 5.925 0.000s 0.000s 0.063s 15.853 [100 0 0]% list{8,2,1,1} 400 48.663s 8.220 C 8 0.000s ->S1 2 0.030s 400 8.220 0.459s 0.241s 0.243s 8.232 [0 1 99]% S2 1 0.040s 400 8.227 0.000s 0.074s 0.122s 8.229 [39 61 0]% S3 1 0.050s 400 8.238 0.000s 0.000s 0.063s 15.861 [100 0 0]% list{8,2,2,1} 400 33.809s 11.831 C 8 0.000s ->S1 2 0.030s 400 11.832 0.316s 0.165s 0.169s 11.858 [1 2 97]% S2 2 0.040s 400 11.854 0.000s 0.000s 0.121s 16.496 [100 0 0]% S3 1 0.050s 400 11.878 0.000s 0.001s 0.063s 15.874 [99 1 0]% list{8,2,2,2} 400 33.928s 11.790 C 8 0.000s ->S1 2 0.030s 400 11.790 0.312s 0.166s 0.169s 11.854 [2 1 97]% S2 2 0.040s 400 11.806 0.000s 0.000s 0.121s 16.500 [100 0 0]% S3 2 0.050s 400 11.829 0.000s 0.000s 0.063s 31.740 [100 0 0]% list{8,3,1,1} 400 48.700s 8.214 C 8 0.000s ->S1 3 0.030s 400 8.214 0.341s 0.237s 0.361s 8.315 [3 0 97]% S2 1 0.040s 400 8.221 0.000s 0.192s 0.121s 8.247 [2 38 60]% S3 1 0.050s 400 8.232 0.000s 0.000s 0.063s 15.873 [100 0 0]% list{8,3,2,1} 400 25.542s 15.660 C 8 0.000s ->S1 3 0.030s 400 15.661 0.173s 0.123s 0.190s 15.770 [2 3 95]% S2 2 0.040s 400 15.688 0.000s 0.016s 0.127s 15.769 [75 25 0]% S3 1 0.050s 400 15.727 0.000s 0.006s 0.063s 15.830 [91 9 0]% #258.265s |
Три сервера деревом.
$ demoscale tree all #CmdName NumMsg Time RPS tree{8,1,1,1} 400 70.995s 5.634 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 5.634 0.845s 0.352s 0.177s 5.634 [0 1 99]% SL 1 0.040s 400 5.644 0.000s 0.000s 0.064s 15.690 [100 0 0]% SR 1 0.050s 400 5.643 0.000s 0.000s 0.065s 15.318 [100 0 0]% tree{8,2,1,1} 400 38.908s 10.281 C 8 0.000s ->S 2 0.030s 400 10.281 0.367s 0.191s 0.194s 10.335 [1 1 98]% SL 1 0.040s 400 10.310 0.000s 0.000s 0.064s 15.561 [100 0 0]% SR 1 0.050s 400 10.311 0.000s 0.001s 0.066s 15.183 [99 1 0]% tree{8,2,1,2} 400 38.643s 10.351 C 8 0.000s ->S 2 0.030s 400 10.351 0.374s 0.191s 0.192s 10.391 [1 0 99]% SL 1 0.040s 400 10.381 0.000s 0.000s 0.064s 15.541 [100 0 0]% SR 2 0.050s 400 10.381 0.000s 0.000s 0.065s 30.566 [100 0 0]% tree{8,2,2,1} 400 38.711s 10.333 C 8 0.000s ->S 2 0.030s 400 10.333 0.376s 0.192s 0.193s 10.341 [0 1 99]% SL 2 0.040s 400 10.364 0.000s 0.000s 0.064s 31.021 [100 0 0]% SR 1 0.050s 400 10.363 0.000s 0.001s 0.065s 15.329 [99 1 0]% tree{8,2,2,2} 400 38.083s 10.503 C 8 0.000s ->S 2 0.030s 400 10.503 0.365s 0.188s 0.190s 10.520 [1 0 99]% SL 2 0.040s 400 10.535 0.000s 0.000s 0.064s 31.287 [100 0 0]% SR 2 0.050s 400 10.534 0.000s 0.000s 0.065s 30.543 [100 0 0]% tree{8,3,1,1} 400 26.460s 15.117 C 8 0.000s ->S 3 0.030s 400 15.117 0.187s 0.128s 0.197s 15.261 [3 1 96]% SL 1 0.040s 400 15.182 0.000s 0.001s 0.063s 15.849 [99 1 0]% SR 1 0.050s 400 15.182 0.000s 0.005s 0.065s 15.296 [93 7 0]% tree{8,3,1,2} 400 25.692s 15.569 C 8 0.000s ->S 3 0.030s 400 15.569 0.185s 0.126s 0.192s 15.605 [2 0 98]% SL 1 0.040s 400 15.640 0.000s 0.001s 0.064s 15.734 [99 1 0]% SR 2 0.050s 400 15.637 0.000s 0.000s 0.065s 30.628 [100 0 0]% tree{8,3,2,1} 400 26.004s 15.382 C 8 0.000s ->S 3 0.030s 400 15.382 0.191s 0.129s 0.195s 15.418 [1 0 99]% SL 2 0.040s 400 15.452 0.000s 0.000s 0.064s 31.354 [100 0 0]% SR 1 0.050s 400 15.450 0.000s 0.002s 0.065s 15.461 [97 3 0]% tree{8,4,1,1} 400 26.170s 15.285 C 8 0.000s ->S 4 0.030s 400 15.285 0.126s 0.128s 0.259s 15.419 [2 1 97]% SL 1 0.040s 400 15.350 0.000s 0.005s 0.063s 15.810 [93 6 1]% SR 1 0.050s 400 15.348 0.000s 0.063s 0.065s 15.415 [8 88 4]% #5m29.6673422s |
$ demoscale++ tree all #CmdName NumMsg Time RPS tree{8,1,1,1} 400 67.537s 5.923 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 5.923 0.787s 0.335s 0.169s 5.924 [0 1 99]% SL 1 0.040s 400 5.932 0.000s 0.000s 0.058s 17.242 [100 0 0]% SR 1 0.050s 400 5.933 0.000s 0.000s 0.063s 15.888 [100 0 0]% tree{8,2,1,1} 400 34.220s 11.689 C 8 0.000s ->S 2 0.030s 400 11.689 0.303s 0.162s 0.170s 11.792 [5 0 95]% SL 1 0.040s 400 11.731 0.000s 0.000s 0.058s 17.256 [100 0 0]% SR 1 0.050s 400 11.726 0.000s 0.001s 0.063s 15.913 [99 1 0]% tree{8,2,1,2} 400 34.452s 11.610 C 8 0.000s ->S 2 0.030s 400 11.611 0.311s 0.165s 0.170s 11.772 [3 2 95]% SL 1 0.040s 400 11.646 0.000s 0.001s 0.058s 17.224 [98 2 0]% SR 2 0.050s 400 11.646 0.000s 0.000s 0.063s 31.799 [100 0 0]% tree{8,2,2,1} 400 34.128s 11.721 C 8 0.000s ->S 2 0.030s 400 11.721 0.310s 0.165s 0.170s 11.769 [1 4 95]% SL 2 0.040s 400 11.758 0.000s 0.000s 0.058s 34.517 [100 0 0]% SR 1 0.050s 400 11.758 0.000s 0.001s 0.063s 15.880 [98 2 0]% tree{8,2,2,2} 400 33.621s 11.897 C 8 0.000s ->S 2 0.030s 400 11.897 0.303s 0.166s 0.168s 11.901 [1 1 98]% SL 2 0.040s 400 11.935 0.000s 0.000s 0.057s 34.845 [100 0 0]% SR 2 0.050s 400 11.935 0.000s 0.000s 0.064s 31.484 [100 0 0]% tree{8,3,1,1} 400 25.662s 15.587 C 8 0.000s ->S 3 0.030s 400 15.588 0.178s 0.122s 0.189s 15.835 [4 1 95]% SL 1 0.040s 400 15.653 0.000s 0.001s 0.058s 17.187 [99 1 0]% SR 1 0.050s 400 15.653 0.000s 0.020s 0.063s 15.854 [69 31 0]% tree{8,3,1,2} 400 23.716s 16.866 C 8 0.000s ->S 3 0.030s 400 16.867 0.170s 0.116s 0.177s 16.911 [2 0 98]% SL 1 0.040s 400 16.943 0.000s 0.009s 0.058s 17.264 [85 15 0]% SR 2 0.050s 400 16.943 0.000s 0.000s 0.063s 31.802 [100 0 0]% tree{8,3,2,1} 400 25.469s 15.705 C 8 0.000s ->S 3 0.030s 400 15.706 0.180s 0.123s 0.189s 15.852 [3 2 95]% SL 2 0.040s 400 15.773 0.000s 0.000s 0.058s 34.637 [100 0 0]% SR 1 0.050s 400 15.773 0.000s 0.021s 0.063s 15.878 [67 33 0]% tree{8,4,1,1} 400 25.547s 15.658 C 8 0.000s ->S 4 0.030s 400 15.658 0.121s 0.122s 0.252s 15.881 [4 1 95]% SL 1 0.040s 400 15.724 0.000s 0.003s 0.058s 17.149 [96 3 1]% SR 1 0.050s 400 15.725 0.000s 0.080s 0.063s 15.859 [5 65 30]% #304.370s |
Четыре сервера ромбом.
$ demoscale rhomb all #CmdName NumMsg Time RPS rhomb{8,1,1,1,1} 400 123.320s 3.244 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 3.244 1.461s 0.610s 0.308s 3.244 [1 0 99]% SL 1 0.040s 400 3.248 0.000s 0.000s 0.130s 7.715 [100 0 0]% SR 1 0.045s 400 3.248 0.000s 0.000s 0.130s 7.685 [100 0 0]% SM 1 0.050s 800 6.493 0.000s 0.000s 0.065s 15.293 [100 0 0]% rhomb{8,2,1,1,1} 400 82.261s 4.863 C 8 0.000s ->S 2 0.030s 400 4.863 0.783s 0.403s 0.410s 4.878 [2 0 98]% SL 1 0.040s 400 4.873 0.000s 0.021s 0.197s 5.083 [90 10 0]% SR 1 0.045s 400 4.873 0.000s 0.004s 0.138s 7.243 [98 2 0]% SM 1 0.050s 800 9.739 0.000s 0.031s 0.070s 14.365 [70 30 0]% rhomb{8,2,1,1,2} 400 66.999s 5.970 C 8 0.000s ->S 2 0.030s 400 5.970 0.638s 0.330s 0.333s 6.003 [1 1 98]% SL 1 0.040s 400 5.986 0.000s 0.010s 0.135s 7.431 [94 6 0]% SR 1 0.045s 400 5.986 0.000s 0.000s 0.132s 7.579 [100 0 0]% SM 2 0.050s 800 11.961 0.000s 0.000s 0.067s 29.805 [100 0 0]% rhomb{8,2,1,2,1} 400 81.470s 4.910 C 8 0.000s ->S 2 0.030s 400 4.910 0.765s 0.401s 0.407s 4.915 [1 1 98]% SL 1 0.040s 400 4.921 0.000s 0.022s 0.198s 5.063 [89 11 0]% SR 2 0.045s 400 4.920 0.000s 0.000s 0.137s 14.572 [100 0 0]% SM 1 0.050s 800 9.833 0.000s 0.031s 0.069s 14.433 [70 30 0]% rhomb{8,2,2,1,1} 400 76.962s 5.197 C 8 0.000s ->S 2 0.030s 400 5.197 0.739s 0.380s 0.384s 5.204 [1 0 99]% SL 2 0.040s 400 5.209 0.000s 0.000s 0.137s 14.632 [100 0 0]% SR 1 0.045s 400 5.209 0.000s 0.035s 0.157s 6.375 [82 18 0]% SM 1 0.050s 800 10.410 0.000s 0.012s 0.069s 14.497 [88 12 0]% rhomb{8,3,1,1,1} 400 55.064s 7.264 C 8 0.000s ->S 3 0.030s 400 7.264 0.402s 0.273s 0.412s 7.282 [1 0 99]% SL 1 0.040s 400 7.297 0.000s 0.011s 0.137s 7.298 [93 6 1]% SR 1 0.045s 400 7.286 0.000s 0.067s 0.134s 7.448 [51 49 0]% SM 1 0.050s 800 14.557 0.000s 0.003s 0.067s 14.884 [96 4 0]% #8m6.0766549s |
$ demoscale++ rhomb all #CmdName NumMsg Time RPS rhomb{8,1,1,1,1} 400 118.037s 3.389 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 1 0.030s 400 3.389 1.330s 0.572s 0.295s 3.389 [2 2 96]% SL 1 0.040s 400 3.393 0.000s 0.000s 0.121s 8.240 [100 0 0]% SR 1 0.045s 400 3.393 0.000s 0.000s 0.126s 7.934 [100 0 0]% SM 1 0.050s 800 6.783 0.000s 0.000s 0.063s 15.897 [100 0 0]% rhomb{8,2,1,1,1} 400 74.684s 5.356 C 8 0.000s ->S 2 0.030s 400 5.356 0.667s 0.366s 0.373s 5.363 [0 4 96]% SL 1 0.040s 400 5.368 0.000s 0.008s 0.149s 6.694 [96 4 0]% SR 1 0.045s 400 5.368 0.000s 0.022s 0.146s 6.833 [88 12 0]% SM 1 0.050s 800 10.727 0.000s 0.024s 0.063s 15.818 [74 26 0]% rhomb{8,2,1,1,2} 400 59.263s 6.750 C 8 0.000s ->S 2 0.030s 400 6.750 0.554s 0.290s 0.296s 6.760 [2 0 98]% SL 1 0.040s 400 6.769 0.000s 0.000s 0.121s 8.246 [100 0 0]% SR 1 0.045s 400 6.769 0.000s 0.001s 0.126s 7.930 [99 1 0]% SM 2 0.050s 800 13.523 0.000s 0.000s 0.063s 31.707 [100 0 0]% rhomb{8,2,1,2,1} 400 72.736s 5.499 C 8 0.000s ->S 2 0.030s 400 5.499 0.650s 0.356s 0.362s 5.517 [2 0 98]% SL 1 0.040s 400 5.512 0.000s 0.023s 0.145s 6.916 [87 13 0]% SR 2 0.045s 400 5.512 0.000s 0.000s 0.147s 13.568 [100 0 0]% SM 1 0.050s 800 11.014 0.000s 0.022s 0.063s 15.855 [75 25 0]% rhomb{8,2,2,1,1} 400 72.236s 5.537 C 8 0.000s ->S 2 0.030s 400 5.537 0.641s 0.352s 0.358s 5.579 [2 1 97]% SL 2 0.040s 400 5.550 0.000s 0.000s 0.139s 14.423 [100 0 0]% SR 1 0.045s 400 5.550 0.000s 0.027s 0.145s 6.904 [85 15 0]% SM 1 0.050s 800 11.091 0.000s 0.019s 0.063s 15.884 [79 21 0]% rhomb{8,3,1,1,1} 400 51.197s 7.813 C 8 0.000s ->S 3 0.030s 400 7.813 0.364s 0.253s 0.383s 7.833 [1 1 98]% SL 1 0.040s 400 7.850 0.000s 0.015s 0.127s 7.858 [89 11 0]% SR 1 0.045s 400 7.840 0.000s 0.067s 0.126s 7.908 [48 52 0]% SM 1 0.050s 800 15.661 0.000s 0.003s 0.063s 15.870 [95 5 0]% #448.167s |
Пять серверов с двумя точками входа.
$ demoscale wshape all #CmdName NumMsg Time RPS wshape{16,1,1,1,1,1} 800 83.120s 9.625 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 16 0.000s ->SL 1 0.030s 400 4.812 0.835s 0.403s 0.207s 4.841 [3 1 96]% ->SR 1 0.035s 400 4.824 0.638s 0.392s 0.207s 4.842 [3 5 92]% SL2 1 0.040s 400 4.820 0.000s 0.000s 0.067s 14.888 [100 0 0]% SM 1 0.055s 800 9.630 0.000s 0.001s 0.075s 13.402 [99 1 0]% SR2 1 0.045s 400 4.832 0.000s 0.000s 0.069s 14.573 [100 0 0]% wshape{16,1,2,1,1,1} 800 85.885s 9.315 C 16 0.000s ->SL 1 0.030s 400 4.657 1.786s 0.406s 0.212s 4.715 [5 1 94]% ->SR 2 0.035s 400 4.668 0.006s 0.006s 0.208s 9.608 [98 1 1]% SL2 1 0.040s 400 4.665 0.000s 0.000s 0.064s 15.562 [100 0 0]% SM 1 0.055s 800 9.320 0.000s 0.007s 0.078s 12.895 [93 7 0]% SR2 1 0.045s 400 4.675 0.000s 0.000s 0.065s 15.370 [100 0 0]% wshape{16,2,1,1,1,1} 800 84.593s 9.457 C 16 0.000s ->SL 2 0.030s 400 4.740 0.006s 0.007s 0.213s 9.406 [98 1 1]% ->SR 1 0.035s 400 4.729 1.755s 0.399s 0.209s 4.787 [4 3 93]% SL2 1 0.040s 400 4.746 0.000s 0.000s 0.064s 15.647 [100 0 0]% SM 1 0.055s 800 9.472 0.000s 0.008s 0.078s 12.900 [93 7 0]% SR2 1 0.045s 400 4.736 0.000s 0.000s 0.065s 15.405 [100 0 0]% wshape{16,2,2,1,1,1} 800 64.551s 12.393 C 16 0.000s ->SL 2 0.030s 400 6.197 0.569s 0.307s 0.315s 6.349 [5 0 95]% ->SR 2 0.035s 400 6.216 0.447s 0.302s 0.315s 6.356 [5 3 92]% SL2 1 0.040s 400 6.210 0.000s 0.000s 0.066s 15.214 [100 0 0]% SM 1 0.055s 800 12.402 0.000s 0.111s 0.079s 12.615 [3 57 40]% SR2 1 0.045s 400 6.229 0.000s 0.000s 0.066s 15.231 [100 0 0]% wshape{16,2,2,1,1,2} 800 63.504s 12.598 C 16 0.000s ->SL 2 0.030s 400 6.299 0.615s 0.298s 0.310s 6.450 [6 0 94]% ->SR 2 0.035s 400 6.301 0.392s 0.281s 0.309s 6.468 [9 6 85]% SL2 1 0.040s 400 6.316 0.000s 0.000s 0.066s 15.181 [100 0 0]% SM 1 0.055s 800 12.610 0.000s 0.105s 0.078s 12.760 [5 58 37]% SR2 2 0.045s 400 6.316 0.000s 0.000s 0.066s 30.203 [100 0 0]% wshape{16,2,2,1,2,1} 800 44.585s 17.943 C 16 0.000s ->SL 2 0.030s 400 8.972 0.067s 0.119s 0.206s 9.722 [40 14 46]% ->SR 2 0.035s 400 9.008 0.592s 0.195s 0.209s 9.564 [12 1 87]% SL2 1 0.040s 400 8.995 0.000s 0.000s 0.065s 15.478 [100 0 0]% SM 2 0.055s 800 17.963 0.000s 0.001s 0.078s 25.529 [98 2 0]% SR2 1 0.045s 400 9.038 0.000s 0.001s 0.065s 15.478 [99 1 0]% wshape{16,2,2,1,2,2} 800 44.090s 18.145 C 16 0.000s ->SL 2 0.030s 400 9.072 0.204s 0.161s 0.206s 9.710 [25 4 71]% ->SR 2 0.035s 400 9.115 0.453s 0.195s 0.208s 9.601 [11 1 88]% SL2 1 0.040s 400 9.102 0.000s 0.001s 0.064s 15.538 [99 1 0]% SM 2 0.055s 800 18.165 0.000s 0.001s 0.079s 25.336 [98 2 0]% SR2 2 0.045s 400 9.145 0.000s 0.000s 0.065s 30.968 [100 0 0]% wshape{16,2,2,2,1,1} 800 63.574s 12.584 C 16 0.000s ->SL 2 0.030s 400 6.309 0.586s 0.303s 0.313s 6.388 [4 1 95]% ->SR 2 0.035s 400 6.292 0.459s 0.289s 0.313s 6.390 [8 2 90]% SL2 2 0.040s 400 6.321 0.000s 0.000s 0.066s 30.478 [100 0 0]% SM 1 0.055s 800 12.609 0.000s 0.109s 0.079s 12.678 [3 57 40]% SR2 1 0.045s 400 6.304 0.000s 0.000s 0.066s 15.145 [100 0 0]% wshape{16,2,2,2,1,2} 800 63.864s 12.527 C 16 0.000s ->SL 2 0.030s 400 6.283 0.542s 0.302s 0.313s 6.385 [4 2 94]% ->SR 2 0.035s 400 6.263 0.470s 0.286s 0.313s 6.394 [8 5 87]% SL2 2 0.040s 400 6.296 0.000s 0.000s 0.066s 30.490 [100 0 0]% SM 1 0.055s 800 12.552 0.000s 0.108s 0.079s 12.664 [3 58 39]% SR2 2 0.045s 400 6.278 0.000s 0.000s 0.066s 30.320 [100 0 0]% wshape{16,2,2,2,2,1} 800 44.170s 18.112 C 16 0.000s ->SL 2 0.030s 400 9.056 0.098s 0.123s 0.206s 9.723 [38 12 50]% ->SR 2 0.035s 400 9.097 0.543s 0.185s 0.210s 9.518 [14 4 82]% SL2 2 0.040s 400 9.083 0.000s 0.000s 0.065s 30.906 [100 0 0]% SM 2 0.055s 800 18.131 0.000s 0.002s 0.078s 25.585 [97 3 0]% SR2 1 0.045s 400 9.124 0.000s 0.001s 0.065s 15.380 [99 1 0]% wshape{16,2,2,2,2,2} 800 42.130s 18.989 C 16 0.000s ->SL 2 0.030s 400 9.540 0.117s 0.142s 0.205s 9.760 [30 5 65]% ->SR 2 0.035s 400 9.494 0.600s 0.194s 0.208s 9.622 [7 2 91]% SL2 2 0.040s 400 9.571 0.000s 0.000s 0.066s 30.513 [100 0 0]% SM 2 0.055s 800 19.048 0.000s 0.002s 0.075s 26.634 [96 4 0]% SR2 2 0.045s 400 9.527 0.000s 0.000s 0.067s 29.965 [100 0 0]% wshape{16,2,3,1,2,1} 800 44.549s 17.958 C 16 0.000s ->SL 2 0.030s 400 8.979 0.763s 0.192s 0.206s 9.728 [13 2 85]% ->SR 3 0.035s 400 9.017 0.005s 0.006s 0.208s 14.445 [97 0 3]% SL2 1 0.040s 400 9.006 0.000s 0.000s 0.066s 15.198 [100 0 0]% SM 2 0.055s 800 17.977 0.000s 0.002s 0.076s 26.148 [97 3 0]% SR2 1 0.045s 400 9.048 0.000s 0.001s 0.066s 15.256 [99 1 0]% wshape{16,3,2,1,2,1} 800 42.276s 18.923 C 16 0.000s ->SL 3 0.030s 400 9.462 0.005s 0.006s 0.208s 14.409 [97 1 2]% ->SR 2 0.035s 400 9.502 0.836s 0.203s 0.209s 9.555 [3 3 94]% SL2 1 0.040s 400 9.487 0.000s 0.001s 0.066s 15.254 [99 1 0]% SM 2 0.055s 800 18.945 0.000s 0.004s 0.076s 26.297 [93 7 0]% SR2 1 0.045s 400 9.533 0.000s 0.001s 0.066s 15.247 [99 1 0]% wshape{16,3,3,1,2,1} 800 32.127s 24.901 C 16 0.000s ->SL 3 0.030s 400 12.530 0.277s 0.143s 0.235s 12.770 [9 3 88]% ->SR 3 0.035s 400 12.451 0.116s 0.151s 0.236s 12.712 [5 2 93]% SL2 1 0.040s 400 12.578 0.000s 0.004s 0.064s 15.617 [95 5 0]% SM 2 0.055s 800 25.000 0.000s 0.025s 0.078s 25.493 [48 40 12]% SR2 1 0.045s 400 12.500 0.000s 0.004s 0.064s 15.510 [95 5 0]% #13m23.0205967s |
$ demoscale++ wshape all #CmdName NumMsg Time RPS wshape{16,1,1,1,1,1} 800 70.953s 11.275 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 16 0.000s ->SL 1 0.030s 400 5.651 0.776s 0.338s 0.174s 5.736 [4 1 95]% ->SR 1 0.035s 400 5.638 0.768s 0.329s 0.174s 5.736 [5 5 90]% SL2 1 0.040s 400 5.659 0.000s 0.000s 0.058s 17.160 [100 0 0]% SM 1 0.055s 800 11.291 0.000s 0.003s 0.064s 15.743 [97 3 0]% SR2 1 0.045s 400 5.645 0.000s 0.000s 0.063s 15.826 [100 0 0]% wshape{16,1,2,1,1,1} 800 69.980s 11.432 C 16 0.000s ->SL 1 0.030s 400 5.716 1.692s 0.343s 0.174s 5.731 [2 0 98]% ->SR 2 0.035s 400 5.730 0.005s 0.005s 0.174s 11.480 [98 1 1]% SL2 1 0.040s 400 5.725 0.000s 0.000s 0.058s 17.232 [100 0 0]% SM 1 0.055s 800 11.439 0.000s 0.003s 0.063s 15.825 [97 3 0]% SR2 1 0.045s 400 5.739 0.000s 0.000s 0.063s 15.918 [100 0 0]% wshape{16,2,1,1,1,1} 800 69.905s 11.444 C 16 0.000s ->SL 2 0.030s 400 5.722 0.005s 0.006s 0.175s 11.440 [98 1 1]% ->SR 1 0.035s 400 5.736 1.651s 0.338s 0.174s 5.737 [3 1 96]% SL2 1 0.040s 400 5.731 0.000s 0.000s 0.058s 17.232 [100 0 0]% SM 1 0.055s 800 11.451 0.000s 0.003s 0.063s 15.786 [97 3 0]% SR2 1 0.045s 400 5.746 0.000s 0.000s 0.063s 15.821 [100 0 0]% wshape{16,2,2,1,1,1} 800 50.923s 15.710 C 16 0.000s ->SL 2 0.030s 400 7.882 0.521s 0.248s 0.252s 7.931 [2 1 97]% ->SR 2 0.035s 400 7.855 0.412s 0.242s 0.252s 7.942 [4 1 95]% SL2 1 0.040s 400 7.898 0.000s 0.000s 0.058s 17.164 [100 0 0]% SM 1 0.055s 800 15.743 0.000s 0.081s 0.063s 15.821 [2 70 28]% SR2 1 0.045s 400 7.872 0.000s 0.000s 0.063s 15.910 [100 0 0]% wshape{16,2,2,1,1,2} 800 51.029s 15.677 C 16 0.000s ->SL 2 0.030s 400 7.839 0.506s 0.243s 0.253s 7.920 [4 2 94]% ->SR 2 0.035s 400 7.865 0.402s 0.247s 0.252s 7.927 [3 1 96]% SL2 1 0.040s 400 7.855 0.000s 0.000s 0.058s 17.242 [100 0 0]% SM 1 0.055s 800 15.691 0.000s 0.081s 0.063s 15.809 [2 69 29]% SR2 2 0.045s 400 7.882 0.000s 0.000s 0.063s 31.757 [100 0 0]% wshape{16,2,2,1,2,1} 800 35.432s 22.579 C 16 0.000s ->SL 2 0.030s 400 11.289 0.069s 0.079s 0.169s 11.817 [52 7 41]% ->SR 2 0.035s 400 11.342 0.605s 0.165s 0.174s 11.520 [6 1 93]% SL2 1 0.040s 400 11.323 0.000s 0.000s 0.058s 17.283 [100 0 0]% SM 2 0.055s 800 22.607 0.000s 0.000s 0.063s 31.710 [99 1 0]% SR2 1 0.045s 400 11.376 0.000s 0.000s 0.063s 15.960 [100 0 0]% wshape{16,2,2,1,2,2} 800 35.146s 22.762 C 16 0.000s ->SL 2 0.030s 400 11.381 0.279s 0.167s 0.173s 11.546 [4 1 95]% ->SR 2 0.035s 400 11.437 0.355s 0.172s 0.174s 11.488 [2 0 98]% SL2 1 0.040s 400 11.416 0.000s 0.002s 0.058s 17.195 [97 3 0]% SM 2 0.055s 800 22.792 0.000s 0.001s 0.063s 31.642 [98 2 0]% SR2 2 0.045s 400 11.473 0.000s 0.000s 0.063s 31.702 [100 0 0]% wshape{16,2,2,2,1,1} 800 51.058s 15.668 C 16 0.000s ->SL 2 0.030s 400 7.861 0.507s 0.248s 0.253s 7.915 [2 2 96]% ->SR 2 0.035s 400 7.834 0.422s 0.247s 0.252s 7.930 [3 1 96]% SL2 2 0.040s 400 7.877 0.000s 0.000s 0.058s 34.555 [100 0 0]% SM 1 0.055s 800 15.701 0.000s 0.081s 0.063s 15.803 [2 69 29]% SR2 1 0.045s 400 7.851 0.000s 0.000s 0.063s 15.915 [100 0 0]% wshape{16,2,2,2,1,2} 800 50.796s 15.749 C 16 0.000s ->SL 2 0.030s 400 7.902 0.531s 0.250s 0.252s 7.926 [1 1 98]% ->SR 2 0.035s 400 7.875 0.397s 0.246s 0.252s 7.943 [2 2 96]% SL2 2 0.040s 400 7.928 0.000s 0.000s 0.057s 34.803 [100 0 0]% SM 1 0.055s 800 15.782 0.000s 0.081s 0.063s 15.818 [1 70 29]% SR2 2 0.045s 400 7.891 0.000s 0.000s 0.063s 31.826 [100 0 0]% wshape{16,2,2,2,2,1} 800 35.107s 22.788 C 16 0.000s ->SL 2 0.030s 400 11.451 0.088s 0.090s 0.170s 11.795 [45 8 47]% ->SR 2 0.035s 400 11.394 0.602s 0.170s 0.174s 11.520 [3 1 96]% SL2 2 0.040s 400 11.485 0.000s 0.000s 0.058s 34.738 [100 0 0]% SM 2 0.055s 800 22.858 0.000s 0.001s 0.063s 31.626 [98 2 0]% SR2 1 0.045s 400 11.429 0.000s 0.000s 0.063s 15.948 [100 0 0]% wshape{16,2,2,2,2,2} 800 35.258s 22.690 C 16 0.000s ->SL 2 0.030s 400 11.345 0.314s 0.164s 0.174s 11.520 [7 0 93]% ->SR 2 0.035s 400 11.401 0.318s 0.171s 0.174s 11.519 [3 1 96]% SL2 2 0.040s 400 11.379 0.000s 0.000s 0.058s 34.437 [100 0 0]% SM 2 0.055s 800 22.718 0.000s 0.002s 0.063s 31.633 [97 0 3]% SR2 2 0.045s 400 11.435 0.000s 0.000s 0.063s 31.826 [100 0 0]% wshape{16,2,3,1,2,1} 800 34.612s 23.114 C 16 0.000s ->SL 2 0.030s 400 11.557 0.688s 0.167s 0.171s 11.722 [3 1 96]% ->SR 3 0.035s 400 11.615 0.004s 0.006s 0.175s 17.099 [96 1 3]% SL2 1 0.040s 400 11.598 0.000s 0.000s 0.058s 17.198 [100 0 0]% SM 2 0.055s 800 23.153 0.000s 0.001s 0.063s 31.580 [98 2 0]% SR2 1 0.045s 400 11.656 0.000s 0.001s 0.063s 15.860 [98 2 0]% wshape{16,3,2,1,2,1} 800 35.735s 22.387 C 16 0.000s ->SL 3 0.030s 400 11.248 0.004s 0.005s 0.171s 17.592 [97 1 2]% ->SR 2 0.035s 400 11.194 0.734s 0.168s 0.174s 11.488 [6 0 94]% SL2 1 0.040s 400 11.281 0.000s 0.001s 0.058s 17.216 [99 1 0]% SM 2 0.055s 800 22.454 0.000s 0.001s 0.063s 31.642 [99 1 0]% SR2 1 0.045s 400 11.227 0.000s 0.000s 0.063s 15.887 [100 0 0]% wshape{16,3,3,1,2,1} 800 25.908s 30.879 C 16 0.000s ->SL 3 0.030s 400 15.554 0.164s 0.121s 0.190s 15.830 [6 1 93]% ->SR 3 0.035s 400 15.440 0.186s 0.124s 0.190s 15.803 [4 1 95]% SL2 1 0.040s 400 15.616 0.000s 0.002s 0.058s 17.206 [98 2 0]% SM 2 0.055s 800 31.025 0.000s 0.016s 0.063s 31.640 [51 48 1]% SR2 1 0.045s 400 15.503 0.000s 0.003s 0.063s 15.919 [95 5 0]% #651.876s |
А пока там орудует банда серверов из начала статьи:
И вот что у них получается:
$ demoscale other #CmdName NumMsg Time RPS other{8,2,2,2,2,2,2,2,1} 16 8.942s 1.789 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 2 0.030s 16 1.789 1.389s 0.972s 1.111s 1.800 [13 1 86]% SL 2 0.050s 16 1.912 0.000s 0.000s 0.533s 3.754 [100 0 0]% SR 2 0.055s 16 1.905 0.000s 0.000s 0.530s 3.775 [100 0 0]% SL1 2 0.070s 16 1.982 0.000s 0.000s 0.229s 8.717 [100 0 0]% SL2 2 0.075s 16 1.971 0.000s 0.000s 0.239s 8.357 [100 0 0]% SR1 2 0.080s 16 1.979 0.000s 0.000s 0.210s 9.516 [100 0 0]% SR2 2 0.085s 16 1.969 0.000s 0.000s 0.239s 8.369 [100 0 0]% DB 1 0.100s 64 7.329 0.000s 0.016s 0.117s 8.564 [89 11 0]% |
$ demoscale++ other #CmdName NumMsg Time RPS other{8,2,2,2,2,2,2,2,1} 16 8.871s 1.804 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 8 0.000s ->S 2 0.030s 16 1.804 1.378s 0.901s 1.101s 1.817 [13 12 75]% SL 2 0.050s 16 1.933 0.000s 0.000s 0.516s 3.873 [100 0 0]% SR 2 0.055s 16 1.925 0.000s 0.000s 0.537s 3.728 [100 0 0]% SL1 2 0.070s 16 2.009 0.000s 0.000s 0.208s 9.624 [100 0 0]% SL2 2 0.075s 16 1.997 0.000s 0.000s 0.246s 8.114 [100 0 0]% SR1 2 0.080s 16 2.005 0.000s 0.000s 0.229s 8.718 [100 0 0]% SR2 2 0.085s 16 1.993 0.000s 0.000s 0.244s 8.197 [100 0 0]% DB 1 0.100s 64 7.383 0.000s 0.019s 0.119s 8.375 [86 14 0]% |
Вы ничего не сделаете с плохой Архитектурой. Вы ничего не измените в Большой Организации. Ничего существенного.
А по мелочи, вы теперь знаете:
Там, где есть шанс сразу сделать все правильно (или полностью переписать), у вас появится возможность осмысленно расходовать ресурсы, что всем обеспечит заметный рост прибыли.
Как показала практика, в реальном Мире очень сильно запущены 4
случая из 5
. Это поле непаханое, но... в чужом Деле вам ничего не дадут изменить.
ОКай, допустим мы правильно видим реальные факты и можем оптимально масштабировать. Что дальше?
А дальше только Полная Автоматизация!
Но это Сказки братьев Брин.
Прежде всего, всем огромное спасибо за фидбек! Я получил неожиданно много вопросов и большинство дискуссий, так или иначе, упоминали C++. Самый частый вопрос: А что получится на C++?
На C++ получится demoscale++
. Это же очевидно!
Т.е. все то же самое, только быстрее. И предсказуемее... Скучно, товарищи! Если не пишете на C++. А если пишете?
Никогда не задумывались, как бы выглядела та же самая Go программа на C++? А я вдруг задумался и теперь знаю ответ.
Но все-таки вернемся к сути дела. На примере тяжелой конфигурации
$ demoscale wshape 800 C/16/0 SL/3/30 SR/3/35 SL2/1/40 SM/2/55 SR2/1/45 #CmdName NumMsg Time RPS wshape{16,3,3,1,2,1} 800 32.127s 24.901 #Name NumInst Slp NumMsg RPS Wait1 Wait2 Work RPS(W) [E NE F] C 16 0.000s ->SL 3 0.030s 400 12.530 0.277s 0.143s 0.235s 12.770 [9 3 88]% ->SR 3 0.035s 400 12.451 0.116s 0.151s 0.236s 12.712 [5 2 93]% SL2 1 0.040s 400 12.578 0.000s 0.004s 0.064s 15.617 [95 5 0]% SM 2 0.055s 800 25.000 0.000s 0.025s 0.078s 25.493 [48 40 12]% SR2 1 0.045s 400 12.500 0.000s 0.004s 0.064s 15.510 [95 5 0]% |
$ demoscale++ wshape 800 C/16/0 SL/3/30 SR/3/35 SL2/1/40 SM/2/55 SR2/1/45 wshape{16,3,3,1,2,1} 800 25.908s 30.879 C 16 0.000s ->SL 3 0.030s 400 15.554 0.164s 0.121s 0.190s 15.830 [6 1 93]% ->SR 3 0.035s 400 15.440 0.186s 0.124s 0.190s 15.803 [4 1 95]% SL2 1 0.040s 400 15.616 0.000s 0.002s 0.058s 17.206 [98 2 0]% SM 2 0.055s 800 31.025 0.000s 0.016s 0.063s 31.640 [51 48 1]% SR2 1 0.045s 400 15.503 0.000s 0.003s 0.063s 15.919 [95 5 0]% |
Ага, 25.908
секунды вместо 32.127
-- это 81%
. Т.е. demoscale++
процентов на 20
быстрее.
Но!
Вы же там не забыли про время задержки?
Например, если время работы SL
0.235
секунды, то общее время задержки SL
, SL2
и SM
будет 0.125
секунды (=30+40+55
). Короче, все отнять и поделить: (190-125)/(235-125)=59%
.
О! 40%
-- это уже не пиво. Надо сказать Шарику.
А без шуток, скучный результат прекрасен! Все рассмотренные варианты масштабирования полностью верны для demoscale++
и дают аналогичный выхлоп. Test PASSED.
Еще один частый вопрос читателей -- смысл терминов bandwidth, throughput и latency. Тут вроде как все понятно, но порой возникает и путаница. Даже чаще!
Так и быть, открою Профессиональный Секрет.
Если не очень понятно английское слово, ваш первый шаг -- хороший online-словарь! Например Google Translate:
Чуете вой над болотом? Это Шарик услышал про Google Translate.
Срочно спасаем друга:
Окай, представьте душевную ленту конвейера суровой Советской Фабрики! Здесь latency -- это время, за которое деталь проезжает от начала до конца конвейера. А throughput -- это количество деталей, проходящих мимо Шарика за секунду.
Тогда:
Никакая часть данного материала не может быть использована в коммерческих целях без письменного разрешения автора.