Значение пакета кода фабрики служб CpuShares для 100% использования ЦП (макс.)

У меня есть 2 приложения сервисной фабрики (sln) с 3 сервисами (3 пакета кода). Я хочу распределить их в 40% 20% 20% от максимального процента ЦП независимо от ядра, то есть без ограничений по количеству ядер ЦП (текущая машина имеет 4 логических ядра). В соответствии с вышеприведенным содержанием/блогом, если я укажу CpuShares = 512, CpuShares = 256 и CpuShares = 256, тогда максимальная загрузка ЦП должна составлять 40, 20, 20 процентов. Однако это не так: разрешено только 5%, 2% и 2% от максимального использования ЦП для соответствующих служб. Прочитав это сообщение (https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-resource-governance) Я думал, что 1024 — это значение по умолчанию (максимальное значение) для CpuShares, после множества попыток и ошибок я наконец пришел к значение 10 000 для CpuShares, если мы применим какие-либо значения, превышающие это, мы получим ошибку в обозревателе служб, говорящую о недопустимом аргументе для CpuShare. Таким образом, учитывая, что 10 000 = разрешено 100% использование ЦП. Я изменил приведенные выше значения доли ЦП на CpuShares = 4000, CpuShares = 2000 и CpuShares = 2000 при тестировании. Я вижу максимальное процентное использование ЦП, где 40% 20% 20% (не точная дисперсия 5%). Итак, вопрос в том, что я не смог найти значение использования ЦП 10 000 = 100% ни в одном из документов. Поэтому я хочу подтвердить, правильно ли это, а если нет, то как я могу ограничить пакет услуг или кода определенным процентом. Пожалуйста, помогите в этом


person Mandar Nagarkar    schedule 20.09.2018    source источник


Ответы (1)


Распространенное заблуждение об управлении ресурсами для служб в SF заключается в том, что это ресурс, зарезервированный и изолированный для вашей службы, как в контейнерах докеров, и это не правда.

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

Чтобы принудительное ограничение ресурсов работало, для всех пакетов кода в пакете службы должны быть указаны ограничения памяти.

Метрики — это меры для нахождения надлежащего баланса сервисов в кластере и размещения сервисов в узлах с доступными ресурсами, поэтому, если у вас есть сервисы A, B и C, и каждый сервис требует определенного объема ресурсов, скажем, памяти, это легко понять, A = 1000 МБ, B = 512 МБ, C = 512 МБ, а узел a имеет 2 ГБ памяти, они могут быть размещены в одном узле, поэтому предполагается, что службе C требуется 1000 МБ, когда службе C нужно быть активированным, он будет избегать того же узла, где активированы A и B, потому что у него нет возможности работать там, даже если эти службы не потребляют все запрошенные ресурсы, и будет выбран другой узел.

Из документов:

Среда выполнения Service Fabric в настоящее время не обеспечивает резервирование ресурсов. Когда процесс или контейнер открывается, среда выполнения устанавливает лимиты ресурсов для нагрузок, которые были определены во время создания. Кроме того, среда выполнения отклоняет открытие новых пакетов служб, доступных при превышении ресурсов.

Что касается вашего основного вопроса об акциях:

В тех же документах описывается, что доли представляют собой долю зарезервированного ядра ЦП, зарезервированного для пакета службы, разделенного между всеми пакетами кода, активированными на этом узле, если вы определяете доли для каждого пакета кода, их сумма будет общей, и каждый получит долю этих акций.

Как контролируются эти акции?

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

Предположим, что пакет услуг с пакетами кодов A и B активирован со следующим разделением доли:

  • Пакет кодов A (CP.A) = 1500 акций
  • Пакет кодов B (CP.B) = 500 акций

СФ будет:

  • Identify the CPU core capacity reserved for the service package:
    • The capacity will be the CPU core reserved capacity(%) / total available
    • на 4-ядерном процессоре: 1 ядро ​​процессора зарезервировано = 25%
  • Get all shares from the code packages and sum their values to identify how many shares should represent 100% of the reserved(25%) capacity
    • 1500 + 500 = 2000 total shares
    • СР.А должен получить 3 дроби по 4
    • CP.B должен получить 1 дробь из 4
  • Convert Shares fraction to CPU Job Cycles(see why below)
    • CP.A should receive 3/4 of 10,000 -> 7500 cycles
    • CP.B должен получить 1/4 от 10 000 -> 2500 циклов
  • Multiply the number of reserved cycles by the amount of reserved cpu core
    • CP.A should receive 25% of 7500 cycles
    • CP.B должен получить 25% от 2500 циклов

Эти ограничения ограничены объектами заданий, когда процесс (кодовый пакет) активирован, он назначается заданию, в котором установлены эти ограничения, всякий раз, когда процесс потребляет больше циклов, чем ограничение, установленное в задании, потоки вытесняются и планируется другой поток процесса. в ядре. В коде они предполагают, что 10000 represents all available cores, но правильно number of processor cycles that the threads in a job object can use during each scheduling interval. В задании 10000 циклов — это интервал каждого расписания задания, в этом задании запланирован поток, который будет потреблять x циклов этого расписания, и вы будете потреблять 10000 циклов только в том случае, если зарезервируете 4 ядра.

Точная логика находится в этом фрагменте кода:

    double shares = fractionOfSp * Constants::JobObjectCpuCyclesNumber;
    shares = shares * (numCoresAllocated / max(numAvailableCores_, systemCpuCores_));
    rg.CpuShares = static_cast<uint>(shares);

    //fractionOfSp -> Fraction of a Service Package
    //   - A service package represents 100% (Like a Pizza) of reserved core capacity
    //   - Each Code Package will have one or more fraction (A slice of the pizza)
    //Constants::JobObjectCpuCyclesNumber -> is a constant for 10000 cycles
    //numCoresAllocated -> How many cores you assigned to a service package

Некоторые приемы:

  • Количество зарезервированных ядер также влияет на результат, вы должны зарезервировать не менее 0,01% ядра, чтобы получить какой-либо эффект.
  • Доли основаны на ядрах ЦП, зарезервированных для пакета услуг, а не на всех ядрах ЦП, доступных в узле. Если у вашего узла 4 ядра, вы резервируете 1 для пакета услуг, что означает, что вы разделяете 25% мощности вашего узла между каждым пакетом кода.
  • Если некоторые из пакетов кода имеют нулевую долю или вообще не имеют доли, все пакеты кода будут иметь одинаковую долю, даже если вы укажете какое-либо значение.
  • В Linux используется CpuQuota.
  • Максимальное количество циклов задания 10k

Если вам нужна дополнительная информация, посмотрите исходный код здесь

PS: у меня немного закружилась голова, вычисляя все эти цифры, я, вероятно, еще раз пересмотрю позже!

person Diego Mendes    schedule 20.09.2018
comment
Привет, Диего, спасибо за ответ. Установка предела памяти прямолинейна, это абсолютный предел, поэтому, если я установлю память на 1000, тогда служба выдаст ошибку «Память вне исключения» и перезапустится. У меня проблемы с использованием ЦП, и ограничение может быть не абсолютным, но оно удерживает использование ЦП около указанной отметки. Однако мне трудно найти такие значения, как 50%, что означает, что должно быть значение CPUShares . Я понял, что если я укажу 10000, то он будет работать как 100%-ное распределение ЦП. Я просто хочу подтвердить, правда ли это, потому что нет подтверждающего документа от Microsoft. - person Mandar Nagarkar; 20.09.2018
comment
10 КБ — это размер расписания JobObject, используемого для ограничения использования ЦП для каждого процесса. 10k означает количество циклов, которое поток будет потреблять, прежде чем он будет вытеснен. Я обновил свой ответ, посмотрим, имеет ли он смысл сейчас - person Diego Mendes; 22.09.2018