Antecedentes :
he creado una aplicación web que me gustaría poder escalar razonablemente bien. Sé que no soy Google ni Twitter, pero mi aplicación utiliza una cantidad bastante grande de datos para cada usuario y, por lo tanto, tiene requisitos de datos bastante altos. Quiero estar listo para escalar razonablemente bien sin tener que rediseñar todo más tarde.
Me considero un desarrollador de software, no un experto en bases de datos. Es por eso que estoy publicando aquí. Espero que alguien con mucha más experiencia en bases de datos pueda darme consejos.
Con un número relativamente grande de usuarios, pero nada parecido a los números de Facebook, espero tener un DB que se vea así:
Una "mesa grande":
- 250 millones de registros
- 20 columnas
- Aproximadamente 100 GB de datos
- Tiene una clave foránea indexada bigint (20)
- Tiene una columna varchar (500) string_id indexada
- Tiene una columna de "valor" int (11)
4 otras mesas:
- 10 millones de registros cada uno
- Aproximadamente 2 - 4 GB de datos cada uno
- cada una de estas tablas tiene 4 - 8 columnas
- una columna es datetime date_created
- una columna es la columna varchar (500) string_id
- se seleccionarán una o dos columnas de cada una de estas tablas en una unión
Una de estas tablas se usa para almacenar promedios: su esquema es bigint (20) id, varchar (20) string_id, datetime date_created, float average_value
Lo que quiero hacer : dos consultas relativamente caras:
Calcular nuevos valores promedio:
- Con una clave externa, seleccione hasta varios millones de registros separados de la tabla grande.
- Calcule un nuevo promedio, agrupando por string_id.
- Insertar resultados en la tabla de promedios.
- Tal como se construye actualmente, esta consulta usa dos combinaciones.
Cree registros de solo lectura no normalizados para servir a los usuarios:
- Use una clave externa para seleccionar entre 1,000 y 40,000 registros de la tabla grande.
- Únase a cada una de las otras cuatro tablas en el registro más nuevo con la columna de id. De cadena.
- Inserte los resultados en una tabla desnormalizada.
- Estos registros son para uso del front-end para mostrar información a los usuarios.
- Tal como se construye actualmente, esta consulta usa cuatro combinaciones.
Planeo ejecutar cada una de estas costosas consultas en una base de datos de fondo de lote que empujará sus resultados a un servidor de base de datos front-end en tiempo real que maneja las solicitudes de los usuarios. Estas consultas se ejecutarán a intervalos regulares. No he decidido con qué frecuencia. La consulta promedio podría hacerse quizás una vez al día. La consulta de normalización deberá ser más frecuente, tal vez cada pocos minutos.
Cada una de estas consultas se ejecuta actualmente en unos pocos segundos en MySQL en una máquina de muy bajo nivel con un conjunto de datos con 100K registros en la "tabla grande". Me preocupan tanto mi capacidad de escalar como los costos de escalar.
Preguntas :
- ¿Este enfoque parece sólido? ¿Hay algo obviamente malo desde una perspectiva general?
- ¿Es un RDBMS la herramienta adecuada, o debería mirar otras soluciones de "big data" como algo de la familia Hadoop? Mi inclinación es usar un RDBMS porque los datos están estructurados y encajan perfectamente en el modelo relacional. Sin embargo, en cierto momento, entiendo que es posible que ya no pueda usar un RDBMS. ¿Es eso cierto? ¿Cuándo sería necesario este cambio?
- ¿Funcionará? ¿Se pueden ejecutar estas consultas en un tiempo razonable? Puedo esperar quizás horas para la consulta n. ° 1, pero la consulta n. ° 2 debería finalizar en minutos.
- ¿Qué debo considerar desde una perspectiva de hardware? ¿Cuáles son mis cuellos de botella de RAM y CPU? Asumo que mantener índices en RAM es importante. ¿Hay algo más que deba considerar?
- En algún momento, probablemente tendré que particionar mis datos y usar múltiples servidores. ¿Parece que mi caso de uso ya está en esa categoría, o podré escalar una sola máquina verticalmente por un tiempo? ¿Funcionará esto con 10 veces los datos? 100x?