93 votos

Creación de una base de datos de series temporales de datos financieros desde cero

Mi empresa está empezando una nueva iniciativa destinada a construir una base de datos financiera desde cero.

Lo usaríamos de estas maneras:

  1. Análisis de series temporales de: datos financieros de una empresa (por ejemplo, el total de activos fijos de IBM a lo largo del tiempo), agregaciones (por ejemplo, el total de activos fijos del sector de los materiales a lo largo del tiempo), etc.
  2. Instantánea de una empresa: varios puntos de datos de una sola empresa
  3. Análisis de varias empresas a través de múltiples campos de datos para un único marco temporal, normalmente el día actual.
  4. Backtesting, análisis de rangos, análisis de datos, etc. de ideas y factores personalizados.

Amplitud aproximada de los datos:

  1. 3000 empresas
  2. 3500 campos de datos (por ejemplo: total de activos fijos, ganancias, etc.)
  3. 500 niveles de agregación
  4. Periodicidad: diaria, mensual, trimestral, anual
  5. 20 años de retrospectiva que crecerían con el tiempo

Preguntas:

  1. ¿Qué base de datos debemos elegir? Actualmente estamos limitados a las opciones gratuitas y preferimos el código abierto (por principio). Actualmente utilizamos PostgreSQL.
  2. ¿Cómo debo estructurar este esquema? Estoy pensando en dividir los tipos de campo en categorías (balance, descriptivo, cuenta de resultados, cálculos personalizados, etc.) de modo que cada empresa tendría una tabla para el balance, descriptivo, cuenta de resultados, cálculos personalizados, etc. con cada fila representando un día y los campos apropiados para la categoría de la tabla para las columnas/campos. Esa será mi base de datos totalmente normalizada. A partir de la base de datos totalmente normalizada, construiré un almacén de datos, tablas temporales, vistas, etc. que no estén totalmente normalizadas para que las consultas sean rápidas para los distintos casos de uso descritos anteriormente. Un problema de este enfoque es el número de tablas. Si tengo, por ejemplo, 5 categorías de datos de empresas y 3.000 empresas, tendré 15.000 tablas en mi base de datos totalmente normalizada sólo para almacenar los datos de las empresas. Pero aún así, desde mi punto de vista, parece la mejor manera de hacerlo.
  3. ¿Cuál es la mejor estrategia para indexar y estructurar la parte de las series temporales? He hablado con algunas personas y he investigado un poco sobre la indexación/estructura de las bases de datos de series temporales, pero la ayuda/referencias/consejos/etc. en esta área, incluso si duplican lo que he encontrado, sería útil. Me doy cuenta de que esto depende de la respuesta a # 1 anterior, así que tal vez asumir que me quedo con PostgreSQL y voy a construir la funcionalidad "serie de tiempo" campanas y silbatos específicos a mí mismo.

Notas:

  • Se prefieren las respuestas técnicas en profundidad y las referencias/enlaces.
  • Esto es para una pequeña empresa de inversión financiera.
  • Si ya has recorrido este camino, se aceptan sugerencias fuera del ámbito de mi pregunta inicial.
  • No podemos comprometer la cantidad de datos, así que reducirla no es una opción para nosotros; sin embargo, las cifras que he proporcionado son sólo estimaciones.
  • Si hay un lugar mejor para hacer esta pregunta, por favor hágamelo saber.
  • Hay mucho más en lo que queremos hacer, pero esto representa el núcleo de lo que queremos hacer desde la perspectiva de la estructura de datos.

5 votos

¿Ha pensado en utilizar github.com/manahl/arctic ?

0 votos

No lo he hecho. ¿Cree usted que es un buen ajuste? He hojeado la descripción y no estoy seguro de que lo haga mejor que pg con la extensión de almacén de columnas o Cassandra. ¿Qué opinas?

1 votos

Creo que la API que proporciona es muy amigable y el autor dice que el rendimiento debería compararse favorablemente con OpenTSDB / Kairosdb.( No lo he probado yo mismo.) También podría valer la pena probar Kairosdb basado en Cassandra. Puedes ejecutar algunos benchmarks para ver cuál se ajusta a tus necesidades.

