Equilibrio de carga de particiones entre varias instancias de una aplicación

Para escalar la aplicación de procesamiento de eventos, puede ejecutar varias instancias de la aplicación y equilibrar la carga entre ellas. En las versiones antiguas y en desuso, EventProcessorHost le permitía equilibrar la carga entre varias instancias de su programa y los eventos de punto de control al recibir los eventos. En las versiones más recientes (5.0 y posteriores), EventProcessorClient (.NET y Java) o EventHubConsumerClient (Python y JavaScript) le permiten hacer lo mismo. El modelo de desarrollo se simplifica mediante el uso de eventos. Puede suscribirse a los eventos que le interesen registrando un controlador de eventos. Si usa la versión anterior de la biblioteca cliente, vea las siguientes guías de migración: .NET, Java, Python y JavaScript.

En este artículo se describe un escenario de ejemplo para usar varias instancias de aplicaciones cliente para leer eventos de un centro de eventos. También se proporcionan detalles sobre las características del cliente del procesador de eventos, que permite recibir eventos de varias particiones a la vez y equilibrar la carga con otros consumidores que usan el mismo centro de eventos y el mismo grupo de consumidores.

Nota:

La clave para escalar para Event Hubs es la idea de consumidores con particiones. En contraposición al patrón de consumidores de la competencia, el patrón de consumidores con particiones permite una alta escalabilidad mediante la eliminación de cuellos de botella de contención y la facilitación del paralelismo de principio a fin.

Escenario de ejemplo

Como caso de ejemplo, considere una empresa de seguridad en el hogar que supervisa 100 000 casas. Cada minuto, obtiene los datos de los diversos sensores como el detector de movimiento, el sensor de apertura de puertas y ventanas, el detector de rotura de cristales, etc., instalados en cada casa. La empresa proporciona un sitio web para que los residentes supervisen la actividad de su casa casi en tiempo real.

Cada sensor inserta datos en un centro de eventos. El centro de eventos está configurado con 16 particiones. En el extremo de consumo, necesita un mecanismo que pueda leer estos eventos, consolidarlos (filtrarlos, agregarlos, etc.) y volcar el agregado a un blob de almacenamiento que, a continuación, se proyecta en una página web fácil de usar.

Aplicación de consumidor

Al diseñar un consumidor en un entorno distribuido, el escenario debe controlar los siguientes requisitos:

  1. Escalado: cree varios consumidores y que cada consumidor tome posesión de la lectura desde varias particiones de Event Hubs.
  2. Equilibrio de carga: aumente o reduzca dinámicamente los consumidores. Por ejemplo, si se agrega un nuevo tipo de sensor (por ejemplo, un detector de monóxido de carbono) a cada casa, aumenta el número de eventos. En ese caso, el operador (una persona) aumenta el número de instancias de consumidor. A continuación, el grupo de consumidores puede volver a equilibrar el número de particiones que poseen para compartir la carga con los consumidores recién agregados.
  3. Reanudación sin problemas después de los errores: si un consumidor (consumidor A) genera un error (por ejemplo, la máquina virtual que hospeda al consumidor se bloquea de repente), otros consumidores pueden recopilar las particiones que posee el consumidor A y continuar. Además, el punto de continuación, llamado punto de comprobación o de desplazamiento, debe estar en el punto exacto en el que se produjo el error del consumidor A o ligeramente antes.
  4. Consumo de eventos: mientras que los tres puntos anteriores trataban sobre la administración del consumidor, también tiene que haber código para consumir eventos y hacer algo útil con él. Por ejemplo, agréguelo y cárguelo en el almacenamiento de blobs.

Cliente de consumidor o procesador de eventos

No es necesario que cree su propia solución para cumplir estos requisitos. Los SDK de Azure Event Hubs proporcionan esta funcionalidad. En los SDK de .NET o Java, se usa un cliente de procesador de eventos (EventProcessorClient) y, en los SDK de Python y JavaScript, se usa EventHubConsumerClient. En la versión anterior del SDK, era el host del procesador de eventos (EventProcessorHost) el que admitía estas características.

En la mayoría de los escenarios de producción, se recomienda usar el cliente del procesador de eventos para leer y procesar eventos. El cliente del procesador está diseñado para proporcionar una experiencia sólida para procesar eventos en todas las particiones de un centro de eventos de un modo eficaz y tolerante a errores, a la vez que permite comprobar el progreso. Los clientes del procesador de eventos pueden trabajar en colaboración en el contexto de un grupo de consumidores para un centro de eventos determinado. Los clientes administrarán de forma automática la distribución y el equilibrio del trabajo a medida que las instancias estén disponibles o no para el grupo.

Propiedad de una partición

Por lo general, una instancia de procesador de eventos posee y procesa los eventos de una o de varias particiones. La propiedad de las particiones se distribuye uniformemente entre todas las instancias del procesador de eventos activas asociadas a una combinación de centro de eventos y grupo de consumidores.

Cada procesador de eventos recibe un identificador único y notifica la propiedad de las particiones mediante la adición o actualización de una entrada en un almacén de puntos de control. Todas las instancias del procesador de eventos se comunican con este almacén periódicamente para actualizar su propio estado de procesamiento, así como para obtener información sobre otras instancias activas. Después, estos datos se usan para equilibrar la carga entre los procesadores activos. Para escalar verticalmente, se pueden unir instancias nuevas al grupo de procesamiento. Cuando las instancias dejan de funcionar, ya sea debido a errores o a una reducción vertical, la propiedad de la partición se transfiere correctamente a otros procesadores activos.

