Introducción a Service Fabric Reliable Actors.Introduction to Service Fabric Reliable Actors

Reliable Actors es un marco de trabajo de la aplicación de Service Fabric que se basa en el modelo Virtual Actor .Reliable Actors is a Service Fabric application framework based on the Virtual Actor pattern. La API de Reliable Actors proporciona un modelo de programación uniproceso basado en las garantías de escalabilidad y confiabilidad que ofrece Service Fabric.The Reliable Actors API provides a single-threaded programming model built on the scalability and reliability guarantees provided by Service Fabric.

¿Qué son los actores?What are Actors?

Un actor es una unidad aislada e independiente de proceso y estado con ejecución uniproceso.An actor is an isolated, independent unit of compute and state with single-threaded execution. El patrón de actor es un modelo informático para sistemas simultáneos o distribuidos en que un gran número de estos actores puede ejecutarse simultánea e independientemente unos de otros.The actor pattern is a computational model for concurrent or distributed systems in which a large number of these actors can execute simultaneously and independently of each other. Los actores pueden comunicarse entre sí y pueden crear más actores.Actors can communicate with each other and they can create more actors.

Cuándo usar Reliable ActorsWhen to use Reliable Actors

Service Fabric Reliable Actors es una implementación del modelo de diseño del actor.Service Fabric Reliable Actors is an implementation of the actor design pattern. Al igual que sucede con cualquier modelo de diseño de software, la decisión sobre si usar un modelo específico se toma en función de si un problema de diseño de software se adapta al modelo o no.As with any software design pattern, the decision whether to use a specific pattern is made based on whether or not a software design problem fits the pattern.

Aunque el modelo de diseño del actor puede resultar adecuado para un número de problemas y escenarios de sistemas distribuidos, se requiere una consideración cuidadosa de las restricciones del modelo y el marco de trabajo que lo implementa.Although the actor design pattern can be a good fit to a number of distributed systems problems and scenarios, careful consideration of the constraints of the pattern and the framework implementing it must be made. Como regla general, tenga en cuenta el patrón de actor para modelar su problema o escenario si:As general guidance, consider the actor pattern to model your problem or scenario if:

  • El espacio del problema implica un gran número (miles o más) de unidades pequeñas, independientes y aisladas de estado y lógica.Your problem space involves a large number (thousands or more) of small, independent, and isolated units of state and logic.
  • Desea trabajar con objetos uniproceso que no requieren una interacción importante de los componentes externos, incluida la consulta del estado en un conjunto de actores.You want to work with single-threaded objects that do not require significant interaction from external components, including querying state across a set of actors.
  • Las instancias de actor no bloquearán a los autores de llamadas con retrasos imprevisibles emitiendo operaciones de E/S.Your actor instances won't block callers with unpredictable delays by issuing I/O operations.

Actores en Service FabricActors in Service Fabric

En Service Fabric, los actores se implementan en el marco de Reliable Actors: Un marco de trabajo de la aplicación basado en patrones construido sobre Reliable Services de Service Fabric.In Service Fabric, actors are implemented in the Reliable Actors framework: An actor-pattern-based application framework built on top of Service Fabric Reliable Services. Cada servicio de Reliable Actors que escribe es en realidad un servicio de confianza con estado particionado.Each Reliable Actor service you write is actually a partitioned, stateful Reliable Service.

Cada actor se define como una instancia de un tipo de actor, similar a la forma en que un objeto de .NET es una instancia de un tipo de .NET.Every actor is defined as an instance of an actor type, identical to the way a .NET object is an instance of a .NET type. Por ejemplo, puede haber un tipo de actor que implemente la funcionalidad de una calculadora y podría haber muchos actores de ese tipo que se distribuyesen en varios nodos en un clúster.For example, there may be an actor type that implements the functionality of a calculator and there could be many actors of that type that are distributed on various nodes across a cluster. Cada uno de esos actores se identifica de forma única mediante un identificador de actor.Each such actor is uniquely identified by an actor ID.

Duración del actorActor Lifetime

Los actores de Service Fabric son virtuales, lo que significa que su duración no está vinculada a su representación en memoria.Service Fabric actors are virtual, meaning that their lifetime is not tied to their in-memory representation. Como resultado, no es necesario crearlas ni destruirlas explícitamente.As a result, they do not need to be explicitly created or destroyed. El tiempo de ejecución de Reliable Actors activa automáticamente un actor la primera vez que recibe una solicitud para ese identificador de actor.The Reliable Actors runtime automatically activates an actor the first time it receives a request for that actor ID. Si no se usa un actor durante un período de tiempo, el tiempo de ejecución de Reliable Actors recopila el objeto en memoria como elemento no utilizado.If an actor is not used for a period of time, the Reliable Actors runtime garbage-collects the in-memory object. También mantendrá conocimientos de la existencia del actor por si es necesario reactivarlo más adelante.It will also maintain knowledge of the actor's existence should it need to be reactivated later. Para más información, consulte Ciclo de vida de un actor y recolección de elementos no utilizados.For more details, see Actor lifecycle and garbage collection.

Esta abstracción de la duración del actor virtual incluye algunas advertencias como resultado del modelo Virtual Actor y, de hecho, la implementación de Reliable Actors se desvía en ocasiones de este modelo.This virtual actor lifetime abstraction carries some caveats as a result of the virtual actor model, and in fact the Reliable Actors implementation deviates at times from this model.

  • Un actor se activa automáticamente (provocando la creación de un objeto de actor) la primera vez que se envía un mensaje a su identificador de actor.An actor is automatically activated (causing an actor object to be constructed) the first time a message is sent to its actor ID. Transcurrido un período de tiempo, el objeto de actor se recolecta como elemento no utilizado.After some period of time, the actor object is garbage collected. En el futuro, usar de nuevo el identificador de actor provoca la creación de un nuevo objeto de actor.In the future, using the actor ID again, causes a new actor object to be constructed. La duración del estado del actor equivale a la vida útil del objeto al almacenarse en el administrador de estado.An actor's state outlives the object's lifetime when stored in the state manager.
  • Al llamar a cualquier método de actor para un identificador de actor se activa dicho actor.Calling any actor method for an actor ID activates that actor. Por este motivo, se llama de forma implícita al constructor de los tipos de actor mediante el tiempo de ejecución.For this reason, actor types have their constructor called implicitly by the runtime. Por lo tanto, el código de cliente no puede pasar parámetros al constructor del tipo de actor, aunque se pueden pasar parámetros al constructor del actor mediante el propio servicio.Therefore, client code cannot pass parameters to the actor type's constructor, although parameters may be passed to the actor's constructor by the service itself. El resultado es que los actores se pueden crear en un estado inicializado de forma parcial en el momento en que se llama a otros métodos en él, en caso de que el actor requiera parámetros de inicialización del cliente.The result is that actors may be constructed in a partially-initialized state by the time other methods are called on it, if the actor requires initialization parameters from the client. No hay ningún punto de entrada único para la activación de un actor desde el cliente.There is no single entry point for the activation of an actor from the client.
  • Aunque Reliable Actors crea de forma implícita objetos de actor, tiene la posibilidad de eliminar explícitamente un actor y su estado.Although Reliable Actors implicitly create actor objects; you do have the ability to explicitly delete an actor and its state.

Distribución y conmutación por errorDistribution and failover

Para proporcionar escalabilidad y confiabilidad, Service Fabric distribuye actores en el clúster y los migra automáticamente desde los nodos con errores hasta los correctos según sea necesario.To provide scalability and reliability, Service Fabric distributes actors throughout the cluster and automatically migrates them from failed nodes to healthy ones as required. Se trata de una abstracción sobre un servicio de confianza con estado particionado.This is an abstraction over a partitioned, stateful Reliable Service. Distribución, escalabilidad, confiabilidad y conmutación por error automática se proporcionan en virtud del hecho de que los actores se ejecuten en un servicio de confianza con estado denominado Servicio de actor.Distribution, scalability, reliability, and automatic failover are all provided by virtue of the fact that actors are running inside a stateful Reliable Service called the Actor Service.

Los actores se distribuyen entre las particiones del Servicio de actor y dichas particiones se distribuyen entre los nodos en un clúster de Service Fabric.Actors are distributed across the partitions of the Actor Service, and those partitions are distributed across the nodes in a Service Fabric cluster. Cada partición del servicio contiene un conjunto de actores.Each service partition contains a set of actors. Service Fabric administra la distribución y conmutación por error de las particiones del servicio.Service Fabric manages distribution and failover of the service partitions.

