Sistema de registro de juegos distribuido de alto rendimiento basado en NodeJS
Recientemente, nuestra empresa necesita crear un sistema de registro de juegos unificado, que requiere un cierto grado de versatilidad y puede manejar todos los negocios de juegos de la empresa. A continuación, comparta su experiencia con este proyecto de sistema de registro.
El sistema de registro más popular actualmente es ELK, que es implementado por Beats, Logstash, Elasticsearch, Kibana y otros componentes, pero sigue siendo el mismo. La arquitectura básica del sistema de registro es aproximadamente la siguiente:
.Los sistemas de servicio, como el análisis del juego, son diferentes de otros sistemas del juego y pueden no ser realistas. Los tipos de datos son diversos e incluso cambian con frecuencia. Necesitamos resumir el contenido que permanece sin cambios durante los cambios, como la producción económica del sistema, el consumo de artículos del jugador, las compras en la tienda, etc., para su análisis. Por lo tanto, el sistema de registro del juego en este momento debe cumplir con los siguientes requisitos:
Aunque ELK no es difícil de instalar y configurar, también hay muchos complementos, como Filebeat, lectura de archivos de registro y filtrado. formatos, reenvío, etc., pero no se menciona quién genera estos archivos de registro. De hecho, las empresas son diversas y siempre que haya archivos de registro, se pueden utilizar. Por ejemplo, la mayoría de la gente usa Nginx para recopilar registros. También debemos considerar a los productores de troncos, la separación de responsabilidades y la necesidad de máquinas separadas para la recolección de troncos.
Los juegos son una combinación de tecnología y arte. Los datos son enormes y se presentan en diferentes formas. Solo trabajar duro en los registros requiere mucha energía y es complicado, pero no podemos renunciar al procesamiento por eso. este. Un buen registro del juego también puede ayudarnos a restaurar el retrato del jugador. El ciclo de actualización del juego es corto y los datos cambian mucho. Es necesario proporcionar más informes de referencia en tiempo real y más interfaces de consulta para amigos no técnicos para brindar un mejor análisis de los datos del juego. ELK básicamente resuelve los problemas de recolección y almacenamiento en este aspecto, pero no puede satisfacer nuestras necesidades en términos de análisis.
Después de reflexionar, podemos usar herramientas existentes para combinar múltiples paquetes, por lo que tenemos las siguientes ideas:
Este marco se usa principalmente para Fluentd, ElasticSearch y NodeJS. Arquitectura FEN, como se muestra en la siguiente figura.
Como se puede ver en la imagen de arriba, esta arquitectura de registro es básicamente la misma que la primera imagen, excepto por la adición de análisis, procesamiento por lotes y una gran cantidad de NodeJS.
Nota: No presentaremos la instalación y configuración detallada de cada componente. Hay demasiados en Internet. Cómo utilizar cada componente es la clave.
Primero, permítanos presentarle las herramientas que utilizamos:
Fluentd es un software de recopilación de información de registro completamente gratuito y de código abierto que admite más de 125 tipos de recopilación de información de registro del sistema. Fluentd es muy conveniente y eficaz al recopilar registros de origen a través de HTTP GET, que es similar al comportamiento de registro de Nginx. El beneficio de esto es que los archivos de registro son altamente personalizables; por ejemplo, aquí generamos un archivo cada 5 segundos, lo que nos da 12 archivos por minuto y cada archivo es de tamaño muy pequeño. ¿Por qué es esto importante? Fluentd también tiene muchos complementos, como almacenamiento directo en MongoDB, Amazon Cloud, etc. Si está familiarizado con Ruby, también puede escribir su propio complemento.
Algunas personas usan MongoDB para la recopilación de registros, lo cual es muy imprudente. Solo requiere decenas de millones. ¿Qué pasa si se generan mil millones de registros en medio mes? Los archivos de registro deben guardarse durante un mes o más, por lo que el mantenimiento del clúster y del disco duro es muy importante. La facilidad de uso también es importante. Por ejemplo, la búsqueda de palabras es muy útil cuando el servicio de atención al cliente visita los registros de los jugadores y analiza los errores del juego. ES a continuación también es la abreviatura de este componente.
NodeJS no es adecuado para tareas que requieren un uso intensivo de la CPU, pero está bien para aplicaciones web, que es con lo que estamos familiarizados. Los requisitos en tiempo real del sistema de registro no son altos; el retraso máximo permitido es de media hora y, de hecho, el retraso normal es de unos 10 segundos. Los siguientes empujadores para leer y reenviar registros, registradores para recopilar registros y analizadores para analizar registros y empaquetar datos se implementan en NodeJS.
A continuación se continúa presentando la implementación de cada parte usando NodeJS:
Como se mencionó anteriormente, por qué Fluentd usa el método de dividir en varios archivos pequeños, porque NodeJS no es bueno procesando archivos grandes.Amigable, y considerando que cuando se envía a otra máquina a través de la red, la velocidad de reenvío es demasiado lenta que la velocidad de lectura, por lo que se deben implementar funciones de transmisión continua y registro de puntos de interrupción. Por lo tanto, es necesario implementar las funciones de transferencia de currículum y registro de puntos de interrupción. Piénselo, si lee cientos de archivos M y hay una interrupción, debe registrar permanentemente la última posición y leer desde aquí la próxima vez, lo que aumenta la complejidad del programa. NodeJS tiene un módulo readline, pero las pruebas reales encontraron que su controlabilidad no es tan buena como el flujo de archivos. El acceso a este módulo aún es aceptable para interfaces interactivas. Por el contrario, si el registro se divide en varios archivos pequeños, la velocidad de lectura es muy eficiente y un archivo cada 5 segundos. Incluso si hay decenas de miles de registros, el archivo no será demasiado grande y la memoria no. ocupa demasiado. Puede manejarlo con calma cuando se produzcan errores al hacer clic en reanudar y volver a intentar. Si los registros de tu juego son grandes, puedes agregar más nodos para reducir la presión sobre archivos demasiado grandes.
¿Por qué no simplemente hacer que el registrador se lo envíe a Koa? Debido a su alta eficiencia y gran ancho de banda. NodeJS está bien para sitios web, pero su rendimiento es demasiado débil en comparación con los servidores HTTP profesionales. Un host de 4 núcleos tendrá dificultades con 3000 QPS. Para obtener más información sobre el rendimiento de NodeJS, consulte el artículo en línea. En situaciones de alta concurrencia, el ancho de banda es un gran problema, especialmente cuando se requieren servicios unificados y la máquina de registro y el juego no están en la misma intranet. Con 100.000 usuarios activos diarios, el ancho de banda supera los 50 M, lo que da mucho miedo. El ancho de banda es muy caro. El alto costo del ancho de banda aquí significa un rendimiento de costo demasiado bajo.
Aquí utilizamos Koa como recolector de registros. Usar Koa es más eficiente que usar expressJS, tanto en términos de rendimiento como de eficiencia de desarrollo. También usamos Redis como caché en lugar de realizar tareas de análisis directamente aquí para maximizar la eficiencia del acoplamiento con Pusher. Después de todo, la velocidad de generación de registros es muy rápida, pero la eficiencia de la entrega de la red es relativamente baja.
Nota: Los clústeres que utilizan pm2 3.2.2 pueden tener problemas de bloqueo debido a conflictos de puertos dentro del clúster. Se recomienda utilizar 3.0.3
El analizador lee el contenido en Redis. aquí Es una operación de cola de proceso único. Hasta ahora, el método de análisis de registros es básicamente gratuito.
Dado que tenemos nuestro propio sistema de administración de backend, es fácil para nosotros conectar el análisis del usuario con otros puntos de análisis. Al consultar el comportamiento del jugador, buscaremos ES. Al consultar los informes de análisis, consultaremos los datos. en MongoDB. Por supuesto, también utilizamos Kibana para posibles necesidades.
Actualmente, el sistema de registro ha estado funcionando durante 1,5 meses. Desde MongoDB puro hasta la combinación con ES, hemos tomado muchos desvíos, pero afortunadamente ahora finalmente estamos estables. En términos de rendimiento en este momento, con el registrador y el generador de perfiles en la misma máquina, el uso de la CPU promedia alrededor del 23% y alcanza un máximo de alrededor del 47%, lo que sugiere que todavía hay espacio para adaptarse a la máquina más grande.
En términos de memoria, el valor máximo está dentro de 5G y el rendimiento general es muy fluido sin muchas fluctuaciones. El uso de memoria de redis es inferior a 800 MB, pero la máquina es 16G y todavía hay. Mucho margen que garantizar.
En el script NodeJS, el uso de CPU del registrador es mucho menor, 3 procesos, solo el 3% cada uno, y el uso de memoria de cada proceso es inferior a 100 MB. El analizador usa más CPU y memoria, que se pueden ajustar mediante parámetros en el script. Por ejemplo, el recuento de memoria se limpia más rápido. Si usa pm2, configure max_memory_restart: '4G' para mejorar la estabilidad. .
Lo anterior es un resumen de mi experiencia con el sistema de registro del juego.
Referencias: