¿Qué almacén de datos es mejor para mi escenario?

10

Estoy trabajando en una aplicación que involucra una ejecución muy alta de consultas de actualización / selección en la base de datos.

Tengo una tabla base (A) que tendrá alrededor de 500 registros para una entidad por un día. Y para cada usuario en el sistema, se crea una variación de esta entidad basada en algunas de las preferencias del usuario y se almacenan en otra tabla (B). Esto lo realiza un trabajo cron que se ejecuta a la medianoche todos los días.

Entonces, si hay 10,000 usuarios y 500 registros en la tabla A, habrá 5 millones de registros en la tabla B para ese día. Siempre guardo los datos de un día en estas tablas y a medianoche guardo los datos históricos en HBase. Esta configuración funciona bien y no tengo problemas de rendimiento hasta ahora.

Últimamente ha habido algún cambio en los requisitos comerciales y ahora algunos atributos en la tabla base A (para 15-20 registros) cambiarán cada 20 segundos y en función de eso tengo que volver a calcular algunos valores para todos esos registros de variación en la tabla B para todos los usuarios. A pesar de que solo cambian 20 registros maestros, necesito volver a calcular y actualizar 200,000 registros de usuarios, lo que lleva más de 20 segundos y, para entonces, la próxima actualización se produce finalmente y todas las consultas de Select se ponen en cola. Recibo alrededor de 3 solicitudes de obtención / 5 segundos de usuarios en línea, lo que resulta en 6-9 consultas de selección. Para responder a una solicitud de API, siempre uso los campos de la tabla B.

Puedo comprar más potencia de procesamiento y resolver esta situación, pero estoy interesado en tener un sistema a escala adecuada que pueda manejar incluso un millón de usuarios.

¿Alguien aquí puede sugerir una mejor alternativa? ¿Nosql + base de datos relacional me ayuda aquí? ¿Existen plataformas / almacenes de datos que me permitan actualizar los datos con frecuencia sin bloqueo y, al mismo tiempo, me den la flexibilidad de ejecutar consultas seleccionadas en varios campos de una entidad?

Tetas
fuente
¿Realmente necesitas almacenar todos esos datos? Esto suena de alguna manera como si fuera mejor calcularlo a pedido. Si puede calcular 200k registros en un poco más de 20 segundos, debería ser posible calcular esos 20 registros * 3 usuarios = 60 registros en muy poco tiempo. ¿Posiblemente podría mirar qué usuarios están en línea en cada momento y optimizar aún más? Parece que estás generando toneladas de datos que nadie usa (durante el tiempo que los datos siguen siendo válidos al menos)
thorsten müller
Generar solo para los usuarios registrados es una muy buena opción. Pensé en eso también, pero aún así no es un enfoque escalable. Mi plataforma se usará solo durante el día y, por lo tanto, durante ese tiempo, la mayoría de los usuarios estarán activos. ¿Alguna otra sugerencia amigo?
Jarras
@Jugs - Eso todavía deja la pregunta de si solo puedes calcular sobre la marcha. ¿ Tiene que actualizar los registros o su aplicación solo necesita los datos para estar allí?
Bobson el
Me temo que no puedo calcular sobre la marcha ya que la tabla de entradas B se clasifica para un usuario (5 estrellas a 1 estrella) y después de realizar estos cálculos, hacemos la clasificación nuevamente para el usuario. Todo el proceso para un usuario toma 500 ms y si lo hago sobre la marcha, afectará nuestro tiempo de respuesta API
Jugs
Estaba pensando si tiene sentido almacenar los puntajes y las clasificaciones fuera de RDBMS pueden estar en una base de datos nosql para que las declaraciones select todavía se ejecuten sin ningún inconveniente, sin embargo, a veces también necesito consultar sobre los puntajes y los rangos. Así que estoy un poco perdida en el momento en que es por eso que estoy en busca de consejo de algunos expertos como ustedes
Jarros

