Управление потреблением ресурсов и нагрузкой в Service Fabric с помощью метрик

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

Примерами метрик может служить использование памяти, дисков и ЦП. Это физические метрики, т. е. ресурсы, соответствующие физическим ресурсам на узле, которыми нужно управлять. Метрики также могут быть (и зачастую являются) логическими. Примерами логических метрик могут служить MyWorkQueueDepth, MessagesToProcess и TotalRecords. Логические метрики определяются приложениями и косвенно соответствуют потреблению некоторых физических ресурсов. Логические метрики больше распространены, так как может быть трудно измерить потребление физических ресурсов для каждой службы и сообщить о нем. Именно из-за сложности измерения и создания отчетов о собственных физических метриках Service Fabric предоставляет метрики по умолчанию.

Метрики по умолчанию

Предположим, что вы хотите начать создание и развертывание службы. На этом этапе вы не знаете, какие физические или логические ресурсы она будет использовать. Все в порядке. Диспетчер кластерных ресурсов Service Fabric использует некоторые метрики по умолчанию, когда не указаны другие метрики. К ним относятся:

  • PrimaryCount — число первичных реплик на узле;
  • ReplicaCount — общее число реплик с отслеживанием состояния на узле;
  • Count — число всех объектов службы (без отслеживания и с отслеживанием состояния) на узле.
Метрика Нагрузка экземпляра без отслеживания состояния Вторичная нагрузка с отслеживанием состояния Первичная нагрузка с отслеживанием состояния Вес
PrimaryCount 0 0 1 Высокий
ReplicaCount 0 1 1 Средний
Count 1 1 1 Низкий

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

Вот что вы получаете:

Макет кластера с метриками по умолчанию

Обратите внимание на следующие моменты.

  • Первичные реплики для службы с отслеживанием состояния распределены между несколькими узлами.
  • Реплики для одной секции находятся на разных узлах.
  • Общее число первичных и вторичных реплик распределено в кластере.
  • Общее количество объектов службы равномерно выделено на каждом узле.

Хорошо!

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

Можно работать, используя только метрики по умолчанию. Но, как правило, это означает, что использование вашего кластера ниже и неравномернее, чем хотелось бы. Это связано с тем, что метрики по умолчанию не адаптивны и подразумевают эквивалентность всех служб. Например, работающая и неиспользуемая первичные реплики обе добавляют 1 к значению метрики PrimaryCount. В худшем случае применение только метрик по умолчанию может также привести к неправильному планированию использования узлов, что, в свою очередь, может вызвать проблемы с производительностью. Если вы стремитесь максимально эффективно использовать кластер и избежать проблем с производительностью, необходимо использовать пользовательские метрики и отчеты о динамической нагрузке.

Настраиваемые метрики

Метрики настраиваются отдельно для каждого экземпляра именованной службы во время ее создания.

У любой метрики есть описывающие ее свойства: имя, вес и нагрузка по умолчанию.

  • Metric Name: имя метрики, которое представляет собой уникальный идентификатор метрики в кластере с точки зрения Resource Manager.

Примечание

Пользовательское имя метрики не должно совпадать ни с одним из имен системных метрик, например, servicefabric:/_CpuCores или servicefabric:/_MemoryInMB, так как это может привести к неопределенному поведению. Начиная с Service Fabric версии 9.1, для существующих служб с этими настраиваемыми именами метрик выдается предупреждение о работоспособности, указывающее на неправильное имя метрики.

  • Weight — это вес метрики, который определяет ее важность по сравнению с другими метриками для этой службы.
  • Загрузка по умолчанию представляется по-разному в зависимости от того, какой является служба: с отслеживанием или без отслеживания состояния.
    • Для служб без отслеживания состояния у каждой метрики есть одно свойство — DefaultLoad.
    • Для служб с отслеживанием состояния можно определить следующие свойства:
      • PrimaryDefaultLoad — величина метрики по умолчанию, которая соответствует потреблению службы в качестве первичной реплики.
      • SecondaryDefaultLoad — величина метрики по умолчанию, которая соответствует потреблению службы в качестве вторичной реплики.

