Автоматическое масштабирование пулов потоков |
суслик играет с пулом потоков
Большинство систем имеют пулы потоков фиксированного размера, apache httpd, php-fpm, gunicorn, gocraft, asynq и Machinery. И эти системы отлично работают и помогают быстро масштабироваться, не решая проблему с нуля. Тем не менее, при достаточном количестве сценариев вы начнете замечать незначительные проблемы, такие как использование только около 25% ЦП, и, тем не менее, ваша задержка в очереди увеличивается, или ваш httpd-сервер выдает 503, хотя у него достаточно ресурсов. Или вы пытались дать 2x ЦП и 2x памяти, ожидая, что ваши контейнеры начнут обрабатывать 2x, но были удивлены, увидев, что это не так.
Основная проблема заключается в том, что эти системы имеют виртуальное ограничение, т. е. настроенный размер пула потоков. Это виртуальное ограничение, если оно не настроено правильно или не поддерживается должным образом часто, может стать основным узким местом для вашей скорости обработки, даже если у вас достаточно физических ресурсов.
Мониторинг и оповещение
Эту проблему можно обойти, просто точно настроив размер пула потоков в соответствии с вашим процессором/памятью. Но это нужно делать часто. Мониторинг и оповещение об использовании пула потоков — еще один отличный способ реактивной оптимизации этой системы, т. е. если количество используемых потоков в вашем пуле превышает 80%, начните настраивать размер пула и выделяйте больше потоков.
Но это по-прежнему не поможет вам в проблемах, когда задержка одной из ваших вышестоящих служб увеличилась и изменила область использования пула потоков. Автоматические выключатели могут защитить вашу службу от такого сценария, но это настолько распространенное требование, что точная настройка каждый раз вызывает затруднения.
Очень большой размер пула потоков
Почему бы не установить размер пула потоков настолько большим, чтобы незначительные или приличные изменения размера в системе не требовали частой тонкой настройки размера пула потоков?
Это решение в первую очередь подходит для пулов потоков с низким объемом используемой памяти и сценариями кратковременных пиковых задержек. Для таких систем, как gunicorn, установка очень большого размера пула потоков в ruby on rails означает выделение большого количества памяти. Это может быть еще более рискованным, если ваш пул потоков имеет концепцию минимума и максимума, а не фиксированный размер. Вы можете подумать, что установка очень высокого максимума решает проблему. Но вы можете столкнуться с инцидентом, когда резко возросло использование памяти и произошел сбой контейнеров из-за того, что контейнер не тестировался на соответствие такому большому размеру пула потоков.
Автоматическое масштабирование пула потоков
Но подождите, если мы автоматически масштабируем пул потоков, не столкнемся ли мы с той же проблемой установки очень большого размера пула потоков? т.е. вылетает.
Да, это было бы так, если бы правильный максимальный предел не определялся автоматически. Возвращаясь к первым принципам, фактическими физическими ресурсами являются «вычисления», «память» и «сеть». Эти ресурсы определяют максимальные пределы системы, за пределами которых они могут сломаться или снизить эффективность, если приблизится к этому пределу.
Имея эти знания, мы можем определить максимальное ограничение для пула потоков, когда мы достигнем 70% или 80% любых физических ресурсов, то есть вычислений, памяти и сети.
Внедрение автоматического масштабирования пула потоков/горутин
Один из способов реализовать это — сохранить независимую систему масштабирования пула потоков и другую систему, которая устанавливает максимальный предел. Однако конкурирующие циклы обратной связи крайне непредсказуемы, если вы не настроите систему должным образом.
Подобно отслеживанию целей, нам необходимо разработать единую метрику и цикл обратной связи, который масштабирует систему вверх или вниз. Эта единственная метрика должна состоять из использования потоков, использования ЦП и использования памяти (часто сеть намного выше и поэтому здесь не рассматривается, но для приложений, где это становится критическим, метрика также должна учитывать использование сети).
Желаемое количество горутин можно оценивать каждую секунду. При скользящем среднем скользящем окне в 30 секунд период охлаждения и игнорирование незначительных изменений в системе могут еще больше сгладить модель масштабирования.
Часто сложнее получить загрузку ЦП только пулом рабочих потоков, исключая все другие компоненты, работающие в системе, и то же самое касается использования памяти. Таким образом, для небольших единиц горутин лучше масштабировать только использование самой горутины до тех пор, пока ЦП и память не вырастут настолько, что основные рабочие горутины или потоки станут значительным вкладом в использование ЦП и памяти. Это можно легко сделать на основе абсолютно приличной единицы ЦП и памяти, то есть 1 ВЦП и 1 ГБ и т. д.,…
Заключение
В то время как мониторинг и оповещение являются достаточно приличным решением для определения правильного размера пула потоков для вашей системы, переход к нулевой конфигурации путем автоматического масштабирования пулов потоков является гораздо более гибкой системой, которая автоматически адаптируется к изменениям в системе.