Respuestas:

1

Parece que la tabla Bes algún tipo de caché. Pero ese tipo de caché que reduce la productividad ...

Incluso si tiene 25 consultas por segundo , puede rechazar el uso de la tablaB y calcular la respuesta para cada solicitud.

De todos modos , si tiene 30 segundos de retraso en la actualización de 20 registros, es una falla en una arquitectura de software (me equivoco, si su DB calcula los primeros 10 ^ 100 signos de PI para cada registro).

Como sé, la base de datos relacional sin consultas SQL feas, con índices y con menos de 1 000 000 de registros funcionará perfectamente para casi todas las consultas.

Intente rechazar el uso de la tabla By agregue índices apropiados a su tabla A(la mayoría de las bases de datos modernas tienen una herramienta auxiliar). A continuación: intente optimizar la estructura de datos (tabla A) y una consulta (utilizando el analizador de consultas o con expertos en SQL) para acelerar el cálculo. Si actualiza solo 20 registros, la existencia de índices no dañará la productividad de un proceso de actualización , pero mejorará significativamente la velocidad de selección .

maxkoryukov
fuente
1

La pregunta realmente es qué sistema calcula el registro para insertar en B y el tamaño de los datos de B.

Cualquier base de datos (p. Ej. MSSQL) debería poder manejar el volumen de inserciones de las que está hablando, no hay problema, suponiendo que el objeto no sea enorme.

Las actualizaciones pueden ser un problema más difícil, pero con la indexación y el bloqueo correctos, nuevamente no debería ser un gran problema.

El 99% del tiempo cuando veo un problema como este se debe a que el registro B está siendo calculado por un proceso almacenado. Esto pone toda la carga en el servidor db

Si este es el caso, la solución es mover este código a un servicio fuera de línea que se puede llamar a través de un sistema de colas.

Por lo tanto, su mensaje de actualización A desencadenaría un proceso de trabajo que pasaría por los usuarios y crearía un mensaje de actualización B para cada usuario

Un segundo proceso de trabajo B recogería la actualización Usuario X con el evento de datos A crearía el registro B y actualizaría la base de datos

Esto se puede escalar agregando más cuadros con trabajadores de cola en ellos, para que tenga más y más poder de procesamiento detrás del cálculo, dejando su base de datos libre para concentrarse en actualizaciones y selecciones.

puede optimizar aún más separando las selecciones de las actualizaciones / inserciones. tiene una nueva base de datos que obtiene todas las solicitudes de selección como esclavo de replicación, la antigua base de datos que recibe todas las actualizaciones.

Ewan
fuente
0

Si está ejecutando en Amazon, consideraría DynamoDB. Está basado en memoria flash. Aquí hay un enlace: https://aws.amazon.com/dynamodb/ .

¿Qué tipo de RDBMS estás usando? Es posible que pueda aumentar el rendimiento utilizando un UDF o un campo calculado en una vista. ¿Está ejecutando el cálculo en la base de datos a través de una única consulta de actualización, o selecciona los datos de la base de datos, ejecuta los cálculos en otro proceso y luego los carga nuevamente?

Oracle está configurado de manera predeterminada para usar la ejecución en modo de instantánea, lo que significa que las filas no están bloqueadas durante la actualización y las selecciones simultáneas obtienen el valor original. SQL Server está configurado de manera predeterminada con concurrencia pesimista, por lo que las selecciones simultáneas se bloquearán hasta que se complete la actualización. Algunas versiones de SQL Server se pueden poner en modo de instantánea, sin embargo, aumenta considerablemente el estrés en la tabla temporal.

¿En qué tipo de entorno estás corriendo? Si se trata de un RDBMS en una instancia EC2 en Amazon, intente colocar los archivos de datos DB en el disco flash local. He visto una diferencia de orden de magnitud al mover los archivos de EBS al disco local.

Robert-Ryan.
fuente