Примечание

Если определены пользовательские метрики и необходимо также использовать метрики по умолчанию, следует явно добавить их и определить для них веса и значения. Это требуется для того, чтобы определить связь между метриками по умолчанию и пользовательскими метриками. Например, вас больше интересуют метрика ConnectionCount или WorkQueueDepth, чем распределение первичных реплик. По умолчанию вес метрики PrimaryCount — высокий, поэтому вы хотите уменьшить его до среднего, когда добавляете другие метрики, чтобы они имели более высокий приоритет.

Определение метрик для службы (пример)

Предположим, требуется следующая конфигурация:

  • Служба сообщает о метрике ConnectionCount.
  • Вы также хотите использовать метрики по умолчанию.
  • Вы провели некоторые измерения и выяснили, что обычно первичная реплика этой службы может потреблять 20 единиц MemoryInMb,
  • а вторичные реплики — 5 единиц.
  • Вы знаете, что ConnectionCount является наиболее важной метрикой с точки зрения управления производительностью данной службы.
  • Но вы все равно хотите, чтобы первичные реплики были сбалансированы. Балансировка первичных реплик обычно имеет смысл при любых обстоятельствах. Это помогает избежать ситуации, когда потеря некоторых узлов или доменов сбоя негативно влияет и на большую часть первичных реплик.
  • В прочих случаях можно использовать метрики по умолчанию.

Ниже приведен код, написанный для создания службы с этой конфигурацией метрики.

Код:

StatefulServiceDescription serviceDescription = new StatefulServiceDescription();
StatefulServiceLoadMetricDescription connectionMetric = new StatefulServiceLoadMetricDescription();
connectionMetric.Name = "ConnectionCount";
connectionMetric.PrimaryDefaultLoad = 20;
connectionMetric.SecondaryDefaultLoad = 5;
connectionMetric.Weight = ServiceLoadMetricWeight.High;

StatefulServiceLoadMetricDescription primaryCountMetric = new StatefulServiceLoadMetricDescription();
primaryCountMetric.Name = "PrimaryCount";
primaryCountMetric.PrimaryDefaultLoad = 1;
primaryCountMetric.SecondaryDefaultLoad = 0;
primaryCountMetric.Weight = ServiceLoadMetricWeight.Medium;

StatefulServiceLoadMetricDescription replicaCountMetric = new StatefulServiceLoadMetricDescription();
replicaCountMetric.Name = "ReplicaCount";
replicaCountMetric.PrimaryDefaultLoad = 1;
replicaCountMetric.SecondaryDefaultLoad = 1;
replicaCountMetric.Weight = ServiceLoadMetricWeight.Low;

StatefulServiceLoadMetricDescription totalCountMetric = new StatefulServiceLoadMetricDescription();
totalCountMetric.Name = "Count";
totalCountMetric.PrimaryDefaultLoad = 1;
totalCountMetric.SecondaryDefaultLoad = 1;
totalCountMetric.Weight = ServiceLoadMetricWeight.Low;

serviceDescription.Metrics.Add(connectionMetric);
serviceDescription.Metrics.Add(primaryCountMetric);
serviceDescription.Metrics.Add(replicaCountMetric);
serviceDescription.Metrics.Add(totalCountMetric);

await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

PowerShell.

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName –Stateful -MinReplicaSetSize 3 -TargetReplicaSetSize 3 -PartitionSchemeSingleton –Metric @("ConnectionCount,High,20,5”,"PrimaryCount,Medium,1,0”,"ReplicaCount,Low,1,1”,"Count,Low,1,1”)

Примечание

