¿Cómo almacenar 3 millones de registros en formato de valor clave?

10

Tenemos que almacenar información básica sobre 3 millones de productos. Actualmente, la información es un CSV de 180 mb que se actualiza trimestralmente.

Habrá alrededor de 30,000 consultas por día, pero las consultas son solo un almacén de valores clave muy simple. Solo necesitamos buscar la identificación del producto y mostrar el resto de la información (que estaría en un solo registro).

Esto es para la web, por lo que un rendimiento rápido es crítico.

¿Deberíamos usar MySQL, aunque realmente no necesitamos una base de datos relacional? ¿Deberíamos generar 3 millones de archivos html estáticos cada trimestre? ¿Deberíamos almacenar un CSV de una línea para cada producto en algo como Amazon S3 o Rackspace Cloud Files? ¿Cuál es la mejor manera de hacer esto?

Phil
fuente

Respuestas:

16

Debido a que MySQL es tan ampliamente compatible y esto es realmente algo muy trivial, sugeriría ir con él. A menos que el servidor tenga al menos unos pocos GB de memoria, sugeriría seguir con MySQL en lugar de usar un sistema en memoria.

Una vez que comience a colocar sus datos en una base de datos, ya sea MySQL u otra cosa, es muy probable que encuentre más usos para ellos. En este momento solo está hablando de pares de valores clave, pero el resto de los datos relacionados con sus productos deben almacenarse en algún lugar. Si eso no está en una base de datos, no puedo imaginar que el almacenamiento de datos sea muy eficiente.

Hagas lo que hagas, no crees esos tres millones de archivos. Hemos visto varias preguntas aquí que ya son el resultado de los problemas que crean tantos archivos.

John Gardeniers
fuente
13

Puede utilizar el tipo de valor clave dedicado de la base de datos NoSQL que está optimizada para este tipo de tareas. Mira esto:

  • Redis : Redis es un almacén de clave-valor avanzado de código abierto. A menudo se lo conoce como un servidor de estructura de datos ya que las claves pueden contener cadenas, hashes, listas, conjuntos y conjuntos ordenados.
  • MemcacheDB : MemcacheDB es un sistema de almacenamiento de valor clave distribuido diseñado para persistente.
  • otros (una de esas listas se puede encontrar aquí: http://nosql-database.org/ )

Por supuesto, puede usar MySQL o cualquier otra base de datos relacional, pero las soluciones especialmente diseñadas para el tipo de datos de valor clave se supone que son mejores (de lo contrario, ¿cuál es el punto de diseñarlas en primer lugar, excepto posiblemente el hecho de que será mucho más pequeño? (en términos de RAM y HDD) solución).

LazyOne
fuente
Podríamos usar Redis, pero ¿crees que esto funcionaría en un P4 con 2 gigas de RAM?
Phil
@Phil Teniendo en cuenta que su archivo CSV es de alrededor de 180 MB, debería estar bien. Aunque lo usamos en un proyecto (solo una vez hasta ahora) con alrededor de 200K registros y el servidor tenía 8GB de RAM, por lo que es difícil para mí comparar.
LazyOne
6

Y ahora para algo completamente diferente:

Dado:

  • Productos de 180 MB / 3 M = 62 bytes / producto en promedio.
  • 30,000 consultas por día = 0.34 consultas por segundo
  • Actualización trimestral = datos esencialmente estáticos

Solución fuera de la caja:

Volcar cada producto como un registro de recursos TXT y almacenarlo en el DNS, por ejemplo:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

Beneficios:

  • extremadamente confiable y confiable (ya depende de ello todos los días)
  • se puede construir en casi cualquier plataforma
  • prácticamente todos los idiomas tienen soporte para consultas DNS de una forma u otra
  • Los servidores de código abierto y comerciales admiten diferentes tipos de bases de datos de fondo
  • se puede replicar trivialmente (solo especifique varios servidores de nombres)
  • maneja actualizaciones atómicas, incluso cuando se replica en una docena de servidores
  • se puede firmar criptográficamente para garantizar la integridad de los datos
  • puede manejar órdenes de magnitud con tasas de consulta por segundo más altas (10,000 consultas por segundo se manejan fácilmente con hardware básico)

Razones por las cuales esta podría ser una mala idea:

  • necesita buscar los datos (DNS es puramente búsqueda de clave / valor)
  • necesita ocultar los datos (DNS no tiene confidencialidad)
Theobroma Cacao
fuente
1
Si pudiera dar un punto de bonificación por originalidad, esto obtendría mi voto. Sin embargo, no diría que el DNS es confiable, ya que en una red doméstica típica parece mágico si funciona y una maldición si no funciona.
Martin Vilcans
1
Estoy intrigado. Realmente me gusta mucho esta idea, pero para mí, iría con algo un poco más probado / probado como CouchDB
Tom O'Connor el
¿Has estado viendo algo de Monty Python?
Mark Henderson el
Presumiblemente esto estaría dentro de una red empresarial. La fiabilidad del DNS se convierte en un problema cuando los paquetes tienen que enfrentarse a la naturaleza de Internet. Dado que, de manera predeterminada, DNS usa UDP, debe confiar en la política de retransmisión del solucionador DNS si se cae un paquete. Dentro de una red empresarial, las posibilidades de obtener una pérdida de paquetes lo suficientemente significativa son (probablemente) insignificantes. Y siempre puede forzar a DNS a usar TCP (aunque con un impacto negativo en el rendimiento, que no se considera significativo en este caso). Y le garantizo que el DNS obtiene más búsquedas que todas las instalaciones de CouchDB combinadas :-).
Theobroma Cacao
Capitán Hindsight aquí. Una palabra: blockchain.
datashaman
4

MySQL con MyISAM y algunos buenos índices suenan perfectos para esto. Por supuesto, hay muchas otras opciones, pero MySQL es ampliamente compatible (si no universalmente) en cualquier servidor web comercial. Dependiendo de la velocidad que requiera, también vale la pena mirar memcached , pero sin conocer el tamaño de cada par clave / valor, almacenar 3 millones de ellos en la memoria podría ser una idea aún peor que un archivo CSV de 180Mb (oh, espera, es un archivo CSV de 180 Mb, por lo que sabemos qué tan grandes son. Deben ser pares bastante pequeños, por lo que memcached podría ser aún mejor).

Usted no quiere 3 millones de archivos HTML estáticas, que hará daño a su sistema de archivos mal. Un CSV de una línea, incluso en S3, tendrá el mismo problema. Nadie quiere 3 millones de archivos en una carpeta.

Mark Henderson
fuente
Son pares bastante pequeños ... son datos muy básicos como precio, fecha de fabricación, número de almacén, etc. Menos de 10 columnas. ¿Entonces crees que MySQL es el camino a seguir? El servidor en el que se ejecutará es un P4 con 2 gigas de RAM. ¿Creo que debería estar bien?
Phil
@Phil: So you think MySQL is the way to go, really?no, en realidad no, pero es muy flexible y, como mencioné, es compatible de manera casi universal. Sin embargo, LazyOne ha publicado algunas buenas alternativas arriba. No podía recordar el término NoSQL, pero estaba flotando en mi cerebro en alguna parte
Mark Henderson
4

Podrías usar la base de datos Berkeley que hace exactamente este tipo de cosas, incluso si no ha estado de moda desde los albores de Perl5. Berkeley solo admite pares de valores clave, y vincula todo el db a un hash y accede a él como tal.

El uso de Berkeley está bien detallado en muchas de las referencias antiguas de Perl que se encuentran en su estante o pruebe el Perldoc para el módulo BerkeleyDB CPAN . En general, evito usar Berkeley DB (aunque mi empleador tiene mucho código antiguo en el que juega un lugar destacado, y algunos de los DB son tan grandes como los suyos), porque no es divertido cuando sus datos se vuelven más complejos.

brainbuz
fuente
2
BDB es viejo pero muy efectivo y apropiado para esta situación.
womble
Tenga cuidado con la licencia de Berkely DB en.wikipedia.org/wiki/Sleepycat_license, ya que requiere que TODO el código fuente esté disponible, no solo la parte DB.
WolfmanJM
4

Has marcado tu pregunta como Amazon S3.

Me gustaría llamar su atención sobre uno de sus otros productos relacionados llamado Amazon SimpleDB.
Parece que el modelo de datos SimpleDB encajaría bien con su tipo de aplicación.