110voto

Nobby Puntos 101

Voy a recomendar algo que no dudo que hará que la gente se alborote por completo y que probablemente haga que la gente me ataque. Ya me pasó en el pasado y perdí muchos puntos en StackOverflow porque la gente votó en contra de mi respuesta. Ciertamente espero que la gente sea más abierta en el foro de quant.

Nota - Parece que esta sugerencia ha vuelto a crear un fuerte desacuerdo. Antes de que leas esto me gustaría señalar que esta sugerencia es para una "Pequeña empresa de compra" y no para un sistema multiusuario masivo.

Pasé 7 años dirigiendo una operación de comercio de alta frecuencia y nuestro principal objetivo era construir sistemas como éste. Pasamos mucho tiempo tratando de encontrar la manera más eficiente de almacenar, recuperar y analizar los datos de nivel de orden de la Bolsa de Nueva York, NASDAQ y una amplia variedad de ECNs. Lo que les estoy presentando es el resultado de ese trabajo.

Nuestra respuesta fue No utilice una base de datos . Un sistema básico de archivos estructurados de trozos de datos serializados funciona mucho mejor. Los datos de las series temporales del mercado son únicos en muchos aspectos, tanto en su uso como en su almacenamiento. Las bases de datos se desarrollaron para necesidades muy diferentes y, de hecho, perjudican el rendimiento de lo que se intenta hacer.

Esto se da en el contexto de una operación comercial de tamaño pequeño o mediano que se centra en el análisis de datos relacionados con las estrategias comerciales o el análisis de riesgos. Si estás creando una solución para un gran corredor de bolsa, un banco o tienes que satisfacer las necesidades de un gran número de clientes simultáneos, entonces me imagino que tu solución será diferente a la mía.

Resulta que me encantan las bases de datos. Ahora mismo estoy usando MongoDB para parte de un nuevo proyecto que nos permite analizar las operaciones de opciones, pero mis datos de series temporales de mercado, incluyendo 16 años de datos de opciones, están todos incorporados en un almacén de archivos estructurados.

Permítanme explicar el razonamiento que hay detrás de esto y por qué es más eficaz.

En primer lugar, veamos cómo se almacenan los datos. Las bases de datos están diseñadas para permitir que un sistema haga una gran variedad de cosas con los datos. Las funciones CRUD básicas: crear, leer, actualizar y eliminar. Para hacer estas cosas de forma eficaz y segura, hay que implementar muchas comprobaciones y mecanismos de seguridad. Antes de leer los datos la base de datos necesita estar segura de que los datos no están siendo modificados, está comprobando si hay colisiones, etc. Cuando se leen los datos en una base de datos, el servidor hace un gran esfuerzo para almacenar esos datos en la caché y determinar si se pueden servir más rápidamente después. Hay operaciones de indexación y replicación de datos para prepararlos para ser vistos de diferentes maneras. Los diseñadores de bases de datos se han esforzado mucho en diseñar estas funciones para que sean rápidas, pero todas ellas requieren tiempo de procesamiento y si no se utilizan son sólo un impedimento.

Los datos de las series temporales del mercado se almacenan de una manera completamente diferente. De hecho, yo diría que se preparan más que se almacenan. Cada elemento de datos sólo tiene que escribirse una vez y, después, nunca tiene que modificarse o cambiarse. Los elementos de datos pueden escribirse secuencialmente, no hay necesidad de insertar nada en el medio. No necesita ninguna funcionalidad ACID. No tienen apenas referencias a otros datos. La serie de tiempo es efectivamente su propia cosa.

Como una base de datos hace toda la magia que hace que las bases de datos sean maravillosas, también se llena de bytes. El mínimo espacio que pueden ocupar los datos es su propio tamaño original. Se pueden hacer algunos trucos con la normalización de los datos y la compresión, pero sólo llegan hasta cierto punto y ralentizan las cosas. La indexación, el almacenamiento en caché y las referencias a los datos acaban por acumular bytes y consumir el almacenamiento.