В приведенных выше примерах и остальной части этого документа описывается управление метриками на уровне отдельных именованных служб. Можно также определить метрики для служб на уровне типа службы. Для этого их нужно указать в манифестах служб. Определение метрики уровня типа не рекомендуется по нескольким причинам. Первая причина заключается в том, что имена метрик часто зависят от среды. При отсутствии утвержденного контракта нельзя быть уверенным, что метрика Cores в одной среде не называется MiliCores или CoReS в других средах. Если метрики определены в манифесте, необходимо создавать новые манифесты для каждой среды. Обычно это порождает большое число различных манифестов с незначительными отличиями, что может усложнить управление.

Как правило, нагрузки метрик назначаются на уровне отдельных именованных экземпляров служб. Предположим, что вы создаете один экземпляр службы для клиента А, который планирует использовать его лишь в незначительной степени. Также предположим, что вы создаете другую службу для клиента Б, рабочая нагрузка которого больше. В этом случае, вероятно, следует настроить нагрузку по умолчанию для этих служб. Если имеются метрики и нагрузки, определенные в манифестах, и необходима поддержка этого сценария, то для этого потребуются разные типы приложений и служб для каждого клиента. Значения, определенные во время создания службы, переопределяют значения, определенные в манифесте, поэтому их можно использовать, чтобы задать значения по умолчанию. Однако это приводит к тому, что значения, объявленные в манифестах, не совпадают с фактическими значениями, используемыми работающей службой. Это может привести к путанице.

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

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

Загрузить

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

  • Можно определить нагрузку при создании службы. Этот тип конфигурации нагрузки называется загрузкой по умолчанию.
  • Информация о показателях, включая нагрузки по умолчанию, для службы может быть обновлена после создания службы. Это обновление метрики выполняется путем обновления службы.
  • Нагрузки для заданной секции можно сбросить, восстановив значения по умолчанию для этой службы. Это обновление метрики называется сбросом загрузки раздела.
  • О нагрузке можно сообщать для каждого объекта службы динамически во время выполнения. Это обновление метрики называется отчетной нагрузкой.
  • Нагрузку для реплик или экземпляров раздела также можно обновить, сообщив о значениях нагрузки с помощью вызова API-интерфейса Fabric. Это обновление метрики называется отчетной нагрузкой для раздела.

Все эти стратегии можно использовать в одной и той же службе на протяжении ее времени существования.

Нагрузка по умолчанию

Нагрузка по умолчанию означает, сколько единиц метрики потребляет каждый объект службы (экземпляр без отслеживания состояния или реплика с отслеживанием состояния) данной службы. Диспетчер кластерных ресурсов использует это число для определения нагрузки объекта службы, пока не получит другие сведения, такие как отчет о динамической нагрузке. Для более простых служб нагрузка по умолчанию представляет собой статическое определение. Нагрузка по умолчанию никогда не обновляется и используется в течение всего времени существования службы. Нагрузки по умолчанию прекрасно подходят для простых сценариев планирования ресурсов, в которых различным рабочим нагрузкам выделяются определенные объемы ресурсов, которые не изменяются.

Примечание

Дополнительные сведения об управлении емкостью и определении емкости узлов в кластере см. в этой статье.

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

Динамическая нагрузка

Предположим, что ваша служба работает уже некоторое время. С помощью средств мониторинга вы определили, что:

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

Такого рода колебания нагрузки могут возникать по различным причинам. Например, разные службы или секции могут быть связаны с разными клиентами с отличающимися требованиями. Нагрузка также может изменяться из-за того, что объем работы, который выполняет служба, меняется в течение дня. Так или иначе, обычно вы не можете использовать для нагрузки по умолчанию какое-либо строго определенное значение. Это особенно важно, если вы хотите максимально эффективно использовать ресурсы кластера. Какую бы величину вы ни выбрали, какое-то время она будет неправильной. При неправильно заданных нагрузках по умолчанию диспетчер кластерных ресурсов будет выделять избыточное или недостаточное количество ресурсов. В результате у вас появятся недостаточно и избыточно используемые узлы, даже если с точки зрения диспетчер кластерных ресурсов кластер будет сбалансированным. И все же использовать нагрузки по умолчанию весьма удобно, так как они предоставляют определенные сведения для первоначального размещения, хотя и не отражают реальное состояние рабочих нагрузок. Чтобы точно выявлять меняющиеся требования к ресурсам, диспетчер кластерных ресурсов позволяет каждому объекту службы обновлять данные о своей нагрузке во время выполнения. Это называется передачей данных о динамической нагрузке.

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