Los registros de propiedad de la partición en el almacén de puntos de control realizan un seguimiento del espacio de nombres de Event Hubs, el nombre del centro de eventos, el grupo de consumidores, el identificador de procesador de eventos (también conocido como propietario), el id. de partición y la hora de la última modificación.

Espacio de nombres de Event Hubs Nombre del centro de eventos Grupo de consumidores Propietario Id. de partición Hora de la última modificación
mynamespace.servicebus.windows.net myeventhub myconsumergroup 3be3f9d3-9d9e-4c50-9491-85ece8334ff6 0 2020-01-15T01:22:15
mynamespace.servicebus.windows.net myeventhub myconsumergroup f5cc5176-ce96-4bb4-bbaa-a0e3a9054ecf 1 2020-01-15T01:22:17
mynamespace.servicebus.windows.net myeventhub myconsumergroup 72b980e9-2efc-4ca7-ab1b-ffd7bece8472 2 2020-01-15T01:22:10
:
:
mynamespace.servicebus.windows.net myeventhub myconsumergroup 844bd8fb-1f3a-4580-984d-6324f9e208af 15 2020-01-15T01:22:00

Cada instancia del procesador de eventos adquiere la propiedad de una partición y empieza el procesamiento de la misma desde el último punto de control conocido. Si se produce un error en un procesador (la máquina virtual se apaga), otras instancias lo detectan al examinar la hora de la última modificación. Otras instancias intentan obtener la propiedad de las particiones que anteriormente eran propiedad de la instancia inactiva. El almacén de puntos de control garantiza que solo una de las instancias tenga éxito al reclamar la propiedad de una partición. Por lo tanto, en un momento dado, hay, a lo sumo, un procesador que recibe eventos de una partición.

Recepción de mensajes

Cuando se crea un procesador de eventos, se especifican funciones que procesan eventos y errores. Cada llamada a la función que procesa los eventos entrega un solo evento de una partición específica. Es su responsabilidad administrar este evento. Si desea asegurarse de que el consumidor procesa cada mensaje al menos una vez, debe escribir su propio código con lógica de reintento. Pero tenga cuidado con los mensajes dudosos.

Se recomienda que lo haga relativamente rápido. Es decir, use el menor procesamiento posible. Si tiene que escribir en el almacenamiento y llevar a cabo cierto enrutamiento, es mejor usar dos grupos de consumidores y tener dos procesadores de eventos.

Punto de control

El punto de control es un proceso por el que un procesador de eventos marca o confirma la posición del último evento procesado correctamente en una partición. Por lo general, el marcado de un punto de control se realiza en la función que procesa los eventos y se produce en cada partición de un grupo de consumidores.

Si un procesador de eventos se desconecta de una partición, otra instancia puede reanudar el procesamiento de la partición en el punto de control confirmado previamente por el último procesador de esa partición en ese grupo de consumidores. Cuando se conecta el procesador, pasa el desplazamiento al centro de eventos para especificar la ubicación en la que se va a empezar a leer. De este modo, puede usar puntos de control para que las aplicaciones de nivel inferior marquen los eventos como "completados" y para ofrecer resistencia cuando un procesador de eventos quede fuera de servicio. Es posible volver a los datos más antiguos especificando un desplazamiento inferior desde este proceso de puntos de control.

Cuando se realiza el punto de control para marcar un evento como procesado, se agrega o se actualiza una entrada en el almacén de puntos de control con el desplazamiento del evento y el número de secuencia. Los usuarios deben decidir la frecuencia de actualización del punto de control. La actualización después de cada evento procesado correctamente puede tener implicaciones en el rendimiento y el costo cuando desencadena una operación de escritura en el almacén de puntos de control subyacente. Además, el punto de control de cada evento único es indicativo de un patrón de mensajería en cola para el que una cola de Service Bus podría ser una opción mejor que un centro de eventos. La ventaja de Event Hubs es que obtiene al menos una entrega a gran escala. Al hacer los sistemas de nivel final idempotentes, es fácil recuperarse de errores o reinicios que hacen que los eventos se reciban varias veces.

Siga estas recomendaciones al usar Azure Blob Storage como almacén de puntos de control:

  • Use un contenedor independiente para cada grupo de consumidores. Puede usar la misma cuenta de almacenamiento, pero usar un contenedor por cada grupo.
  • No use el contenedor ni la cuenta de almacenamiento para otras actividades.
  • La cuenta de almacenamiento debe estar en la misma región en la que se encuentra la aplicación implementada. Si la aplicación es local, intente elegir la región más cercana posible.

En la página Cuenta de almacenamiento de Azure Portal, en la sección Blob service, asegúrese de que la siguiente configuración está deshabilitada.

  • Espacio de nombres jerárquico
  • Eliminación temporal de blobs
  • Control de versiones

Seguridad para subprocesos e instancias de procesador

De manera predeterminada, se llama de forma secuencial a la función que procesa eventos para una partición determinada. Los siguientes eventos y llamadas a esta función desde la misma partición se ponen en cola en segundo plano mientras el suministro de eventos continúa ejecutándose en segundo plano en otros subprocesos. Los eventos de diferentes particiones se pueden procesar simultáneamente, y cualquier estado compartido al que se tenga acceso desde varias particiones se debe sincronizar.

Pasos siguientes

Consulte las siguientes guías de inicio rápido: