El mejor almacén de datos para miles de millones de filas


86

Necesito poder almacenar pequeños bits de datos (aproximadamente 50-75 bytes) para miles de millones de registros (~ 3 mil millones / mes durante un año).

El único requisito son inserciones y búsquedas rápidas para todos los registros con el mismo GUID y la capacidad de acceder al almacén de datos desde .net.

Soy un tipo de servidor SQL y creo que SQL Server puede hacer esto, pero con todo lo que se habla sobre BigTable, CouchDB y otras soluciones nosql, suena cada vez más como una alternativa a un RDBS tradicional que puede ser mejor debido a las optimizaciones para consultas distribuidas y escalado. Probé cassandra y las bibliotecas .net no se compilan actualmente o están todas sujetas a cambios (junto con la propia cassandra).

He buscado en muchos almacenes de datos nosql disponibles, pero no puedo encontrar uno que satisfaga mis necesidades como una plataforma sólida lista para producción.

Si tuviera que almacenar 36 mil millones de registros pequeños y planos para que sean accesibles desde .net, ¿qué elegiría y por qué?


Sí, mis números son correctos. Actualmente tenemos esta cantidad de datos ingresando al sistema, pero los agregamos y almacenamos solo los recuentos agregados, por lo que perdemos los datos por registro y mantenemos solo sumas de datos por hora. Debido a los requisitos comerciales, queremos mantener cada registro como ocurrió originalmente y eso es 3 mil millones de filas / mes.
Jody Powlette

Ha planteado algunas buenas preguntas. Las respuestas son: 95% de tiempo de actividad es suficiente: los datos ya están retrasados ​​una cantidad variable, por lo que tendré que sincronizarlos después del hecho de todos modos, por lo que estar inactivo por un corto tiempo no es un factor decisivo. Perder inserciones o incluso miles de inserciones no es el fin del mundo. Sin embargo, perder los datos de un día sería bastante malo. La consistencia tampoco es tan importante. Básicamente, después de insertar filas de 30Mil en un día, necesito buscar todas las filas con el mismo GUID (quizás 20 filas) y estar razonablemente seguro de que las recuperaría todas.
Jody Powlette

¿Vuelca 30 millones de filas al día en trabajos por lotes programados diarios / por hora, o vienen en un flujo constante de uno en uno?
Remus Rusanu

Los datos llegan de un sitio FTP ... los archivos entran continuamente y tengo un proceso que analiza los archivos y actualmente genera los datos agregados e inserta los valores agregados (quizás 1000 filas) como una transacción. El nuevo proceso necesitará insertar cientos de miles de filas de cada archivo que llegue, probablemente usar la inserción masiva sería la forma más eficiente de hacerlo.
Jody Powlette

Eso suena como un trabajo ETL para SSIS y SQL Server. Tienen un récord mundial de ETL, con una velocidad de carga de más de 2 TB / hora: blogs.msdn.com/sqlperf/archive/2008/02/27/etl-world-record.aspx
Remus Rusanu

Respuestas:


102

Almacenar ~ 3.5TB de datos e insertar aproximadamente 1K / seg 24x7, y también realizar consultas a una velocidad no especificada, es posible con SQL Server, pero hay más preguntas:

  • ¿Qué requisito de disponibilidad tienes para esto? 99,999% de tiempo de actividad, o es suficiente el 95%?
  • ¿Qué requisito de fiabilidad tienes? ¿Falta un inserto le cuesta $ 1 millón?
  • ¿Qué requisito de recuperabilidad tienes? Si pierde un día de datos, ¿importa?
  • ¿Qué requisito de consistencia tienes? ¿Es necesario garantizar que una escritura sea visible en la siguiente lectura?

Si necesita todos estos requisitos que destaqué, la carga que propone costará millones en hardware y licencias en un sistema relacional, cualquier sistema, sin importar los trucos que intente (fragmentación, partición, etc.). Un sistema nosql, por su propia definición, no cumpliría con todos estos requisitos.

Entonces, obviamente, ya ha relajado algunos de estos requisitos. Hay una buena guía visual que compara las ofertas de nosql según el paradigma 'elegir 2 de 3' en Visual Guide to NoSQL Systems :

comparación de nosql

Después de la actualización del comentario OP

