¿Cuáles son mis opciones para almacenar y consultar enormes cantidades de datos donde se repite una gran cantidad de ellos?

StackOverflow https://stackoverflow.com/questions/416432

Pregunta

Estoy evaluando opciones para el almacenamiento eficiente de datos en Java. El conjunto de datos son valores de datos con marca de tiempo con una clave principal con nombre. por ejemplo

Name: A|B|C:D
Value: 124
TimeStamp: 01/06/2009 08:24:39,223

Podría ser un precio de las acciones en un momento dado en el tiempo, por lo que es, supongo, un patrón clásico de datos de series de tiempo. Sin embargo, realmente necesito una solución RDBMS genérica que funcione con cualquier base de datos compatible con JDBC razonable, ya que me gustaría usar Hibernate. En consecuencia, las extensiones de series de tiempo a bases de datos como Oracle no son realmente una opción, ya que me gustaría que el implementador pudiera usar su propia base de datos con capacidad JDBC / Hibernate.

El desafío aquí es simplemente el volumen masivo de datos que se pueden acumular en un corto período de tiempo. Hasta ahora, mis implementaciones se centran en la definición de periodos de acumulación y depuración periódica donde los datos en bruto se agregan en las tablas DÍA, SEMANA, MES, etc., pero la desventaja es la pérdida temprana de granularidad y el ligero inconveniente de los desfases entre períodos almacenados en diferentes agregados.

El desafío tiene opciones limitadas, ya que hay un límite absoluto en la cantidad de datos que pueden comprimirse físicamente mientras se conserva la granularidad original de los datos, y este límite se ve agravado por la directiva de usar una base de datos relacional y un JDBC genérico. uno en eso

Tomando prestado un concepto nocional de los algoritmos de compresión de datos clásicos y aprovechando el hecho de que muchos valores consecutivos para la misma clave con nombre pueden ser idénticos, me pregunto si hay alguna manera de reducir sin problemas el número de registros almacenados al combinarlos. repetir los valores en una fila lógica al mismo tiempo que se almacena un contador que indica, efectivamente, que los siguientes registros n tienen el mismo valor " ;. La implementación de eso parece bastante simple, pero la compensación es que el modelo de datos ahora es horriblemente complicado de consultar con el uso de SQL estándar, especialmente cuando se usa cualquier tipo de funciones de SQL agregadas. Esto reduce significativamente la utilidad del almacén de datos ya que solo un código personalizado complejo puede restaurar los datos a un " descomprimido " estado que resulta en una discrepancia de impedancia con cientos de herramientas que no podrán procesar estos datos correctamente.

Consideré la posibilidad de definir tipos de Hibernate personalizados que básicamente entendieran " El conjunto de datos comprimidos lo revienta y devuelve resultados de consulta con las filas sintéticas creadas dinámicamente. (La base de datos se leerá solo para todos los clientes excepto el flujo de entrada estrechamente controlado). Varias de las herramientas que tenía en mente se integrarán con Hibernate / POJOS además de JDBC sin formato (por ejemplo, JasperReports). Pero esto realmente no aborda el problema de las funciones agregadas y, probablemente, también tiene muchos otros problemas.

Así que, en parte, me resigno a tener que usar un almacén de datos más propietario [posiblemente no SQL] (se agradece cualquier sugerencia) y luego me concentro en la tarea posiblemente menos compleja de escribir un controlador pseudo JDBC al menos Facilita la integración con herramientas externas.

Escuché una referencia a algo llamado " archivo de bits empaquetado " como un mecanismo para lograr esta compresión de datos, pero no conozco ninguna base de datos que proporcione esto y lo último que quiero hacer (o puedo hacer, realmente ...) es escribir mi propia base de datos.

¿Alguna sugerencia o idea?

¿Fue útil?

Solución

Me gustaría ver una base de datos orientada a columnas . Sería genial para este tipo de aplicación

Otros consejos

Hibernar (o cualquier solución JPA) es la herramienta incorrecta para este trabajo.

JPA / Hibernate no es una solución liviana. En aplicaciones de alto volumen, la sobrecarga no solo es significativa sino prohibitiva. Realmente necesitas buscar en soluciones de grilla y cluster . No repetiré la descripción general de las diversas tecnologías aquí.

Tengo mucha experiencia en sistemas de información de mercados financieros. Algunas de las cosas que dijiste me quedaron:

  • Tienes muchos datos en bruto;
  • Desea aplicar varias agregaciones a esos datos (por ejemplo, resúmenes diarios abiertos / altos / bajos / cerrados);
  • La alta disponibilidad es probablemente un problema (siempre lo es en este tipo de sistemas); y
  • La baja latencia es probablemente un problema (ídem).

Ahora, para las soluciones de tipo grilla / clúster, las divido en dos categorías:

  1. Soluciones basadas en mapas como Coherence o Terracotta; y
  2. Soluciones basadas en Javaspaces como GigaSpaces.

He usado mucho Coherence y la solución Map puede ser buena, pero también puede ser problemática. Los mapas de coherencia pueden tener escuchas y puedes usar este tipo de cosas para hacer cosas como:

  • Alertas de precios de mercado (los usuarios pueden querer una notificación cuando un precio alcanza un cierto nivel);
  • Precios derivados (por ejemplo, un sistema de precios de opciones negociados en el mercado de valores querrá volver a tomar una decisión cuando un valor subyacente cambie el precio negociado por última vez);
  • Es posible que un sistema de comparación / reserva comercial quiera emparejar las notificaciones comerciales recibidas para propósitos de conciliación;
  • etc.