Отчеты о нагрузке для каждой реплики или экземпляра позволяют диспетчеру кластерных ресурсов реорганизовать отдельные объекты службы в кластере. Реорганизация служб гарантирует получение ими необходимых ресурсов. По сути, загруженные службы "высвобождают" неиспользуемые или мало используемые ресурсы других реплик или экземпляров.

В Reliable Services код, используемый для динамического создания отчетов о нагрузке, выглядит следующим образом.

Код:

this.Partition.ReportLoad(new List<LoadMetric> { new LoadMetric("CurrentConnectionCount", 1234), new LoadMetric("metric1", 42) });

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

Отчетность о нагрузке на раздел

В предыдущем разделе описывается, как реплики служб или отчеты об экземплярах загружаются сами. Доступен дополнительный параметр для динамического создания отчетов о нагрузке для реплик секции или экземпляров с помощью API Service Fabric. Сообщая о нагрузке для раздела, вы можете сообщать сразу для нескольких разделов.

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

Есть несколько способов обновить нагрузку в кластере с помощью этого API:

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

Также можно одновременно комбинировать любые из этих обновлений для каждого раздела. Сочетание обновлений нагрузки для определенной секции должно быть указано с помощью объекта PartitionMetricLoadDescription, который может содержать соответствующий список обновлений нагрузки, как показано в примере ниже. Обновления нагрузки представлены с помощью объекта MetricLoadDescription, который может содержать текущее или прогнозируемое значение нагрузки для метрики, заданное с помощью имени метрики.

Примечание

Значения прогнозируемой нагрузки метрики в настоящее время предоставляются в предварительной версии. Они позволяют регистрировать прогнозируемые значения нагрузки и использовать их в Service Fabric, но эта функция в настоящее время не включена.

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

  • PartitionNotFound — указанный идентификатор раздела не существует.
  • ReconfigurationPending — раздел в настоящее время перестраивается.
  • InvalidForStatelessServices — была предпринята попытка изменить загрузку первичной реплики для раздела, принадлежащего службе без отслеживания состояния.
  • ReplicaDoesNotExist — вторичная реплика или экземпляр не существует на указанном узле.
  • InvalidOperation — может произойти в двух случаях: обновление нагрузки для раздела, принадлежащего системному приложению, или обновление прогнозируемой нагрузки не включено.

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

Код:

Guid partitionId = Guid.Parse("53df3d7f-5471-403b-b736-bde6ad584f42");
string metricName0 = "CustomMetricName0";
List<MetricLoadDescription> newPrimaryReplicaLoads = new List<MetricLoadDescription>()
{
    new MetricLoadDescription(metricName0, 100)
};

string nodeName0 = "NodeName0";
List<MetricLoadDescription> newSpecificSecondaryReplicaLoads = new List<MetricLoadDescription>()
{
    new MetricLoadDescription(metricName0, 200)
};

OperationResult<UpdatePartitionLoadResultList> updatePartitionLoadResults =
    await this.FabricClient.UpdatePartitionLoadAsync(
        new UpdatePartitionLoadQueryDescription
        {
            PartitionMetricLoadDescriptionList = new List<PartitionMetricLoadDescription>()
            {
                new PartitionMetricLoadDescription(
                    partitionId,
                    newPrimaryReplicaLoads,
                    new List<MetricLoadDescription>(),
                    new List<ReplicaMetricLoadDescription>()
                    {
                        new ReplicaMetricLoadDescription(nodeName0, newSpecificSecondaryReplicaLoads)
                    })
            }
        },
        this.Timeout,
        cancellationToken);

В этом примере вы выполните обновление последней зарегистрированной нагрузки для раздела 53df3d7f-5471-403b-b736-bde6ad584f42. Загрузка первичной реплики для метрики CustomMetricName0 будет обновлена со значением 100. В то же время нагрузка для той же метрики для конкретной вторичной реплики, расположенной на узле NodeName0, будет обновлена до значения 200.

Обновление конфигурации метрик службы

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

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

Основными интерфейсами API для изменения конфигурации метрик являются FabricClient.ServiceManagementClient.UpdateServiceAsync в C# и Update-ServiceFabricService в PowerShell. Любые данные, указанные с помощью этих API, немедленно заменяют существующие сведения о метриках для службы.

Совместное использование значений нагрузки по умолчанию и отчетов о динамической загрузке

Нагрузка по умолчанию и динамические нагрузки могут использоваться для одной и той же службы. Если служба использует нагрузку по умолчанию и отчеты о динамической нагрузке, то нагрузка по умолчанию служит в качестве оценочного значения, пока не появятся отчеты о динамической нагрузке. Использовать нагрузку по умолчанию удобно, так как диспетчер кластерных ресурсов сразу получает данные для работы. Используя нагрузку по умолчанию, диспетчер кластерных ресурсов может оптимально разместить объекты службы при их создании. Если сведения по умолчанию не предоставляются, службы размещаются практически произвольно. Когда позже поступают отчеты о нагрузке, первоначальное произвольное размещение часто оказывается неправильным, и диспетчеру кластерных ресурсов приходится перемещать службы.

Возьмем наш предыдущий пример и посмотрим, что произойдет, если мы добавим пользовательские метрики и будем динамически создавать отчеты о нагрузке. В этом примере мы используем метрику MemoryInMb.

Примечание

Память является одной из системных метрик, ресурсами которой может управлять Service Fabric, и самостоятельно создавать отчеты о ней обычно затруднительно. Мы не ожидаем, что вы действительно будете создавать отчеты об использовании памяти. Здесь память используется как средство для изучения возможностей диспетчера кластерных ресурсов.

Предположим, мы создали службу с отслеживанием состояния с помощью следующей команды:

PowerShell.

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName –Stateful -MinReplicaSetSize 3 -TargetReplicaSetSize 3 -PartitionSchemeSingleton –Metric @("MemoryInMb,High,21,11”,"PrimaryCount,Medium,1,0”,"ReplicaCount,Low,1,1”,"Count,Low,1,1”)

Напомним, что синтаксис выглядит следующим образом: ("MetricName, MetricWeight, PrimaryDefaultLoad, SecondaryDefaultLoad").

Один из возможных макетов кластера может выглядеть как:

Сбалансированный кластер с метриками по умолчанию и пользовательскими метриками

Обратите внимание на следующие факторы.

  • Вторичные реплики в секции могут иметь собственные нагрузки.
  • В целом метрики выглядят сбалансированными. В случае памяти отношение между минимальной и максимальной нагрузкой составляет 1,75 (узел с наибольшей нагрузкой — N3, с наименьшей — N2, следовательно 28/16 = 1,75).

Но некоторые факторы все же необходимо объяснить.

  • Как определить, является ли соотношение 1,75 разумным? Как Cluster Resource Manager узнает, достаточно ли этого соотношения или нужно еще что-то делать?
  • Когда происходит балансировка нагрузки?
  • Что означает, если вес метрики "Память" определен как высокий?

Вес метрик

Важно отслеживать одни и те же метрики для разных служб. Такой глобальный охват позволяет диспетчеру кластерных ресурсов отслеживать потребление ресурсов в кластере, обеспечивать балансировку потребления межу узлами и следить за тем, чтобы емкость узлов не была превышена. Тем не менее важность одной и той же метрики для разных служб может отличаться. Кроме того, в кластере с множеством метрик и большим количеством служб для некоторых метрик полностью сбалансированные решения могут и не существовать. Как в таких ситуациях должен поступать Cluster Resource Manager?