Con SQL Server, esta sería una implementación sencilla:

  • una sola clave de tabla agrupada (GUID, hora). Sí, se va a fragmentar , pero si la fragmentación afecta las lecturas anticipadas y las lecturas anticipadas solo se necesitan para escaneos de rango significativo. Dado que solo consulta por GUID y rango de fechas específicos, la fragmentación no importará mucho. Sí, es una clave ancha, por lo que las páginas que no son hojas tendrán una densidad de clave baja. Sí, dará lugar a un factor de llenado deficiente. Y sí, pueden ocurrir divisiones de página. A pesar de estos problemas, dados los requisitos, sigue siendo la mejor opción de clave agrupada.
  • particione la tabla por tiempo para que pueda implementar la eliminación eficiente de los registros caducados, a través de una ventana deslizante automática . Aumente esto con una reconstrucción de la partición de índice en línea del último mes para eliminar el factor de relleno deficiente y la fragmentación introducida por el agrupamiento GUID.
  • habilitar la compresión de página. Dado que los grupos de claves agrupados por GUID primero, todos los registros de un GUID estarán uno al lado del otro, lo que brinda a la compresión de página una buena oportunidad para implementar la compresión de diccionario.
  • necesitará una ruta de E / S rápida para el archivo de registro. Está interesado en un alto rendimiento, no en una baja latencia para que un registro se mantenga al día con 1K inserciones / seg, por lo que la eliminación es imprescindible.

El particionado y la compresión de páginas requieren cada uno de un servidor SQL de Enterprise Edition, no funcionarán en Standard Edition y ambos son muy importantes para cumplir con los requisitos.

Como nota al margen, si los registros provienen de una granja de servidores web front-end, pondría Express en cada servidor web y en lugar de INSERT en el back-end, colocaría SENDla información en el back-end, utilizando una conexión / transacción local en el Express coubicado con el servidor web. Esto le da una historia de disponibilidad mucho mejor a la solución.

Así que así es como lo haría en SQL Server. La buena noticia es que se comprenden bien los problemas que enfrentará y se conocen las soluciones. eso no significa necesariamente que sea mejor que lo que podría lograr con Cassandra, BigTable o Dynamo. Dejaré que alguien más conocedor de cosas no sql-ish argumente su caso.

Tenga en cuenta que nunca mencioné el modelo de programación, la compatibilidad con .Net y demás. Sinceramente, creo que son irrelevantes en grandes implementaciones. Hacen una gran diferencia en el proceso de desarrollo, pero una vez implementados, no importa qué tan rápido fue el desarrollo, si la sobrecarga de ORM mata el rendimiento :)


Hice un
enlace

@RemusRusanu: mirando la migración de dba.se Solo para prepararte :-) Y +1
gbn

A partir de Microsoft SQL Server 2016, la edición Enterprise ya no es necesaria para la partición de tablas, ya que la partición de tablas ahora está disponible en casi todas las ediciones de SQL Server 2016.
TChadwick

17

Contrariamente a la creencia popular, NoSQL no se trata de rendimiento, ni siquiera de escalabilidad. Se trata principalmente de minimizar el llamado desajuste de impedancia relacional de objeto, pero también se trata de la escalabilidad horizontal frente a la escalabilidad vertical más típica de un RDBMS.

Para el simple requisito de inserciones rápidas y búsquedas rápidas, casi cualquier producto de base de datos servirá. Si desea agregar datos relacionales, o uniones, o tiene alguna lógica transaccional compleja o restricciones que necesite aplicar, entonces desea una base de datos relacional. Ningún producto NoSQL se puede comparar.

Si necesita datos sin esquema, querrá optar por una base de datos orientada a documentos como MongoDB o CouchDB. El esquema flexible es el principal atractivo de estos; Personalmente, me gusta MongoDB y lo uso en algunos sistemas de informes personalizados. Lo encuentro muy útil cuando los requisitos de datos cambian constantemente.

La otra opción principal de NoSQL son las tiendas de valor clave distribuidas, como BigTable o Cassandra. Estos son especialmente útiles si desea escalar su base de datos en muchas máquinas que ejecutan hardware básico. También funcionan bien en servidores, obviamente, pero no aprovechan el hardware de gama alta, así como SQL Server u Oracle u otra base de datos diseñada para el escalado vertical , y obviamente, no son relacionales y no son buenos para hacer cumplir la normalización. o limitaciones. Además, como habrá notado, la compatibilidad con .NET tiende a ser irregular en el mejor de los casos.

