
Durante la refactorización de nuestro intercambio de cifrado, se decidió revisar el concepto de trabajar con una fecha de mercado. En el caso clásico, la fecha de mercado se distribuye de dos maneras:
1. interfaz REST;
2. Suscripción a la transmisión WEBSocket.
El método REST se usa a menudo para obtener datos históricos, mientras que WEBSocket envía información en vivo en línea. En algunos casos, WEBSocket no se utiliza en absoluto, y las actualizaciones se realizan mediante solicitudes regulares a través de REST.
Y parece que todos están felices. Pero, tras una inspección más cercana, la enorme sobrecarga de tal concepto se hace evidente. Su volumen descansa en REST. Para garantizar el funcionamiento de la interfaz REST, debemos crear un back-end que cumpla con los requisitos de los sistemas altamente cargados. Naturalmente, aquí puede elegir varias opciones de solución desde PHP hasta el Golang ahora de moda.
También es necesario crear una infraestructura altamente accesible, implementar pequeños detalles como CI / CD para servicios, proporcionar todo esto con los especialistas adecuados para el desarrollo, mantenimiento, etc., etc.
Al mismo tiempo, es la fecha histórica de mercado que ocupa la mayor parte del espacio en disco. Generalmente se almacena en la base de datos. Por un lado, esto nos permite resolver el problema de la agrupación, pero a tamaños críticos, se convierte en una carga insoportable y plantea tareas no triviales para el equipo y los desarrolladores de DevOps.
En general ... la aparente simplicidad y consistencia de este concepto se rompe en una vida dura.
Por separado, debe notar la peculiaridad de la fecha de mercado. Siempre se acumula (crece). Es decir en el lenguaje del programador de la base de datos, siempre insertamos y luego seleccionamos. Pero no divisible. Es decir maravillosa funcionalidad de base de datos para sistematización, optimización, etc. Los datos almacenados quedan sin reclamar.
Otra propiedad importante de una fecha de mercado es su estructura claramente definida. Por ejemplo, una vela en un gráfico tiene solo ocho parámetros:
1. El momento del tiempo;
2. Exposición;
3. El precio máximo;
4. El precio mínimo;
5. Precio de apertura;
6. precio de cierre;
7. Volumen;
8. Precio medio.
Lo mismo puede decirse de las ofertas.
Basado en estos requisitos previos, y también armado con experiencia, rápidamente llegué a la conclusión de que es más correcto considerar la fecha de mercado como un flujo estructurado.
Por ejemplo, un flujo con velas se puede considerar como una matriz de estructuras binarias:
moment: int32
exposition: int32
min: float64
max: float64
open: float64
close: float64
volume: float64
average: float64
Total: 56 bytes.
Por ejemplo, dicha vela en JSON se describirá de la siguiente manera:
{ "date":1501004700, "high":0.08053391, "low":0.08020004, "open":0.08030001, "close":0.0803542, "volume":48.62169347, "weightedAverage":0.08038445 }
Total: 167 bytes.
El beneficio en tamaño es obvio. Y esto es menos tráfico, mayor velocidad de entrega al cliente.
Y aquí, por supuesto, me viene a la mente BSON. Pero no resuelve el problema de la necesidad de un backend, y en general no resuelve el problema fundamentalmente. Además, los navegadores no lo admiten de forma nativa.
Miré hacia otro lado. La red tiene muchos recursos trabajando con hilos. Estos son recursos de audio y video. Demuestran todos los signos que son necesarios:
- trabajar con grandes cantidades de datos;
- hacer frente perfectamente a altas cargas;
- son capaces de entregar contenido en línea, pero al mismo tiempo permiten acceder a datos históricos.
Profundicé un poco más en la transmisión de video, lo que me permitió resolver radicalmente todos los problemas anteriores por fecha de mercado. Resultó que toda la magia está oculta en la tecnología
Content-Range , que es compatible de inmediato, por ejemplo, Nginx. Le permite acceder a cualquier área de un recurso estático (archivo en el servidor) sin utilizar un back-end. En general, esto sucede de la siguiente manera: se refiere a la URL que indica la exposición que desea devolver en el encabezado. Por ejemplo: rango: 100-200. No me detendré en las complejidades, puede encontrar todos los matices de la tecnología en artículos especializados. Creo que la esencia es clara.
De hecho, ahora, en la parte frontal, puede organizar una apelación a la parte necesaria del archivo, por ejemplo, que contiene velas. Y como se sabe exactamente cuántos bytes ocupa una vela (56 bytes), podemos determinar fácilmente el desplazamiento que necesitamos. Es cierto que todavía necesitamos saber el momento en que comienza el horario. Y esto se resuelve muy fácilmente agregando un encabezado al archivo, cuyo tamaño también es una constante.
Es decir En primer lugar, el frente accede al archivo desde la posición cero y recibe
rumbo Al mismo tiempo, nginx devolverá el tamaño del archivo. Esto determinará el número total de velas en el archivo y la hora de inicio.
Ahora, conociendo el punto de partida del tiempo, teniendo una idea clara del número de velas, podemos obtener cualquiera de ellas por cualquier período de tiempo desde el frente, sin usar un backend.
Ah, sí ... otro momento ... tenemos un parámetro como la exposición de la vela. Aquí la solución también es simple: tenemos varios archivos a la vez para diferentes exposiciones. Como un pequeño bono adicional, el tamaño de la estructura de la vela se reduce en otros 4 bytes.
En general, la solución ya era lo suficientemente interesante para la implementación, pero resultó que todavía no me da vergüenza decir: beneficios muy interesantes. El hecho es que los navegadores pueden almacenar en caché los datos recibidos por el método de rango. Es decir en la siguiente solicitud frontal al servidor, si esta sección del archivo fue recibida por el navegador anteriormente, no llegará a su servidor, sino que la tomará del caché.
Pero incluso eso no es todo. Usando CDN, el almacenamiento en caché también se puede configurar por sus medios. Es decir En resumen, puede obtener un sistema que puede proporcionar grandes volúmenes de la fecha de mercado al tiempo que minimiza la carga en la infraestructura y los servidores.
No hace falta decir que ya no había ninguna duda sobre la fidelidad de la idea. Ahora hay pequeñas cosas reales ... necesitas hacer la generación de estos mismos archivos.
Como se mencionó anteriormente, generalmente, el intercambio opera dos medios de entrega de la fecha de mercado: REST y WEBSocket. Este último transmite en línea la fecha actual del mercado. Este suele ser un servicio separado. Como la práctica ha demostrado, finalizar este servicio para que agregue datos a los archivos necesarios no es difícil y se resuelve literalmente con un par de horas de trabajo del desarrollador. Podemos decir que inicia sesión al mismo tiempo que el boletín.
El problema de entregar archivos a los nodos es un problema clásico de sincronización del sistema de archivos. El equipo de DevOps lo resuelve fácil y naturalmente. Por ejemplo, usando rsync.
Ahora, podemos decir con seguridad: ¡BINGO!
Quizás surja la pregunta: ¿por qué todos los intercambios de cifrado funcionan de manera diferente? No tengo una respuesta confiable a esta pregunta. Pero hay pensamientos:
- los intercambios fueron creados por simpatizantes desarrolladores de cifrado. Quizás no tenían idea sobre el trabajo de los intercambios clásicos, no tuvieron en cuenta su experiencia y utilizaron soluciones fácilmente disponibles para obtener resultados rápidos. Y estas son soluciones de plantilla: el mismo REST y el JSON que lo acompaña;
- como dicen en la gente: ¿funciona? No tocar - porque Las tendencias tecnológicas ya han sido creadas por los intercambios clave, y los nuevos intercambios emergentes las han tomado prestadas.
Si el tema es interesante para la comunidad, continuaré con artículos sobre otras soluciones no estándar implementadas en nuestro proyecto. Cómo funciona esto en la práctica, puedes verlo en el sitio web de intercambio (ver mi perfil). Propongo especialmente prestar atención al trabajo de la tabla, que demuestra claramente todos los beneficios de esta tecnología.