Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
De forma predeterminada, el Orleans entorno de ejecución no crea más de una activación de un grano dentro del clúster. Esta es la expresión más intuitiva del modelo de actor virtual, donde cada grano corresponde a una entidad con un tipo o identidad únicos. Sin embargo, a veces una aplicación necesita realizar operaciones funcionales sin estado no vinculadas a una entidad determinada en el sistema. Por ejemplo, si un cliente envía solicitudes con cargas comprimidas que necesitan descompresión antes de enrutar al grano de destino para su procesamiento, dicha lógica de descompresión o enrutamiento no está vinculada a una entidad específica y puede escalar horizontalmente fácilmente.
Cuando aplicas el StatelessWorkerAttribute a una clase de grano, indica al tiempo de ejecución Orleans que los granos de esa clase deben tratarse como granos sin estado de trabajo. Los granos de trabajo sin estado tienen las siguientes propiedades que hacen que su ejecución sea muy diferente de las clases de grano normal:
- El Orleans tiempo de ejecución puede y crea varias activaciones de un grano de trabajo sin estado en diferentes silos del clúster.
- Los granos de procesamiento sin estado ejecutan solicitudes localmente siempre que el silo sea compatible; de esa manera, no incurren en costos de redes ni serialización. Si el silo local no es compatible, las solicitudes se reenvieron a un silo compatible.
- El entorno de ejecución Orleans crea automáticamente activaciones adicionales para un grano de trabajo sin estado si las existentes están ocupadas. El número máximo de activaciones por silo está limitado de forma predeterminada por el número de núcleos de CPU en la máquina, a menos que lo especifique explícitamente mediante el argumento opcional
maxLocalWorkers. - Debido a los puntos 2 y 3, las activaciones de grano de trabajo sin estado no son direccionables individualmente. Dos solicitudes posteriores a un grano de trabajo sin estado pueden procesarse mediante diferentes activaciones.
Los granos de trabajo sin estado proporcionan una forma sencilla de crear un grupo automanejado de activaciones de granos que se escala automáticamente hacia arriba y hacia abajo según la carga real. El tiempo de ejecución siempre busca activaciones específicas de trabajo sin estado disponibles en el mismo orden. Debido a esto, siempre envía solicitudes a la primera activación local inactiva que encuentra y solo continúa con el último si todas las activaciones anteriores están ocupadas. Si todas las activaciones están ocupadas y no se ha alcanzado el límite de activación, crea una activación más al final de la lista y envía la solicitud a ella. Esto significa que cuando aumenta la tasa de solicitudes a un grano de trabajo sin estado y las activaciones existentes están ocupadas, el tiempo de ejecución expande el grupo de activaciones hasta el límite. Por el contrario, cuando la carga disminuye y un número menor de activaciones puede controlarla, las activaciones al final de la lista no recibirán solicitudes. Primero quedan inactivos y, finalmente, son desactivados mediante el proceso estándar de recopilación de activación. Por lo tanto, el grupo de activaciones finalmente se reduce para que coincida con la carga.
En el ejemplo siguiente se define una clase MyStatelessWorkerGrain de grano de trabajo sin estado con el límite de número máximo de activación predeterminado.
[StatelessWorker]
public class MyStatelessWorkerGrain : Grain, IMyStatelessWorkerGrain
{
// ...
}
Realizar una llamada a un grano de trabajo sin estado es el mismo que llamar a cualquier otro grano. La única diferencia es que, en la mayoría de los casos, se usa un identificador de grano único, por ejemplo, 0 o Guid.Empty. Puede usar varios identificadores de grano si es deseable tener varios grupos de granos de trabajo sin estado (uno por identificador).
var worker = GrainFactory.GetGrain<IMyStatelessWorkerGrain>(0);
await worker.Process(args);
En este ejemplo se define una clase de grano de trabajo sin estado sin más de una activación por silo.
[StatelessWorker(1)] // max 1 activation per silo
public class MyLonelyWorkerGrain : ILonelyWorkerGrain
{
//...
}
Tenga en cuenta que StatelessWorkerAttribute no cambia la reentrada de la clase de grano de destino. Al igual que cualquier otro grano, los granos de trabajo sin estado no son reentrantes de forma predeterminada. Puede convertirlas explícitamente en reentrant agregando un ReentrantAttribute a la clase de grain.
Estado
La parte "sin estado" de "trabajador sin estado" no significa que un trabajador sin estado no pueda tener estado o esté limitado solo a ejecutar operaciones funcionales. Al igual que cualquier otro grano, un grano de trabajo sin estado puede cargarse y mantener en memoria cualquier estado que necesite. Sin embargo, dado que se pueden crear varias activaciones de un grano de trabajo sin estado en los mismos y en diferentes silos del clúster, no existe un mecanismo sencillo para coordinar el estado mantenido por diferentes activaciones.
Varios patrones útiles implican a trabajadores sin estado que gestionan el estado.
Elementos de caché caliente distribuidos
Para los elementos de caché activa que experimentan un alto rendimiento, mantener cada elemento en un grano de trabajo sin estado proporciona estas ventajas:
- Se escala horizontalmente automáticamente dentro de un silo y en todos los silos del clúster.
- Hace que los datos estén siempre disponibles localmente en el silo que recibió la solicitud del cliente a través de su puerta de enlace de cliente, lo que permite responder a las solicitudes sin un salto de red adicional a otro silo.
Agregación de estilo de reducción
En algunos escenarios, las aplicaciones deben calcular determinadas métricas en todos los granos de un tipo determinado del clúster e informar periódicamente de los agregados. Algunos ejemplos incluyen informar del número de jugadores por mapa de juego o la duración media de una llamada VoIP. Si cada uno de los muchos miles o millones de granos notificó sus métricas a un único agregador global, el agregador se sobrecargaría inmediatamente y no podrá procesar la inundación de informes. El enfoque alternativo consiste en convertir esta tarea en una agregación de estilo de reducción de dos pasos (o más). La primera capa de agregación implica que los granos informantes envían sus métricas a un grano de pre-agregación de un trabajador sin estado. El Orleans tiempo de ejecución crea automáticamente varias activaciones del grano de trabajo sin estado en cada silo. Dado que Orleans procesa todas estas llamadas localmente sin llamadas remotas o serialización de mensajes, el costo de esta agregación es significativamente menor que en un caso remoto. Ahora, cada activación de grano de trabajo sin estado previa a la agregación, de forma independiente o en coordinación con otras activaciones locales, puede enviar su informe agregado al agregador final global (o a otra capa de reducción si es necesario) sin sobrecargarlo.