Esto no es un complemento, pero vale la pena mirarlo especialmente si está planeando usar los servicios en la nube de Amazon.

El modelo de datos SDB se asemeja a una hoja de cálculo.

Consulte aquí para obtener más información al respecto: http://aws.amazon.com/simpledb/ Y el modelo de datos: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

Mate
fuente
SimpleDB es caro. Dolorosamente, en muchos casos.
Tom O'Connor
1

Si bien cualquier base de datos relacional puede manejar fácilmente 180mb de datos, recomendaría MongoDB ( http://www.mongodb.org/) por encima de MySQL, Redis, MemcacheDB y otros almacenes de valores clave o bases de datos relacionales más simples. La razón es que para este tipo de problema, MongoDB es el sistema más rápido y expresivo de usar, lo que permite actualizaciones dinámicas súper rápidas sin restricciones de esquema, por lo que sus documentos pueden tener diferentes formatos si lo desea. Estuve en una presentación de guardian.co.uk el otro día y han tomado una decisión política de prohibir todas las bases de datos relacionales y usar MongoDB exclusivamente para servir sus noticias. Puede tener una idea de lo rápido que es su sitio web y cuál ha estado en línea desde 1995 (el periódico en línea más antiguo del Reino Unido). También han pasado por todo tipo de cuellos de botella en el pasado debido a las bases de datos relacionales. Para 180mb, MongoDB servirá todo desde la memoria, por lo que es probable que los tiempos de carga por debajo del ms sean el caso.

snez
fuente
0

Habrá alrededor de 30,000 consultas por día, pero las consultas son solo un almacén de valores clave muy simple. Solo necesitamos buscar la identificación del producto y mostrar el resto de la información (que estaría en un solo registro).

Dijiste que tus consultas son simples búsquedas de claves, con la búsqueda binaria necesitas 21 iteraciones en el peor de los casos, con claves hash tus consultas son aún más rápidas. Tres millones de registros son pequeños siempre que evite las uniones (u otras operaciones cartesianas de tipo de producto) y las búsquedas lineales.

Me atrevería a decir que casi cualquier cosa estaría bien. Su carga es de 30000 consultas / día significa que (suponiendo que su carga sea constante durante todo el día) tiene una sola consulta cada 20 segundos; eso no es tan malo.

Recomiendo implementar primero la tecnología con la que está más familiarizado y luego medir si este es realmente el cuello de botella del sistema.

Lie Ryan
fuente
0

La mejor manera de hacerlo realmente depende de la calidad y la naturaleza de sus datos y consultas. Para empezar, 180 MB de datos en una sola tabla para productos no es un problema, de cualquier forma que lo mire. Y 30 mil consultas por día son aún menos problemáticas. Con una base de datos configurada correctamente, cualquier escritorio antiguo puede manejar esta carga.

Otros ya han señalado sus dos opciones principales, MySQL o una base de datos noSQL.

Si tiene un cierto número de atributos que existen para cada producto individual (como fabricante, precio, número de almacén, etc.), su mejor opción es tener columnas para estos atributos y convertir sus pares clave / valor en un formato de tabla plana, con un ID de producto como clave principal para esa tabla. Esto funcionará muy bien incluso si algunas columnas solo son utilizadas por la mitad de las filas, ya que para la mayoría de los productos solo necesitará ejecutar 1 consulta para recuperar todos sus atributos. se trata de datos sobre productos, supongo que es muy probable que esta sea la estructura de sus datos.

Si los atributos varían ampliamente en presencia y tipo de datos, entonces podría ser mejor usar una base de datos noSQL, que maneja este escenario de manera más eficiente que las bases de datos SQL tradicionales.

En cuanto al rendimiento: anteriormente trabajé para una empresa de comercio electrónico, donde durante mucho tiempo el sitio web recibió datos de un servidor MySQL. Este servidor tenía 2 GB de RAM, la base de datos en total era de aprox. De 5 GB de tamaño y bajo carga superior, el servidor manejó varios miles de consultas por segundo. Sí, habíamos optimizado muchas consultas, pero definitivamente es factible.

wolfgangsz
fuente