La lectura también está muy simplificada. Encontrar los datos es tan sencillo como la hora y el símbolo. La indexación compleja no sirve de nada. Dado que los datos de las series temporales suelen leerse de forma lineal y en un trozo secuencial a la vez, las estrategias de almacenamiento en caché en realidad ralentizan el acceso en lugar de ayudar. Se necesitan ciclos del procesador para almacenar en caché los datos que no se van a volver a leer en breve.

Estas son las estructuras básicas que nos han funcionado. Creamos estructuras de datos básicas para serializar los datos. Si tu mayor preocupación es la velocidad y el tamaño de los datos puedes ir con un simple almacenamiento binario personalizado. En otra respuesta, omencat sugirió usar TeaFiles y parece que también es prometedor. Nuestra necesidad reciente es la de una mayor flexibilidad, por lo que optamos por utilizar un formato JSON bastante denso, pero flexible.

Hemos dividido los datos en trozos bastante obvios. Los datos bursátiles EOD son un ejemplo muy sencillo, pero el concepto también funciona para nuestros conjuntos de datos más amplios.

Utilizamos los datos para el análisis en escenarios de series temporales bastante tradicionales. Se puede hacer referencia a una cita o a una serie que contenga años de datos a la vez. Era importante dividir los datos en trozos del tamaño de un bocado para su almacenamiento, por lo que optamos por hacer que un "bloque" de nuestros datos equivalga a un año de datos de series temporales de acciones EOD. Cada bloque es un archivo que contiene un año de datos EOD de OHLC serializados como JSON. El nombre del archivo es el símbolo de la acción precedido por un guión bajo. Nota: el guión bajo evita problemas cuando el símbolo de la acción entra en conflicto con comandos del DOS como COM o PRN.

Nota, asegúrese de entender las limitaciones de su sistema de archivos. Nos metimos en problemas cuando pusimos demasiados archivos en un solo lugar. Esto llevó a una estructura de directorio que es efectivamente su propio índice. Se desglosa por el año de los datos y luego también se ordena por la primera letra del símbolo de la acción. Esto nos da entre 20 y unos cientos de archivos de símbolos por directorio. El aspecto es más o menos el siguiente;

\StockEOD\ {YYYY} {Inicial} \_symbol.json

Los datos de AAPL para 2015 serían

\StockEOD\2015\A\_AAPL.json

Un pequeño fragmento de su archivo de datos tiene el siguiente aspecto;

[{"dt":"2007-01-03T00:00:00","o":86.28,"h":86.58,"l":81.9,"c":83.8,"v":43674760},
{"dt":"2007-01-04T00:00:00","o":84.17,"h":85.95,"l":83.82,"c":85.66,"v":29854074},
{"dt":"2007-01-05T00:00:00","o":85.84,"h":86.2,"l":84.4,"c":85.05,"v":29631186},
{"dt":"2007-01-08T00:00:00","o":85.98,"h":86.53,"l":85.28,"c":85.47,"v":28269652}

Tenemos un objeto router que puede darnos una lista de nombres de archivos para cualquier solicitud de datos en sólo un puñado de líneas. Cada archivo se lee con un Async filestream y se deserializa. Cada cita se convierte en un objeto y se añade a una lista ordenada en el sistema. En ese momento, podemos hacer una consulta muy rápida para recortar los datos innecesarios. Los datos están ahora en la memoria y pueden ser utilizados en casi cualquier forma necesaria.

Si el tamaño de la consulta es demasiado grande para el ordenador, no es difícil fragmentar el proceso. Se necesita una petición masiva para conseguirlo.

He tenido programadores a los que les he descrito esto que casi entran en cólera diciéndome que lo estaba haciendo mal. Que esto era "rodar mi propia base de datos" y una completa pérdida de tiempo. De hecho, cambiamos de una base de datos bastante sofisticada. Cuando hicimos nuestra base de código para manejar esto cayó a un pequeño puñado de clases y menos de 1/4 del código que utilizamos para gestionar la solución de base de datos. También obtuvimos un salto de casi 100 veces en la velocidad. Puedo recuperar 7 años de datos de acciones al final del día para 20 símbolos en un par de milisegundos.

Nuestro antiguo sistema de comercio HF utilizaba conceptos similares, pero en un entorno Linux altamente optimizado y operaba en el rango de los nanosegundos.

6 votos

¡No puedo creer que hayas perdido puntos por esto! Debería ser de conocimiento común (al menos en el mundo de los cuates) que los archivos planos se desempeñan y escalan mejor que cualquier (incluso KDB y sus amigos) base de datos. El único inconveniente es la falta de un lenguaje de consulta.

2 votos

Tras una primera lectura rápida, ¡muy interesante! Investigaré más sobre esto. Tiene sentido desde el punto de vista conceptual. Pronto volveré con preguntas. ¡Gracias de nuevo!

1 votos

@hroptatyr Sí, creo que fueron algunos chicos orientados a la web, pero me echaron en cara que incluso sugiriera que los archivos planos podían tener un mejor rendimiento que su querida base de datos. Incluso después de mostrar los datos de rendimiento no se echaron atrás. Eso me alejó de stack overflow por un tiempo.

35voto

Timothy Carter Puntos 7079

Todas las respuestas anteriores (desgraciadamente muy votadas a estas alturas) no tienen en cuenta la cuestión. No se debe elegir un SGBD o una solución de almacenamiento en función de las pruebas de rendimiento generales, sino en función del caso de uso. Si alguien dice que consigue "x ms de lectura", "y inserciones por segundo", "k veces más rápido", "almacena n TB de datos" o "tiene m años de experiencia" y utiliza eso para justificar una propuesta ante ti, no te fíes de esa persona.

Puedo describir un punto de ruptura común para cada una de las soluciones propuestas anteriormente:

  1. Archivos planos: Esto es una mala idea cuando empiezas a tener muchas aplicaciones de clientes, tienes un equipo pequeño, y/o necesita acceder a estos datos en tiempo real. Incluso un equipo pequeño puede tener cientos de procesos en servidores heterogéneos que acceden a los datos de forma simultánea, por lo que se empieza a convertir en un problema de hardware o de sistema de archivos si se almacenan los datos en archivos planos y se confía en las propias aplicaciones para gestionar el acceso simultáneo. Incluso los RDBMS de hace 10-20 años hacen un trabajo bastante decente para gestionar esto, lo que llevaría una cantidad de tiempo no trivial a tus propios desarrolladores para replicarlo. Escribir software concurrente de bajo nivel para lidiar con los límites de E/S de la red o las limitaciones del sistema de archivos es casi siempre más caro que averiguar cómo implementar una base de datos en clúster o sharding con herramientas de código abierto, y si tienes un equipo pequeño, tu tiempo de desarrollador es infinitamente más valioso que la velocidad de consulta de un solo archivo. Has dicho que planeas hacer backtest contra el almacén de datos - sí, claro, puedes hacer backtest a 500 MB/s a 2 GB/s (millones de entradas por segundo, ¡genial!) en un solo servidor con un archivo simple en un SSD rápido, pero no es trivial escalar esto con archivos simples.

  2. Base de datos de series temporales orientada a columnas: La mayoría de la gente confunde las optimizaciones modernas de las bases de datos con las ventajas orientadas a las columnas. Los SGBD más modernos disponen de uniones hash paralelas inteligentes, operaciones de agregación basadas en SIMD y otras similares que explican su aumento de velocidad. Digamos que, en teoría, un SGBD orientado a filas debería superar siempre a un SGBD orientado a columnas en cuanto a velocidad de escritura, pero en muchos benchmarks se ve lo contrario porque muchos SGBD orientados a columnas tienen formas más modernas de diferir la generación de metadatos o mantener los índices. Al final, la orientación a columnas es

    i. Una mala idea cuando casi siempre materializar plenamente sus registros temprano . Por ejemplo, suponga que sólo almacena {time, best_bid, best_ask} y que sólo selecciona todas las columnas del intervalo de tiempo $[a,b]$ porque está haciendo un análisis exploratorio y aún no sabe qué función $f(best\ bid, best\ ask)$ con la que quieres trabajar. En primer lugar, la ventaja de la caché de recorrer secuencialmente los tiempos (almacenados continuamente) en $\mathbb{O}(n)$ pierde con la ventaja algorítmica de perseguir punteros a través del árbol B de índices en $\mathbb{O}(\log n)$ . La mayoría de los arquitectos de SGBD orientados a columnas son conscientes de ello e implementan sus optimizadores de consultas para que recurran al índice si la consulta sigue este patrón, por lo que tanto los SGBD orientados a filas como los orientados a columnas están en igualdad de condiciones. Pero en el paso de materialización, el SGBD orientado a columnas todavía tiene que deserializar las columnas separadas en registros orientados a filas, mientras que el SGBD orientado a filas sólo escribe los datos en orden de almacenamiento y debería ser más rápido en teoría.

    ii. Insignificante si sus conjuntos de calificación de consultas suelen ser pequeños. El mayor cuello de botella está en la carga de un sector del disco en la memoria. Si el conjunto de datos calificados es pequeño, todos ellos se encuentran en los mismos (pocos) sectores, independientemente de la disposición orientada a columnas o a filas, por lo que no existe una ventaja de velocidad de primer orden en la disposición orientada a columnas.

    iii. Caro si se necesita el apoyo de terceros. Sólo hay unos pocos SGBD orientados a columnas con fuerza de producción, y conseguir que un contratista le ayude aquí es más caro que conseguir asistencia gratuita de calidad en MySQL. Si quieres que las aplicaciones en tiempo real se suscriban a tu base de datos, lo más probable es que necesites una solución comercial cara porque todas las opciones de código abierto tienen un soporte débil para dicha funcionalidad.

  3. NoSQL: Digamos que tienes dos empresas que deciden fusionarse, lo que sucede muy a menudo ya que estás viendo la granularidad diaria. Hay diferentes convenciones para manejar esto, pero ahora ¿cómo se actualizan las ganancias asociadas con cualquiera de las dos empresas? No hay un modelo de datos en cascada en MongoDB, así que ahora se descarga el trabajo del nivel de la base de datos al nivel de la aplicación. Esto puede ser malo por varias razones, (1) lo más probable es que le des esta tarea a un analista para que lo haga por ti, que es más propenso a estropearlo que dejar que el esquema garantice la integridad por ti, (2) tienes que escribir código específico para cada caso para actualizar campos específicos en tus documentos JSON, lo que es difícil de mantener, (3) MongoDB, propuesto anteriormente, tiene un formato de serialización bastante ineficiente (BSON) y casi todas tus aplicaciones aguas abajo van a tener un cuello de botella por la biblioteca BSON en algún momento.

Esto es lo que te sugiero que hagas: Quédese con PostgreSQL porque ya está familiarizado con él, diseñe su esquema de manera que sea fácil para usted migrar sus datos a cualquier solución futura, determine dónde están los cuellos de botella de rendimiento de sus casos de uso antes de pedir una solución más específica.

Tendrá que preguntar a sus usuarios finales cuáles son estos cuellos de botella. Lo son:

  1. Backtesting
  2. Ejecución de consultas de rango de tiempo ("Consígueme todas las columnas de datos en este rango de tiempo").
  3. Ejecución de operaciones de agregación ("Quiero encontrar el precio máximo de la operación, calcular el volumen total, etc.")
  4. Acceso concurrente ("Quiero escribir mis resultados de backtest en el servidor A mientras el servidor B está transmitiendo los resultados al servidor B y C").
  5. Mantener relaciones complejas ("Necesito conocer todas las revisiones de fechas de dividendos y tengo que actualizarlas con frecuencia").
  6. Mantener relaciones no estructuradas ("Esta clase de activos tiene precios de ejercicio, pero esta otra clase de activos no").

La solución ideal difiere en función de su caso de uso.

0 votos

Muchas gracias. En cuanto a tu sugerencia de construirlo y luego "determinar dónde están los cuellos de botella de tus casos de uso antes de pedir una solución más específica" - Es un enfoque tradicional y antes de hacer esta pregunta era mi plan. Sin embargo, intentaba evitar construirlo dos veces, si era posible. En cuanto a "diseñar su esquema de una manera a prueba de futuro que es fácil para que usted pueda migrar sus datos a cualquier solución futura" - ¿Puede explicar lo que podría parecer? ¿Qué pasa con el tema de las tablas de 15k, etc., que menciona mi OQ? Muy buen material, ¡gracias!

0 votos

Una última pregunta. ¿Puede ampliar esta afirmación "no es trivial escalar esto con archivos planos"? ¿Puede explicar por qué? Lo siento, no lo entiendo exactamente. ¿Qué aspecto hace que no se escale bien? Gracias.

4 votos

@madilyn siento que hayas sentido la necesidad de atacar mi respuesta. Se basa en años de hacer lo que percibo como su necesidad. También se refería específicamente a los datos de las series temporales con los que he estado trabajando activamente durante 17 años. Voy a hacer la suposición de que usted no ha trabajado con datos de archivos planos mucho porque algunos de sus puntos son erróneos. Los sistemas de archivos son extremadamente fáciles de programar en estos días y no he visto ningún problema relacionado con el FS desde mediados de los 90.

16voto

Paul Calcraft Puntos 144

Interesante debate y Not to wake sleeping dogs El mundo se ha movido bastante en este año y medio, y el espacio de los datos se ha disparado.

Me gustaría recomendar algunas nuevas tecnologías y, al mismo tiempo, compartir algunas de mis experiencias en este espacio.

Como intenta explicar @madilyn: Todo depende de tu caso de uso. En mi experiencia, es fácil saber lo que quieres hacer hoy, pero es muy difícil prever todos los casos de uso futuros. Por lo tanto, también tengo en cuenta la agilidad a la hora de elegir la pila a utilizar para un sistema determinado.

Los archivos planos son realmente potentes, especialmente si se almacenan en formato binario (por ejemplo , HDF5 , Pluma , Parquet Apache ), usar JSON y serializar/deserializar los datos no es nada inteligente.

Cuando se trata de grandes cantidades de filas de datos estructurados, una base de datos moderna orientada a columnas es difícil de superar, especialmente en combinación con tecnologías interesantes como snappy (compresión que... bueno, comprime y da un i/o más rápido - ¡¿Qué?!) y sistemas de archivos distribuidos (por ejemplo, GlusterFS, GridFS, CEPH), que le permite construir un clúster de base de datos relativamente barato y escalable, consulte Columnstore de MariaDB y el super performante (pero con algunos inconvenientes) Clickhouse .

La mayoría de los datos de las finanzas tienen la dimensión del tiempo, por lo que podría ser una buena idea de pensar esto en el? KDB+ existe desde hace décadas con una base de datos muy potente, que desgraciadamente no está disponible para las pequeñas empresas debido a su coste. Ahora está surgiendo toda una subindustria, alimentada por el rumor del IoT, que ofrece bases de datos de series temporales (p. ej. InfluxDB , RiakTS , OpenTSDB ), pero en mi opinión el último y aún relativamente desconocido contendiente TimescaleDB ofrece algunas características realmente únicas. TimescaleDB es una extensión de PostgreSQL y ofrece capacidades de series temporales dentro de la misma base de datos donde residen sus datos no dimensionales en el tiempo, facilitando el JOIN y en general aprovechando el gran conjunto de características de PostgreSQL.

El lenguaje de consulta es realmente importante, y en mi opinión nada supera a SQL (y NewSQL) en términos de compatibilidad. Al obligar a otras personas a aprender y utilizar CQL o MongoDB Query Language, es muy posible que acabes construyendo un cementerio de datos.

Cuando NoSQL estaba en la cúspide de su fama, yo era uno de los chicos cool a bordo de una base de datos MongoDB, rápidamente me di cuenta de que a. Yo era el único usuario b. Yo quería usar herramientas de BI para la exploración de datos temprana, MongoDB han tenido correctamente un montón de clientes con la misma petición, así que por suerte han hecho un 'Conector para BI'. He probado tanto el oficial como un montón de conectores SQL hechos por proveedores de terceros, y déjame decir esto: No tienes que hacer el mismo experimento, a menos que quieras perder un día o dos de tu vida.


Conclusión Me pondré (en parte) del lado de @madilyn PostgreSQL con la extensión TimescaleDB podría ser el camino a seguir para el OP, pero si usted no está ya casado con PostgreSQL entonces también checkout Columnstore de MariaDB Una vez que tengas una buena solución, entonces construir un feature/script para extraer datos en un archivo binario para investigaciones puntuales/eventos.

0 votos

Buena respuesta, de acuerdo en que los diferentes DBMS y formatos de serialización sugeridos son todos posibles candidatos. También tengo que añadir que un problema común con todos los candidatos modernos disponibles para nosotros es que muy pocos de ellos tienen ganchos bien mantenidos para cluster middleware o cualquier cosa que está haciendo para orquestar la computación distribuida, lo que significa que en realidad puede obtener una mejor productividad al sacrificar el rendimiento de una solución más comúnmente utilizado que tiene una comunidad de software más amplio. Muchas de las principales empresas siguen utilizando HDFS aunque sea notoriamente lento.

0 votos

Postgre también tiene una extensión de almacén de columnas github.com/citusdata/cstore_fdw

15voto

Ted Percival Puntos 3712

La respuesta estándar va a ser que para las series temporales, usted quiere una base de datos de almacenamiento de columnas. Estas bases de datos están optimizadas para las consultas de rango (es decir, dame todo lo que hay entre dos marcas de tiempo) porque, fundamentalmente, almacenan los datos a lo largo de una de las dimensiones (que debes elegir, normalmente el tiempo) de forma contigua en el disco, y por lo tanto las lecturas son extremadamente rápidas. La alternativa, cuando se normaliza completamente en una base de datos relacional, es que el tiempo se indexará, pero no se almacenará de forma contigua. Por lo tanto, si se piden, digamos, 3000 puntos de datos, se golpea el índice 3000 veces, e incluso si dicho índice se mantiene completamente en la memoria (poco probable si se tienen 3000 empresas x3500 campos), esto lleva mucho tiempo. Anecdóticamente, incluso usando MongoDB, que es muy vasto, obtuve una velocidad 100x mayor usando Cassandra. Hbase también le servirá, mientras que los participantes menos conocidos, como RiakTS, InfluxDB y otros, están más especializados en series temporales y a menudo no tienen soporte de herramientas (por ejemplo, Flink o Spark). Cassandra se adapta muy bien a mis necesidades, pero no tengo tantos campos como tú (aunque los maneja con facilidad). Sin embargo, almaceno grandes cantidades de datos de series temporales (intradía) y Cassandra también tiene tasas de ingesta muy altas.

Sin embargo, . Usted menciona la normalización. Cassandra y otros no le darán normalización. No le darán nada parecido a las sofisticadas herramientas de integridad que ofrecen las bases de datos relacionales, ni las complejas opciones de esquema. En particular, si desea una velocidad de almacenamiento de columnas a lo largo de más de uno de los ejes de su hibercubo de datos, tendrá que repetir la forma transpuesta de los datos. De lo contrario, volverá a tener un rendimiento relacional (es decir, todavía puede indexar a través de las dimensiones, por supuesto). Si crees que la mayor parte de tus consultas se realizarán a lo largo del eje temporal, y que no tienes mucha necesidad de esquemas complejos, te recomiendo encarecidamente Cassandra. Se utiliza mucho en la industria financiera por esta razón.

Sin embargo, una opción que podría ser equivalente para usted es Postgres con sus capacidades de almacenamiento de columnas. Puedes especificar a Postgres que almacene los datos a lo largo de un eje contiguo, obteniendo así el beneficio de los almacenes de columnas. Tenga en cuenta, sin embargo, que Postgres no escala a través de múltiples máquinas tan fácilmente como Cassandra o Hbase. Tendrás que escalarlo verticalmente, lo que es mucho más caro cuando empiezas a forzar la ingesta o el rendimiento de las consultas. Con Cassandra, sólo hay que añadir cajas baratas. Todos sabemos que 10 cajas baratas son mucho más baratas que la única caja monstruosa que mantendrá su rendimiento (paralelizado). De hecho, en algunos niveles de rendimiento, el sistema relacional se ahoga, mientras que Cassandra escala linealmente a tantas cajas como se quiera (se dice que Apple tiene 75.000 nodos). Por eso Netflix utiliza Cassandra, al igual que Apple. Necesitarás un gran equipo de estilo z-enterprise si quieres intentar acercarte al rendimiento de un clúster de Cassandra, incluso de tamaño medio, con una base de datos relacional.

Entonces, Postgres o Cassandra. Probablemente se reducirá a si vas a poner los datos para el consumo público (es decir, un gran número de usuarios), o si tus datos son realmente grandes (> 5 terabytes es lo que yo llamo "grande"). En ese caso, Cassandra. O si necesita una normalización rigurosa de la ciencia de la computación y todas las campanas y silbatos que Postgres le dará, y de hecho es una excelente opción (con almacén de columnas) si no está demasiado preocupado por el crecimiento de los datos verdaderamente grandes.

1 votos

Thomas Browne - Estoy investigando su respuesta en profundidad. Gracias. ¿Es esta la función/extensión de la tienda de columnas pg a la que se refería? citusdata.com/blog/2014/04/03/columnar-store-for-analytics

5voto

omencat Puntos 151

En lo que respecta al almacenamiento, transmito las actualizaciones en tiempo real de los contratos cotizados en bolsa (directos + diferenciales de calendario cotizados en bolsa) a InfluxDB . Es una base de datos de series temporales, orientada principalmente a las operaciones de TI para almacenar datos de registro, pero funciona bien con datos financieros homogéneos.

Para las tiras de opciones, debido a la gran cantidad de datos generados por día, utilizo TeaFiles . Las ventajas de usar archivos de té son que el tamaño de los archivos es pequeño y los tiempos de carga son rápidos. Para cada archivo .tea asigno la siguiente estrategia: [ContractSymbol]_[Strike]_[CallOrPut]_[Date].tea . Los archivos se guardan en el almacenamiento Azure BLOB. Los benchmarks de lectura son buenos; ~25ms para leer un archivo con 300k entradas desde un cargador C#.

0 votos

En algún momento consideré utilizar InfluxDB, pero los requisitos de las especificaciones del servidor me asustaron. Me gustaría conocer tu experiencia con ese sistema en producción.

2 votos

He publicado la respuesta utilizando datos JSON más arriba. No había visto TeaFiles antes de esto. Parece que realizan la misma función que mis datos JSON. Estoy interesado en ver cómo los dos realizan lado a lado. Gracias por indicarme esta dirección y te he dado un upvote por ello.

0 votos

Claro, los archivos tea no cumplen la misma función que JSON. Los archivos tea son archivos binarios con cabeceras diseñados para series temporales homogéneas. Mientras que JSON está diseñado para objetos de atributo=valor en archivos de texto legibles por humanos. Si no está capturando actualizaciones intradía de alta frecuencia, entonces los archivos tea pueden no ser la mejor solución para usted. Pero si se encuentra con que tiene que cargar millones/decenas de millones de series temporales para cada consulta, entonces debería considerarse al menos una solución de almacenamiento basada en binarios. He aquí algunos métricas de rendimiento

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X