Todos los productos de bases de datos relacionales admiten particiones de un tipo limitado. No son tan flexibles como BigTable u otros sistemas DKVS, no se dividen fácilmente en cientos de servidores, pero realmente no parece que eso sea lo que estás buscando. Son bastante buenos manejando recuentos de registros de miles de millones, siempre que indexe y normalice los datos correctamente, ejecute la base de datos en hardware potente (especialmente SSD si puede pagarlos) y particione en 2 o 3 o 5 discos físicos si necesario.

Si cumple con los criterios anteriores, si trabaja en un entorno corporativo y tiene dinero para gastar en hardware decente y optimización de la base de datos, me quedaría con SQL Server por ahora. Si está pellizcando centavos y necesita ejecutar esto en hardware de computación en la nube Amazon EC2 de gama baja, probablemente desee optar por Cassandra o Voldemort en su lugar (suponiendo que pueda trabajar con .NET).


11

Muy pocas personas trabajan en el tamaño del conjunto de filas de miles de millones, y la mayoría de las veces que veo una solicitud como esta en el desbordamiento de la pila, los datos no están cerca del tamaño que se informa.

36 mil millones, 3 mil millones por mes, eso es aproximadamente 100 millones por día, 4.16 millones por hora, ~ 70k filas por minuto, 1.1k filas por segundo ingresando al sistema, de manera sostenida durante 12 meses, asumiendo que no hay tiempo de inactividad.

Esas cifras no son imposibles por un amplio margen, he hecho sistemas más grandes, pero desea verificar que realmente sean las cantidades a las que se refiere: muy pocas aplicaciones realmente tienen esta cantidad.

En términos de almacenamiento / recuperación, un aspecto bastante crítico que no ha mencionado es el envejecimiento de los datos más antiguos; la eliminación no es gratuita.

La tecnología normal que se observa es la partición, sin embargo, la búsqueda / recuperación basada en GUID daría como resultado un rendimiento deficiente, suponiendo que tenga que obtener todos los valores coincidentes durante todo el período de 12 meses. Puede colocar índices agrupados en la columna GUID para que sus datos asociados se agrupen para lectura / escritura, pero a esas cantidades y velocidad de inserción, la fragmentación será demasiado alta para admitirla y caerá al suelo.

También sugeriría que necesitará un presupuesto de hardware muy decente si se trata de una aplicación seria con velocidades de respuesta de tipo OLTP, es decir, según algunas suposiciones aproximadas, asumiendo muy pocos gastos generales de indexación, alrededor de 2.7TB de datos.

En el campo de SQL Server, lo único que podría querer ver es la nueva edición de almacenamiento de datos paralelo (madison), que está diseñada más para fragmentar datos y ejecutar consultas paralelas en ellos para proporcionar alta velocidad contra grandes datamarts.


3
En bioinformática, los conjuntos de datos de miles de millones de filas no son infrecuentes. Pero con frecuencia se tratan de forma puramente continua desde archivos planos.
Erik Garrison

3
@Erik: para el procesamiento de transmisiones (es decir, solo es necesario detectar ciertas condiciones, pero no es necesario almacenar los datos para consultas posteriores) algo como StreamInsight es mejor que cualquier base de datos microsoft.com/sqlserver/2008/en/us/r2 -complex-event.aspx
Remus Rusanu

2

"Necesito poder almacenar pequeños bits de datos (aproximadamente 50-75 bytes) para miles de millones de registros (~ 3 mil millones / mes durante un año).

El único requisito son inserciones y búsquedas rápidas para todos los registros con el mismo GUID y la capacidad de acceder al almacén de datos desde .net ".

Puedo decirles por experiencia que esto es posible en SQL Server, porque lo hice a principios de 2009 ... y sigue funcionando hasta el día de hoy y es bastante rápido.

La tabla se particionó en 256 particiones, tenga en cuenta que esta era la versión de SQL 2005 ... e hicimos exactamente lo que está diciendo, y eso es almacenar bits de información por GUID y recuperar por GUID rápidamente.

Cuando me fui, teníamos alrededor de 2 a 3 mil millones de registros, y la recuperación de datos todavía era bastante buena (1 a 2 segundos si pasaba por la interfaz de usuario, o menos si estaba en RDBMS) a pesar de que la política de retención de datos estaba a punto de ser instanciada.

Entonces, para resumir, tomé el octavo carácter (es decir, en algún lugar en el medio) de la cadena GUID y SHA1 lo hash y lo lancé como un pequeño int (0-255) y lo almacené en la partición apropiada y usé la misma llamada de función al obtener los datos de vuelta.

envíame un ping si necesitas más información ...


2

El siguiente artículo analiza la importación y el uso de una tabla de 16 mil millones de filas en Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

Del artículo:

Aquí hay algunos consejos destilados de mi experiencia:

  • Cuantos más datos tenga en una tabla con un índice agrupado definido, más lento será importar registros sin clasificar en ella. En algún momento, se vuelve demasiado lento para ser práctico.
  • Si desea exportar su tabla al archivo más pequeño posible, hágalo en formato nativo. Esto funciona mejor con tablas que contienen principalmente columnas numéricas porque están representadas de manera más compacta en campos binarios que en datos de caracteres. Si todos tus datos son alfanuméricos, no ganarás mucho exportándolos en formato nativo. No permitir valores nulos en los campos numéricos puede compactar aún más los datos. Si permite que un campo sea anulable, la representación binaria del campo contendrá un prefijo de 1 byte que indica cuántos bytes de datos seguirán.
  • No puede usar BCP para más de 2,147,483,647 registros porque la variable de contador BCP es un entero de 4 bytes. No pude encontrar ninguna referencia a esto en MSDN o en Internet. Si su mesa consta de
    más de 2.147.483.647 registros, tendrá que exportarla en trozos
    o escribir su propia rutina de exportación.
  • La definición de un índice agrupado en una tabla rellenada previamente ocupa mucho espacio en disco. En mi prueba, mi registro explotó a 10 veces el original
    tamaño de la tabla antes de completarlo.
  • Cuando importe una gran cantidad de registros mediante la instrucción BULK INSERT, incluya el parámetro BATCHSIZE y especifique cuántos
    registros se comprometerán a la vez. Si no incluye este parámetro,
    todo el archivo se importa como una sola transacción, que
    requiere mucho espacio de registro.
  • La forma más rápida de introducir datos en una tabla con un índice agrupado es ordenar previamente los datos primero. Luego puede importarlo usando la
    instrucción BULK INSERT con el parámetro ORDER.

1

Hay un hecho inusual que parece pasarse por alto.

" Básicamente, después de insertar filas de 30 mililitros en un día, necesito buscar todas las filas con el mismo GUID (tal vez 20 filas) y estar razonablemente seguro de que las recuperaría todas "

Al necesitar solo 20 columnas, un índice no agrupado en el GUID funcionará bien. Puede agrupar en otra columna para la dispersión de datos entre particiones.

Tengo una pregunta sobre la inserción de datos: ¿Cómo se inserta?

  • ¿Es esta una inserción masiva en un horario determinado (por minuto, por hora, etc.)?
  • ¿De qué fuente se extraen estos datos (archivos planos, OLTP, etc.)?

Creo que deben responderse para ayudar a comprender un lado de la ecuación.


1

Amazon Redshift es un gran servicio. No estaba disponible cuando la pregunta se publicó originalmente en 2010, pero ahora es un actor importante en 2017. Es una base de datos basada en columnas, bifurcada de Postgres, por lo que las bibliotecas de conectores SQL y Postgres estándar funcionarán con ella.

Se utiliza mejor para fines de informes, especialmente para la agregación. Los datos de una sola tabla se almacenan en diferentes servidores en la nube de Amazon, distribuidos por las claves de tabla definidas, por lo que confía en la potencia de la CPU distribuida.

Por lo tanto, los SELECT y especialmente los SELECT agregados son ultrarrápidos. La carga de datos grandes debe realizarse preferiblemente con el comando COPY de los archivos csv de Amazon S3. Los inconvenientes son que los DELETE y UPDATE son más lentos de lo habitual, pero es por eso que Redshift no es principalmente una base de datos transnacional, sino más bien una plataforma de almacenamiento de datos.


0

Puede intentar usar Cassandra o HBase, aunque necesitará leer sobre cómo diseñar las familias de columnas según su caso de uso. Cassandra proporciona su propio lenguaje de consulta, pero debe utilizar las API de Java de HBase para acceder a los datos directamente. Si necesita usar Hbase, le recomiendo consultar los datos con Apache Drill de Map-R, que es un proyecto de código abierto. El lenguaje de consulta de Drill es compatible con SQL (las palabras clave en drill tienen el mismo significado que tendrían en SQL).


0

Con tantos registros por año, eventualmente se quedará sin espacio. ¿Por qué no el almacenamiento del sistema de archivos como xfs, que admite archivos 2 ^ 64 y utiliza cajas más pequeñas? Independientemente de lo sofisticada que la gente quiera obtener o la cantidad de dinero que uno terminaría gastando en obtener un sistema con cualquier base de datos SQL NoSQL ... cualquiera que sea, estos registros suelen ser realizados por compañías eléctricas y estaciones / proveedores meteorológicos como el ministerio de medio ambiente que controlan los más pequeños. estaciones en todo el país. Si está haciendo algo como almacenar presión ... temperatura ... velocidad del viento ... humedad, etc. y guid es la ubicación ... aún puede dividir los datos por año / mes / día / hora. Suponiendo que almacena 4 años de datos por disco duro. Luego puede ejecutarlo en un Nas más pequeño con espejo donde también proporcionaría mejores velocidades de lectura y tendría múltiples puntos de montaje. basado en el año en que fue creado. Simplemente puede crear una interfaz web para las búsquedas. Así que descargue la ubicación1 / 2001/06/01 // temperatura y ubicación1 / 2002/06/01 // temperature solo volcaría el contenido de la temperatura por hora para el primer día de verano en esos 2 años (24 h * 2) 48 archivos pequeños en lugar de buscar en una base de datos con miles de millones de registros y posiblemente millones gastados. Una forma sencilla de ver las cosas ... 1.500 millones de sitios web en el mundo con Dios sabe cuántas páginas cada uno. Si una empresa como Google tuviera que gastar millones por cada 3.000 millones de búsquedas para pagar supercomputadoras, estarían en quiebra. En cambio, tienen la factura de la luz ... un par de millones de computadoras basura. Y la indexación de cafeína ... preparada para el futuro ... sigue agregando más. Y sí, donde la indexación que se ejecuta desde SQL tiene sentido, entonces es genial Construir supercomputadoras para tareas de mierda con cosas fijas como el clima ... estadísticas y así sucesivamente para que los técnicos puedan presumir de que sus sistemas procesan xtb en x segundos ... gastado en otro lugar ..


-2

Almacenar registros en archivos binarios simples, un archivo por GUID, no sería más rápido que eso.


5
¿Realmente espera que esto funcione bien?
ChaosPandion

3
Sí, crear miles de millones de archivos en un sistema de archivos puede ser devastador para algunos sistemas de archivos. Cometí el error de hacer algo como esto, pero con solo 1 millón y prácticamente derribé el sistema tratando de abrir un shell en una de esas carpetas. Además, a menos que esté buscando en función de una guía, ¿cómo se supone que funciona el mecanismo de consulta?
Rob Goodwin

Es difícil adivinar cómo funcionaría esto sin saber cuántos GUID únicos se esperan :) Pero no hay nada más simple que escribir en archivos planos. Y las inserciones rápidas junto con la búsqueda por GUID era el único requisito.
Thomas Kjørnes

Puede funcionar, pero debe limitar la cantidad de archivos por carpeta. Tienes que generar una nueva carpeta por n archivos. Puede usar una subcadena del guid como nombre de carpeta.
TTT

1
sí, hay un límite en el número de inodos para muchos sistemas de archivos y recuerdo haber llegado a ese límite en el sistema de archivos predeterminado de redhat ... el límite era de alrededor de 1,000,000 de archivos más o menos.
Dean Hiller

-3

Puede usar MongoDB y usar el guid como clave de fragmentación, esto significa que puede distribuir sus datos en varias máquinas, pero los datos que desea seleccionar están solo en una máquina porque los selecciona mediante la clave de fragmentación.

La fragmentación en MongoDb aún no está lista para producción.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.