Todo esto se puede hacer con oyentes, pero en Coherence, por ejemplo, los oyentes tienen que ser baratos, lo que lleva a que un Mapa tenga un oyente que escriba algo en otro Mapa y esto puede encadenar por un tiempo. Además, modificar la entrada de la memoria caché puede ser problemático (aunque también existen mecanismos para solucionar ese tipo de problema; estoy hablando de situaciones como desactivar una alerta de precio de mercado para que no se active por segunda vez).

Encontré que las soluciones de cuadrícula tipo GigaSpaces son mucho más atractivas para este tipo de aplicación. La operación de lectura (o lectura destructiva) es una solución altamente elegante y escalable y puede obtener actualizaciones de cuadrícula transaccional con un rendimiento inferior al milisegundo.

Considere las dos arquitecturas clásicas de colas:

  • Solicitud / Respuesta: un mensaje incorrecto puede bloquear la cola y, si bien puede hacerlo, muchos remitentes y receptores (para escalabilidad) escalar el número de canalizaciones no siempre es sencillo; y
  • Publicación / Suscripción: esto desacopla al remitente y al receptor, pero carece de escalabilidad, ya que si tiene varios suscriptores, cada uno recibirá el mensaje (no necesariamente lo que desea, por ejemplo, un sistema de reserva).

En GigaSpaces, una lectura destructiva es como un sistema escalable de publicación-suscripción y una operación de lectura es como el modelo tradicional de publicación-suscripción. Hay una implementación de Mapa y JMS construida sobre la cuadrícula y puede hacer pedidos FIFO.

Ahora, ¿qué pasa con la persistencia que te oigo preguntar? La persistencia es una consecuencia de decidir todas las otras cosas. Para este tipo de aplicación, me gusta el Persistencia como servicio modelo (irónicamente escrito sobre Hibernate pero se aplica a cualquier cosa).

Básicamente, esto significa que sus visitas al almacén de fechas son asíncronas y funcionan bien al hacer datos de resumen. Al igual que usted puede tener un servicio que escucha las notificaciones comerciales y persistir en las que le interesan (agregando en la memoria si es necesario). Puede hacer precios de apertura / alta / baja / cierre de esta manera.

Para datos de gran volumen, realmente no desea escribir todo en la base de datos. No sincrónicamente de todos modos. Un almacén persistente más un almacén de datos es probablemente más la ruta a la que desea ir, pero nuevamente esto depende de los requisitos, volúmenes, etc.

Es un tema complicado y solo lo he tocado. Espero que te ayude.

Probablemente le interese escuchar presentación de Michael Stonebraker en Money: Tech . Se topa con varias de las cosas que mencionas que necesitan e ilustra cómo los tres grandes elefantes (SQL Server, Oracle y DB2) nunca podrán satisfacer las necesidades de las tiendas de garrapatas (que parece que estás construyendo). Él cava más allá de las tiendas de columna, que estoy de acuerdo es la dirección correcta. Incluso analiza la compresión y la velocidad, que son ambos problemas para usted.

Aquí hay algunos enlaces más que pueden ser interesantes:

Muchos sistemas de administración de bases de datos compatibles con JDBC (por ejemplo, Oracle) proporcionan compresión en el motor de almacenamiento físico. Oracle, por ejemplo, tiene la noción de " comprimido " tabla sin sobrecarga de descompresión:

http: //www.ardentperf .com / wp-content / uploads / 2007/07 / advanced-compress-datasheet.pdf

Gracias por las respuestas.

Cletus, aprecio el esquema, pero una de las ventajas y desventajas que no puedo hacer es abandonar la flexibilidad y compatibilidad de DB con JDBC / Hibernate para permitir el uso de todas las herramientas disponibles. Además, aunque no lo dije claramente, no quiero obligar a mis usuarios a adoptar una solución comercial [posiblemente costosa]. Si tienen Database Brand X, déjalos usarlo. Si no les importa, recomendamos la marca de base de datos de código abierto Y. Básicamente, la aplicación tiene varias caras, una de ellas es un repositorio para los datos entrantes, pero otra cara es una fuente de informes y realmente don No quiero meterme en el negocio de escribir generadores de informes.

Aunque todavía no lo he probado, todavía estoy muy impresionado con LucidDB . Es una base de datos orientada a columnas y proporciona un buen rendimiento de consulta y una compresión de datos aparentemente buena. Tiene un controlador JDBC, aunque no hay dialecto de Hibernate para él todavía, por lo que puedo decir. También admite transformaciones definidas por el usuario que, en resumen, creo que me permitirán implementar sin problemas mi idea de comprimir valores repetidos y consecutivos en una "fila", pero reventarlos en múltiples "sintéticos" filas en el momento de la consulta, todo hecho de manera invisible para el llamador de la consulta. Por último, es compatible con esta característica ingeniosa de tablas externas donde otras tablas de bases de datos compatibles con JDBC pueden ser puestas de frente en LucidDB. Creo que esto puede ser invaluable para proporcionar algún nivel de soporte para otras bases de datos.

Gracias por el puntero, Javaman. Me ubicó en LucidDB.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top