Por ejemplo, un Servicio de actor con nueve particiones implementadas en tres nodos mediante la ubicación predeterminada de la partición del actor se distribuiría del siguiente modo:For example, an actor service with nine partitions deployed to three nodes using the default actor partition placement would be distributed thusly:

Distribución de Reliable Actors

El marco de trabajo de actores administra la configuración del intervalo de claves y el esquema de partición por usted.The Actor Framework manages partition scheme and key range settings for you. Esto simplifica algunas opciones, pero también implica cierta consideración:This simplifies some choices but also carries some consideration:

  • Reliable Services le permite elegir un esquema de creación de particiones, el intervalo de claves (al usar un esquema de creación de particiones por rangos) y el recuento de particiones.Reliable Services allows you to choose a partitioning scheme, key range (when using a range partitioning scheme), and partition count. Reliable Actors se restringe al esquema de creación de particiones por rangos (el esquema Int64 uniforme) y requiere que use el intervalo de claves Int64 completo.Reliable Actors is restricted to the range partitioning scheme (the uniform Int64 scheme) and requires you use the full Int64 key range.
  • De forma predeterminada, los actores se colocan aleatoriamente en particiones, dando como resultado una distribución uniforme.By default, actors are randomly placed into partitions resulting in uniform distribution.
  • Como los actores se colocan aleatoriamente, debe esperarse que las operaciones del actor requieran siempre la comunicación de red, incluidas la serialización y deserialización de datos de la llamada al método, incurriendo en latencia y sobrecarga.Because actors are randomly placed, it should be expected that actor operations will always require network communication, including serialization and deserialization of method call data, incurring latency and overhead.
  • En escenarios avanzados, es posible controlar la ubicación de la partición del actor mediante los identificadores de actor Int64 que se asignan a particiones específicas.In advanced scenarios, it is possible to control actor partition placement by using Int64 actor IDs that map to specific partitions. Sin embargo, esto puede dar lugar a una distribución desequilibrada de los actores entre particiones.However, doing so can result in an unbalanced distribution of actors across partitions.

Para más información sobre cómo se particionan los servicios de actor, consulte Partitioning concepts for actors(Conceptos de creación de particiones para actores).For more information on how actor services are partitioned, refer to partitioning concepts for actors.

Comunicación con actoresActor communication

Las interacciones entre actores se definen en una interfaz compartida por el actor que implementa la interfaz y el cliente que consigue un proxy a un actor a través de la misma interfaz.Actor interactions are defined in an interface that is shared by the actor that implements the interface, and the client that gets a proxy to an actor via the same interface. Como esta interfaz se usa para invocar métodos de actor de forma asincrónica, cada método de la interfaz debe devolver tareas.Because this interface is used to invoke actor methods asynchronously, every method on the interface must be Task-returning.

Las invocaciones de método y sus respuestas tienen como resultado final solicitudes de red en el clúster, de modo que los argumentos y los tipos de resultado de las tareas que devuelven deben ser serializables por parte de la plataforma.Method invocations and their responses ultimately result in network requests across the cluster, so the arguments and the result types of the tasks that they return must be serializable by the platform. En particular, deben ser serializables mediante contrato de datos.In particular, they must be data contract serializable.

El proxy de actorThe actor proxy

La API de cliente de Reliable Actors ofrece comunicación entre una instancia de actor y un cliente de actor.The Reliable Actors client API provides communication between an actor instance and an actor client. Para comunicarse con un actor, un cliente crea un objeto proxy de actor que implementa la interfaz del actor.To communicate with an actor, a client creates an actor proxy object that implements the actor interface. El cliente interactúa con el actor mediante la invocación de métodos en el objeto proxy.The client interacts with the actor by invoking methods on the proxy object. El proxy de actor puede usarse para la comunicación de cliente a actor y de actor a actor.The actor proxy can be used for client-to-actor and actor-to-actor communication.

// Create a randomly distributed actor ID
ActorId actorId = ActorId.CreateRandom();

// This only creates a proxy object, it does not activate an actor or invoke any methods yet.
IMyActor myActor = ActorProxy.Create<IMyActor>(actorId, new Uri("fabric:/MyApp/MyActorService"));

// This will invoke a method on the actor. If an actor with the given ID does not exist, it will be activated by this method call.
await myActor.DoWorkAsync();
// Create actor ID with some name
ActorId actorId = new ActorId("Actor1");

// This only creates a proxy object, it does not activate an actor or invoke any methods yet.
MyActor myActor = ActorProxyBase.create(actorId, new URI("fabric:/MyApp/MyActorService"), MyActor.class);

// This will invoke a method on the actor. If an actor with the given ID does not exist, it will be activated by this method call.
myActor.DoWorkAsync().get();

Tenga en cuenta que los dos tipos de datos que se usan para crear el objeto de proxy de actor son el identificador del actor y el nombre de la aplicación.Note that the two pieces of information used to create the actor proxy object are the actor ID and the application name. El identificador de actor identifica de forma única al actor, mientras que el nombre de la aplicación identifica la Aplicación de Service Fabric en la que se implementa el actor.The actor ID uniquely identifies the actor, while the application name identifies the Service Fabric application where the actor is deployed.

La clase ActorProxy(C#) / ActorProxyBase(Java) del cliente realiza la resolución necesaria para localizar el actor mediante el identificador y abre un canal de comunicación con él.The ActorProxy(C#) / ActorProxyBase(Java) class on the client side performs the necessary resolution to locate the actor by ID and open a communication channel with it. También vuelve a intentar localizar el actor en caso de que se produzcan errores de comunicación y conmutaciones por error.It also retries to locate the actor in the cases of communication failures and failovers. Como resultado, la entrega de mensajes tiene las siguientes características:As a result, message delivery has the following characteristics:

  • La entrega de mensajes es la mejor opción.Message delivery is best effort.
  • Los actores pueden recibir mensajes duplicados del mismo cliente.Actors may receive duplicate messages from the same client.

SimultaneidadConcurrency

El tiempo de ejecución de Reliable Actors ofrece un modelo de acceso simple basado en turnos para obtener acceso a los métodos de actor.The Reliable Actors runtime provides a simple turn-based access model for accessing actor methods. Esto significa que no puede haber más de un subproceso activo dentro del código del objeto de actor en ningún momento.This means that no more than one thread can be active inside an actor object's code at any time. El acceso basado en turnos simplifica considerablemente sistemas simultáneos, pues no es necesario que los mecanismos de sincronización tengan acceso a datos.Turn-based access greatly simplifies concurrent systems as there is no need for synchronization mechanisms for data access. También significa que los sistemas deben diseñarse con consideraciones especiales para la naturaleza de acceso uniproceso de cada instancia de actor.It also means systems must be designed with special considerations for the single-threaded access nature of each actor instance.

  • Una sola instancia de actor no puede procesar más de una solicitud cada vez.A single actor instance cannot process more than one request at a time. Una instancia de actor puede provocar un cuello de botella de procesamiento si se espera que controle solicitudes simultáneas.An actor instance can cause a throughput bottleneck if it is expected to handle concurrent requests.
  • Los actores pueden interbloquearse si hay una solicitud circular entre dos actores mientras se realiza una solicitud externa destinada a uno de los actores simultáneamente.Actors can deadlock on each other if there is a circular request between two actors while an external request is made to one of the actors simultaneously. El tiempo de ejecución del actor agotará el tiempo de expiración en llamadas de actor automáticamente y generará una excepción al autor de llamada para interrumpir posibles situaciones de interbloqueo.The actor runtime will automatically time out on actor calls and throw an exception to the caller to interrupt possible deadlock situations.

Comunicación de Reliable Actors

Acceso basada en turnosTurn-based access

Un turno es la ejecución completa de un método de actor en respuesta a la solicitud de otros actores o clientes, o la ejecución completa de la devolución de llamada de un temporizador o recordatorio .A turn consists of the complete execution of an actor method in response to a request from other actors or clients, or the complete execution of a timer/reminder callback. Aunque estos métodos y devoluciones de llamada son asincrónicos, el tiempo de ejecución de los actores no los intercala.Even though these methods and callbacks are asynchronous, the Actors runtime does not interleave them. Un turno debe completarse por completo antes de que se permita uno nuevo.A turn must be fully finished before a new turn is allowed. En otras palabras, la devolución de llamada de un método de actor, un temporizador o recordatorio que se esté ejecutando se debe completar totalmente antes de que se permita una llamada a un método o una devolución de llamada nuevas.In other words, an actor method or timer/reminder callback that is currently executing must be fully finished before a new call to a method or callback is allowed. Un método o una devolución de llamada se consideran finalizadas si la ejecución ha devuelto desde el método o la devolución de llamada y la tarea devuelta por el método o la devolución de llamada ha terminado.A method or callback is considered to have finished if the execution has returned from the method or callback and the task returned by the method or callback has finished. Merece la pena resaltar que la simultaneidad basada en turnos se respeta incluso entre devoluciones de llamada, temporizadores y métodos diferentes.It is worth emphasizing that turn-based concurrency is respected even across different methods, timers, and callbacks.

El tiempo de ejecución de los actores impone la simultaneidad basada en turnos mediante la adquisición de un bloqueo por actor al principio de un turno y su liberación al final del turno.The Actors runtime enforces turn-based concurrency by acquiring a per-actor lock at the beginning of a turn and releasing the lock at the end of the turn. Por lo tanto, la simultaneidad basada en turnos se aplica por actor y no para todos los actores.Thus, turn-based concurrency is enforced on a per-actor basis and not across actors. Las devoluciones de llamada de los métodos de actor, los temporizadores y los recordatorios se pueden ejecutar simultáneamente en nombre de los diferentes actores.Actor methods and timer/reminder callbacks can execute simultaneously on behalf of different actors.

En el ejemplo siguiente se muestran los conceptos anteriores.The following example illustrates the above concepts. Supongamos un tipo de actor que implementa dos métodos asincrónicos (digamos Method1 y Method2), un temporizador y un recordatorio.Consider an actor type that implements two asynchronous methods (say, Method1 and Method2), a timer, and a reminder. En el diagrama siguiente se muestra un ejemplo de una escala de tiempo de la ejecución de estos métodos y las devoluciones de llamada en nombre de los dos actores (ActorId1 y ActorId2) que pertenecen a este tipo de actor.The diagram below shows an example of a timeline for the execution of these methods and callbacks on behalf of two actors (ActorId1 and ActorId2) that belong to this actor type.

Acceso y simultaneidad basada en turnos de tiempo de ejecución de Reliable Actors

Este diagrama sigue estas convenciones:This diagram follows these conventions:

  • Cada línea vertical muestra el flujo lógico de ejecución de un método o una devolución de llamada en nombre de un actor determinado.Each vertical line shows the logical flow of execution of a method or a callback on behalf of a particular actor.
  • Los eventos marcados en cada línea vertical se producen en orden cronológico, con los eventos más recientes por debajo de los más antiguos.The events marked on each vertical line occur in chronological order, with newer events occurring below older ones.
  • Se usan colores diferentes para las escalas de tiempo correspondientes a actores distintos.Different colors are used for timelines corresponding to different actors.
  • Se usa el resaltado para indicar la duración durante la cual se mantiene el bloqueo por actor en nombre de un método o una devolución de llamada.Highlighting is used to indicate the duration for which the per-actor lock is held on behalf of a method or callback.

Algunos puntos importantes a tener en cuenta:Some important points to consider:

  • Cuando Method1 se ejecuta en nombre de ActorId2 en respuesta a la solicitud de cliente xyz789, llega otra solicitud de cliente (abc123) que también requiere que Method1 lo ejecute ActorId2.While Method1 is executing on behalf of ActorId2 in response to client request xyz789, another client request (abc123) arrives that also requires Method1 to be executed by ActorId2. Sin embargo, la segunda ejecución de Method1 no comienza hasta que se haya completado la ejecución anterior.However, the second execution of Method1 does not begin until the prior execution has finished. De forma similar, un recordatorio que haya registrado ActorId2 se activa cuando Method1 se ejecuta en respuesta a la solicitud de cliente xyz789.Similarly, a reminder registered by ActorId2 fires while Method1 is being executed in response to client request xyz789. La devolución de llamada del recordatorio se ejecuta solo después de que las dos ejecuciones de Method1 se hayan completado.The reminder callback is executed only after both executions of Method1 are complete. Todo esto se debe a la simultaneidad basada en turnos que se exige para ActorId2.All of this is due to turn-based concurrency being enforced for ActorId2.
  • De forma similar, también se aplica la simultaneidad basada en turnos para ActorId1, como se muestra en la ejecución de Method1, la ejecución de Method2 y la devolución de llamada del temporizador en nombre de ActorId1, que suceden en serie.Similarly, turn-based concurrency is also enforced for ActorId1, as demonstrated by the execution of Method1, Method2, and the timer callback on behalf of ActorId1 happening in a serial fashion.
  • La ejecución de Method1 en nombre de ActorId1 se superpone con su ejecución en nombre de ActorId2.Execution of Method1 on behalf of ActorId1 overlaps with its execution on behalf of ActorId2. Esto es así porque solo se exige la simultaneidad basada en turnos dentro de un actor y no para todos los actores.This is because turn-based concurrency is enforced only within an actor and not across actors.
  • En algunas ejecuciones de métodos y devoluciones de llamada, el elemento Task(C#) / CompletableFuture(Java) que devuelve el método o la devolución de llamada se completa después de la devolución del método.In some of the method/callback executions, the Task(C#) / CompletableFuture(Java) returned by the method/callback finishes after the method returns. En otras, la operación asincrónica ya se completó antes de la devolución del método o la devolución de llamada.In some others, the asynchronous operation has already finished by the time the method/callback returns. En ambos casos, el bloqueo por actor se libera solo después de la devolución del método o la devolución de llamada, y de la finalización de la operación asincrónica.In both cases, the per-actor lock is released only after both the method/callback returns and the asynchronous operation finishes.

ReentradaReentrancy

El tiempo de ejecución de los actores permite la reentrada de forma predeterminada.The Actors runtime allows reentrancy by default. Esto significa que si un método de actor del actor A llama a un método del actor B, que a su vez llama a otro método del actor A, se permite que ese método se ejecute.This means that if an actor method of Actor A calls a method on Actor B, which in turn calls another method on Actor A, that method is allowed to run. Esto es porque forma parte del mismo contexto lógico de la cadena de llamada.This is because it is part of the same logical call-chain context. Todas las llamadas del temporizador y el recordatorio comienzan con el nuevo contexto de llamada lógico.All timer and reminder calls start with the new logical call context. Consulte Reentrada en Reliable Actors para más detalles.See the Reliable Actors reentrancy for more details.

Ámbito de garantías de simultaneidadScope of concurrency guarantees

El tiempo de ejecución de los actores ofrece estas garantías de simultaneidad en situaciones donde controla la invocación de estos métodos.The Actors runtime provides these concurrency guarantees in situations where it controls the invocation of these methods. Por ejemplo, ofrece estas garantías para las invocaciones de método que se realizan en respuesta a una solicitud de cliente y para las devoluciones de llamada de temporizadores y recordatorios.For example, it provides these guarantees for the method invocations that are done in response to a client request, as well as for timer and reminder callbacks. Sin embargo, si el código del actor invoca directamente a estos métodos fuera de los mecanismos que ofrece el tiempo de ejecución de los actores, el tiempo de ejecución no puede ofrecer ninguna garantía de simultaneidad.However, if the actor code directly invokes these methods outside of the mechanisms provided by the Actors runtime, then the runtime cannot provide any concurrency guarantees. Por ejemplo, si el método se invoca en el contexto de una tarea que no está asociada con la tarea que han devuelto los métodos de actor, el tiempo de ejecución no puede ofrecer garantías de simultaneidad.For example, if the method is invoked in the context of some task that is not associated with the task returned by the actor methods, then the runtime cannot provide concurrency guarantees. Si el método se invoca desde un subproceso que el actor crea por sí mismo, entonces el tiempo de ejecución tampoco puede proporcionar garantías de simultaneidad.If the method is invoked from a thread that the actor creates on its own, then the runtime also cannot provide concurrency guarantees. Por lo tanto, para realizar operaciones en segundo plano, los actores deben usar temporizadores de actor o recordatorios de actor que respeten la simultaneidad basada en turnos.Therefore, to perform background operations, actors should use actor timers and actor reminders that respect turn-based concurrency.

Pasos siguientesNext steps

Para empezar, cree su primer servicio de Reliable Actors:Get started by building your first Reliable Actors service: