En muchos de los servicios en los que trabajo, se realizan muchos registros. Los servicios son servicios WCF (principalmente) que usan la clase .NET EventLogger.
Estoy en el proceso de mejorar el rendimiento de estos servicios, y tuve que pensar que el registro asíncrono beneficiaría el rendimiento.
No estoy al tanto de lo que sucede cuando varios subprocesos solicitan iniciar sesión, y si crea un cuello de botella, pero incluso si no lo hace, sigo pensando que no debería interferir con el proceso real que se está ejecutando.
Creo que debería invocar el mismo método de registro que llamo ahora, pero hacerlo con un nuevo hilo, mientras continúo con el proceso real.
Algunas preguntas sobre eso:
¿Está bien?
¿Hay alguna desventaja?
¿Debería hacerse de otra manera?
¿Quizás es tan rápido que ni siquiera vale la pena el esfuerzo?
Respuestas:
El hilo separado para la operación de E / S suena razonable.
Por ejemplo, no sería bueno registrar qué botones ha presionado el usuario en el mismo hilo de la interfaz de usuario. Dicha interfaz de usuario se bloqueará al azar y tendrá un rendimiento lento percibido .
La solución es desacoplar el evento de su procesamiento.
Aquí hay mucha información sobre el problema del productor-consumidor y la cola de eventos del mundo de desarrollo de juegos
A menudo hay un código como
Este enfoque conducirá a la contención de hilos. Todos los subprocesos de procesamiento lucharán para poder bloquear y escribir en el mismo archivo a la vez.
Algunos pueden intentar quitar las cerraduras.
No es posible predecir el resultado si 2 hilos ingresarán al método al mismo tiempo.
Entonces, los desarrolladores eventualmente deshabilitarán el registro ...
¿Es posible arreglarlo?
Si.
Digamos que tenemos interfaz:
En lugar de esperar a que la cerradura y la realización de bloqueo de operación de archivo cada vez que
ILogger
se llama Vamos a añadir nueva Mensaje de registro a la Penging Cola de mensajes y el retorno a las cosas más importantes:Hemos terminado con este simple registrador asincrónico .
El siguiente paso es procesar los mensajes entrantes.
Para simplificar, comencemos un nuevo subproceso y esperemos para siempre hasta que la aplicación salga o Asynchronous Logger agregará un nuevo mensaje a la cola pendiente .
Estoy pasando una cadena de oyentes personalizados. Probablemente quiera enviar un marco de registro de llamadas (
log4net
, etc.)Aquí está el resto del código:
Punto de entrada:
fuente
Los factores clave a considerar son su necesidad de confiabilidad en los archivos de registro y la necesidad de rendimiento. Consulte las desventajas. Creo que esta es una gran estrategia para situaciones de alto rendimiento.
¿Está bien? Sí
¿Hay alguna desventaja? Sí. Dependiendo de la importancia de su registro y su implementación, podría ocurrir cualquiera de los siguientes: registros escritos fuera de secuencia, acciones de hilo de registro que no se completan antes de que se completen las acciones del evento. (Imagine un escenario en el que inicia sesión "comenzando a conectarse a la base de datos" y luego bloquea el servidor; es posible que el evento de registro nunca se escriba aunque el evento haya ocurrido (!))
Si se hace de una manera diferente, es posible que desee ver el modelo Disruptor, ya que es casi ideal para este escenario
Tal vez es tan rápido que ni siquiera vale la pena el esfuerzo, no estoy de acuerdo. Si la suya es una lógica de "aplicación", y lo único que hace es escribir registros de la actividad, entonces obtendrá órdenes de magnitud de menor latencia al descargar el registro. Sin embargo, si confía en una llamada SQL DB de 5 segundos para regresar antes de registrar 1-2 declaraciones, los beneficios son mixtos.
fuente
Creo que el registro es generalmente una operación sincrónica por su naturaleza. Desea registrar cosas si suceden o si no dependen de su lógica, por lo que para registrar algo, esa cosa debe evaluarse primero.
Dicho esto, puede mejorar el rendimiento de su aplicación almacenando en caché los registros y luego creando un hilo y guardándolos en archivos cuando tiene una operación vinculada a la CPU.
Debe identificar sus puntos de control de manera inteligente para no perder su información de registro importante durante ese período de caché.
Si desea aumentar el rendimiento de sus subprocesos, debe equilibrar las operaciones de E / S y las operaciones de la CPU.
Si crea 10 hilos que hacen IO, entonces no obtendrá un aumento de rendimiento.
fuente
El registro asíncrono es la única forma de hacerlo si necesita baja latencia en los hilos de registro. La forma en que se hace para obtener el máximo rendimiento es a través del patrón disruptor para la comunicación de subprocesos sin bloqueo y sin basura. Ahora, si desea permitir que varios subprocesos se registren simultáneamente en el mismo archivo, debe sincronizar las llamadas de registro y pagar el precio en contención de bloqueo O utilizar un multiplexor sin bloqueo. Por ejemplo, CoralQueue proporciona una cola de multiplexación simple como se describe a continuación:
Puede echar un vistazo a CoralLog, que utiliza estas estrategias para el registro asincrónico.
Descargo de responsabilidad: soy uno de los desarrolladores de CoralQueue y CoralLog.
fuente