Веса метрик позволяют Cluster Resource Manager принимать решение о способе балансировки кластера, когда нет идеального решения. Веса метрик также позволяют Cluster Resource Manager по-разному выполнять балансировку для определенных служб. Метрики могут иметь четыре разных уровня веса: нулевой, низкий, средний и высокий. Метрика с нулевым весом не играет роли для балансировки нагрузки. Однако ее нагрузка имеет значение для управления емкостью. Метрики с нулевым весом удобны и часто используются для настройки поведения службы и отслеживания производительности. В этой статье приведены дополнительные сведения об использовании метрик для мониторинга и диагностики служб.

Фактическое влияние разных весов метрик в кластере проявляется в том, что Cluster Resource Manager создает различные решения. По ним он определяет, какие из метрик важнее других. При отсутствии идеального решения служба Cluster Resource Manager может выбрать решения, которые лучше балансируют метрики с большими весами. Если определенная метрика неважна для какой-либо службы, то с точки зрения диспетчера кластерных ресурсов ее использование может казаться несбалансированным. Это позволит другой службе получить равномерное распределение для метрики, которая важна для нее.

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

Пример метрического веса и его влияние на решения для балансировки

В этом примере используются четыре разные службы. Все они сообщают разные значения для двух метрик, MetricA и MetricB. В одном случае все службы определяют метрику MetricA как наиболее важную (высокий вес), а метрику MetricB — как несущественную (низкий вес). В результате мы видим, что диспетчер кластерных ресурсов размещает службы таким образом, чтобы нагрузка для метрики MetricA была лучше сбалансирована, чем нагрузка для метрики MetricB. "Лучше сбалансирована" означает, что среднеквадратичное отклонение метрики MetricA меньше, чем среднеквадратичное отклонение метрики MetricB. Во втором случае мы поменяли веса метрик местами. В результате диспетчер кластерных ресурсов меняет местами службы A и B, чтобы обеспечить выделение ресурсов, при котором нагрузка для метрики MetricB сбалансирована лучше, чем для метрики MetricA.

Примечание

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

Глобальный вес метрик

Предположим, что служба ServiceA определяет метрику MetricA и назначает ей высокий вес, а служба ServiceB назначает метрике MetricA низкий или нулевой вес. Какой же фактический вес будет использован в итоге?

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

Что произойдет, если Cluster Resource Manager не будет учитывать и глобальный, и локальный баланс? Конечно, несложно создать решения с глобальной балансировкой нагрузки, но это приводит к неправильной балансировке выделяемых ресурсов для отдельных служб. В следующем примере рассмотрим службу, для которой настроены только метрики по умолчанию, и узнаем, что происходит, если учитывается только глобальная балансировка нагрузки.

Влияние решения только для глобальной балансировки

В приведенном выше примере только с глобальной балансировкой нагрузки кластер в целом действительно сбалансирован. Все узлы имеют одинаковое количество первичных реплик и реплик вообще. Однако, если взглянуть на результаты такого выделения ресурсов, окажется, что оно не совсем правильное. Потеря одного узла непропорционально влияет на конкретную рабочую нагрузку, так как вместе с узлом теряются все первичные реплики этой рабочей нагрузки. Например, в случае сбоя первого узла будут потеряны три первичные реплики для трех разных разделов службы "Круг". В то же время в секциях служб "Треугольник" и "Шестиугольник" будет утрачена реплика. Это не нарушит работу, но потребуется восстановить утраченную реплику.

В примере ниже служба Cluster Resource Manager распределил реплики с учетом глобального баланса и баланса каждой службы. При вычислении оценки решения она присваивает наибольший вес глобальному решению и (настраиваемой) части для отдельных служб. Глобальное распределение нагрузки для метрики вычисляется на основе средних весов метрик, настроенных для каждой службы. Каждая служба балансируется с учетом определенных для нее весов метрик. Это гарантирует, что внутренняя балансировка служб выполняется в соответствии с их потребностями. В результате, если сбой произойдет на том же первом узле, то его последствия распределятся на все секции всех служб. При этом она влияет одинаково на каждую из них.

Дальнейшие действия