Compartir vía


Costo del movimiento del servicio

Un factor que Cluster Resource Manager de Service Fabric toma en cuenta al intentar determinar qué cambios se deben realizar en un clúster es el costo de esos cambios. La noción de "costo" se valora frente a la cantidad de mejora que se puede introducir en el clúster. El costo se tiene en cuenta al mover los servicios por cuestiones de equilibrio, desfragmentación y otros requisitos. El objetivo es cumplir los requisitos de la forma menos perjudicial o costosa.

Mover servicios supone unos costos mínimos de tiempo de CPU y ancho de banda de red. Para los servicios con estado, requiere copiar el estado de dichos servicios, consumiendo memoria y espacio en disco adicionales. Minimizar el costo de las soluciones que Cluster Resource Manager de Azure Service Fabric proporciona ayuda a garantizar que los recursos del clúster no se utilizan de forma innecesaria. De todas formas, tampoco deben pasar por alto soluciones que mejorarían significativamente la asignación de recursos en el clúster.

Cluster Resource Manager cuenta con dos formas de calcular los costos y limitarlos, mientras administra el clúster. El primer mecanismo consiste simplemente en contar cada movimiento que realizaría. Si se generan dos soluciones con prácticamente el mismo equilibrio (puntuación), Cluster Resource Manager elige la que tiene el menor costo (número total de movimientos).

Esta estrategia da buenos resultados. Pero, al igual que con cargas predeterminadas o estáticas, es poco probable que en cualquier sistema complejo todos los movimientos sean iguales. Probablemente algunos sean mucho más costosos.

Establecimiento de los costos de movimiento

Puede especificar el costo de movimiento predeterminado para un servicio cuando este se crea:

PowerShell:

New-ServiceFabricService -ApplicationName $applicationName -ServiceName $serviceName -ServiceTypeName $serviceTypeName –Stateful -MinReplicaSetSize 3 -TargetReplicaSetSize 3 -PartitionSchemeSingleton -DefaultMoveCost Medium

C#:

FabricClient fabricClient = new FabricClient();
StatefulServiceDescription serviceDescription = new StatefulServiceDescription();
//set up the rest of the ServiceDescription
serviceDescription.DefaultMoveCost = MoveCost.Medium;
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

También puede especificar o actualizar MoveCost de forma dinámica para un servicio después de que este se haya creado:

PowerShell:

Update-ServiceFabricService -Stateful -ServiceName "fabric:/AppName/ServiceName" -DefaultMoveCost High

C#:

StatefulServiceUpdateDescription updateDescription = new StatefulServiceUpdateDescription();
updateDescription.DefaultMoveCost = MoveCost.High;
await fabricClient.ServiceManager.UpdateServiceAsync(new Uri("fabric:/AppName/ServiceName"), updateDescription);

Especificación de forma dinámica del costo de movimiento por réplica

Los fragmentos de código anteriores son todos para especificar MoveCost para un servicio completo de una sola vez desde fuera del propio servicio. Sin embargo, el coste de movimiento es más útil cuando el costo de movimiento de un objeto de servicio específico cambia a través de su tiempo medio de vida. Dado que los propios servicios tienen probablemente la idea más precisa del coste de su movimiento en un momento dado, hay una API para que los servicios informen sobre el costo de su propios movimientos en tiempo de ejecución.

C#:

this.Partition.ReportMoveCost(MoveCost.Medium);

Nota:

Solo se puede establecer el coste de movimiento de las réplicas secundarias a través del código.

Informes del coste de movimiento de una partición

En la sección anterior se describe cómo se cargan el informe de instancias o las réplicas de servicio. Hemos proporcionado Service Fabric API para notificar valores MoveCost en nombre de otras particiones. A veces, la réplica o instancia de servicio no puede determinar el mejor valor de MoveCost por sí misma y debe basarse en otra lógica de servicios. La creación de informes de MoveCost en nombre de otras particiones, junto con la carga de informes en nombre de otras particiones, le permite administrar completamente las particiones desde fuera. Estas API eliminan las necesidades del patrón Sidecar desde la perspectiva del Cluster Resource Manager.

Puede notificar actualizaciones de MoveCost para una partición diferente con la misma llamada API. Debe especificar el objeto PartitionMoveCostDescription para cada partición que quiera actualizar con los nuevos valores de MoveCost. La API permite varias maneras de actualizar MoveCost:

  • Una partición de servicio con estado puede actualizar su MoveCost de réplica principal.
  • Los servicios con y sin estado pueden actualizar el MoveCost de todas sus instancias o réplicas secundarias.
  • Los servicios con y sin estado pueden actualizar el MoveCost de una instancia o réplica específica o una instancia en un nodo.

Cada actualización de MoveCost para la partición debe contener al menos un valor válido que se va a cambiar. Por ejemplo, podría omitir la actualización de la réplica principal con la asignación de null a la entrada de la réplica principal, se usarán otras entradas durante la actualización de MoveCost y omitiremos la actualización de MoveCost para la réplica principal. Puesto que es posible actualizar MoveCost para varias particiones con una sola llamada API, la API proporciona una lista de códigos de retorno para la partición correspondiente. Si aceptamos y procesamos correctamente una solicitud de actualización de MoveCost, el código de retorno será Correcto. De lo contrario, la API proporciona código de error:

  • PartitionNotFound: el id. de la partición especificado no existe.
  • ReconfigurationPending: la partición se está volviendo a configurar.
  • InvalidForStatelessServices: se intentó cambiar el MoveCost de una réplica principal para una partición que pertenece a un servicio sin estado.
  • ReplicaDoesNotExist: la réplica o instancia secundaria no existe en un nodo especificado.
  • InvalidOperation: actualización de MoveCost para una partición que pertenece a la aplicación System.

C#:

Guid partitionId = Guid.Parse("53df3d7f-5471-403b-b736-bde6ad584f42");
string nodeName0 = "NodeName0";

OperationResult<UpdatePartitionMoveCostResultList> updatePartitionMoveCostResults =
    await this.FabricClient.UpdatePartitionMoveCostAsync(
        new UpdatePartitionMoveCostQueryDescription
        {
            new List<PartitionMoveCostDescription>()
            {
                new PartitionMoveCostDescription(
                    partitionId,
                    MoveCost.VeryHigh,
                    MoveCost.Zero,
                    new List<ReplicaMoveCostDescription>()
                    {
                        new ReplicaMoveCostDescription(nodeName0, MoveCost.Medium)
                    })
            }
        },
        this.Timeout,
        cancellationToken);

En este ejemplo, realizará una actualización del último coste de traslado notificado para una partición 53df3d7f-5471-403b-b736-bde6ad584f42. El coste de traslado de réplica principal VeryHigh. El coste de traslado de todas las réplicas secundarias será Cero, excepto el costo de traslado de una réplica secundaria específica ubicada en el nodo NodeName0. El coste de traslado de una réplica específica será Medio. Si desea omitir la actualización del costo de traslado de la réplica principal o de todas las réplicas secundarias, puede dejar la entrada correspondiente como null.

Impacto del costo de movimiento

MoveCost tiene cinco niveles: Zero, Low, Medium, High y VeryHigh. Se aplican las reglas siguientes:

  • Los valores de MoveCost están relacionados entre sí, excepto en el caso de Zero y VeryHigh.
  • Zero significa que mover una réplica es gratuito y que no se debe tener en cuenta en la puntuación de la solución.
  • Establecer el costo de movimiento en High o VeryHigh no ofrece ninguna garantía con respecto a que la réplica no se moverá nunca.
  • Las réplicas con el costo de movimiento VeryHigh solo se moverán si hay una infracción de restricción en el clúster que no se puede corregir de otra manera (aunque sea necesario mover muchas otras réplicas para corregir la infracción).

Costo de movimiento como un factor en la selección de réplicas para el movimiento

MoveCost ayuda a encontrar las soluciones que provocan la menor interrupción posible y que son más sencillas de conseguir a la vez que se llega a un equilibrio equivalente. La noción de costo de un servicio puede ser relativa a muchas cosas. Los factores más comunes para calcular el costo de movimiento son:

  • La cantidad de estados o de datos que el servicio tiene que mover.
  • El costo de desconexión de los clientes. El costo de mover una réplica principal es normalmente mayor que el costo de mover una réplica secundaria.
  • El costo de interrumpir una operación en curso. Algunas operaciones en el nivel de almacén de datos o las operaciones realizadas en respuesta a una llamada del cliente son costosas. Llegadas a un cierto punto, no quiere detenerlas si no es necesario. Por lo tanto, mientras la operación está en ejecución, aumenta el costo de movimiento de este objeto de servicio para disminuir la probabilidad de que se mueva. Cuando finaliza la operación, devuelve el costo a la normalidad.

Importante

Se debe considerar con cuidado el uso del costo de movimiento VeryHigh, ya que restringe significativamente la capacidad de Cluster Resource Manager para encontrar una solución de selección de ubicación globalmente óptima en el clúster. Las réplicas con el costo de movimiento VeryHigh solo se moverán si hay una infracción de restricción en el clúster que no se puede corregir de otra manera (aunque sea necesario mover muchas otras réplicas para corregir la infracción).

Habilitación del costo de movimiento en el clúster

Para que sea posible tener en cuenta el MoveCost más pormenorizado, MoveCost tiene que estar habilitado en el clúster. Sin esta configuración, se utilizará el modo predeterminado de recuento de movimientos para calcular MoveCost y se omiten los informes de MoveCost.

ClusterManifest.xml:

        <Section Name="PlacementAndLoadBalancing">
            <Parameter Name="UseMoveCostReports" Value="true" />
        </Section>

a través de ClusterConfig.json para las implementaciones independientes o Template.json para los clústeres hospedados en Azure:

"fabricSettings": [
  {
    "name": "PlacementAndLoadBalancing",
    "parameters": [
      {
          "name": "UseMoveCostReports",
          "value": "true"
      }
    ]
  }
]

Pasos siguientes