2009-11-04 20 views
8

Muchas de las aplicaciones de LOB que ofrecemos a nuestros clientes son de naturaleza comercial/promocional (sorteos, registro de eventos, etc.). La mayoría de las aplicaciones, aunque son muy simples, son muy exigentes en la base de datos. Imagine un sitio tipo "registro" como respaldo de un comercial que se emite durante la superbowl, por ejemplo (sí, hemos tenido varios).Diseño de base de datos para la aplicación web de escritura pesada

Aunque hemos mejorado la optimización de nuestro código de aplicación web, la base de datos siempre sigue siendo un problema, a pesar de que la aplicación es relativamente simple. El flujo es típicamente algo como:

  1. Leer de base de datos para detectar registro existente
  2. de escritura a la base de datos si el registro es nuevo

En muchos casos, se trata de acceder a todos los datos de nuestra aplicación necesita realizar. Sin embargo, dado que es el único propósito de la aplicación, es muy importante que este proceso simple se optimice en gran medida.

Para los fines de esta pregunta, tenemos un único servidor que ejecuta una matriz de discos raid 5 para los archivos de datos y otra matriz raid 5 para los registros. En este momento, el sistema operativo es Windows 2003 estándar de 32 bits y el servidor tiene 4 GB de memoria. Algunas aplicaciones usan el estándar SQL 2005 mientras que otras usan MySQL 5.1. Soy muy consciente que ciertas optimizaciones de SO y hardware son posibles aquí, pero estoy tratando de abordar mis necesidades desde el lado del software primero. El perfil extenso nos ha enseñado que disco IO es generalmente el principal cuello de botella.

Habiendo dicho todo eso, y sabiendo que el almacenamiento en caché no ayudará mucho ya que la mayoría de las lecturas son únicas y devuelven muy pocos datos (a menudo solo un poco indicando si un registro existe o no), estoy considerando dar un salto el ámbito de las bases de datos en memoria como una especie de capa de caché de escritura en la base de datos real. Esto parece una buena opción dado que la mayoría de nuestro tráfico de alto volumen es de naturaleza esporádica y no se mantiene durante varias horas. Además, la pérdida potencial de unos pocos minutos de datos debido a un bloqueo del servidor sería aceptable en la mayoría de los casos.

En la forma más simple, me gustaría modificar una aplicación típica de inscripción para hacer lo siguiente:

  1. Consulta el disco DB y DB memoria para registros existentes
  2. si no tiene, escribir datos en la memoria DB y volver
  3. DB memoria periódicamente descarga a disco DB

Mi pregunta es: ¿cuáles son mis opciones para este intermedio mí en base de datos mory? He experimentado con tablas hash en memoria, tablas de datos, etc., pero estoy buscando otras opciones o incluso sugerencias para un enfoque completamente diferente.

+0

Proporcione un orden de magnitud para el número y tamaño de registros, tal vez diferenciando el conteo antes de una campaña en particular, y después (es decir, incluyendo una idea aproximada del recuento de registros adicionales durante la campaña) – mjv

+0

En una aplicación típica respaldada por conductores de alto tráfico como anuncios de televisión o anuncios de radio, podríamos ver más de ~ 200,000 intentos de registro en un período de 15-30 minutos después del anuncio. La mayor parte de esto generalmente se produce dentro de un período de 3-5 minutos inmediatamente después del spot, de ahí el problema de contención. El volumen no es el problema, es la concurrencia el problema. Nuestra base de datos más grande para una sola aplicación a corto plazo de esta naturaleza se acercó a 10 millones de registros en 2 meses, y la mayor parte del tráfico proviene de anuncios televisivos y campañas de correo electrónico. – Chris

+2

Otra opción sería encapsular la lógica UPSERT en un procedimiento almacenado, lo que le ahorraría un viaje de la base de datos (y gastos indirectos relacionados). –

Respuesta

4

Acepta la nueva noción "Todo es un mensaje, la base de datos es la copia de seguridad". Cuando tenga algo que almacenar, cree un mensaje y envíelo a una blackbox (como eJabberD) ​​usando XMPP. Deje que Blackbox actualice su base de datos según su propio cronograma. Así es como funcionan sitios como Twitter.

Tome un vistazo a esta presentación de diapositivas: http://www.slideshare.net/kellan/beyond-rest

1

SQLite tiene un modo de operación in memory. Esto funcionaría si tiene un proceso de servidor persistente detrás del controlador de aciertos de su página.

De lo contrario, los archivos de base de datos comunes pueden ser engañados para escribir sus archivos en un sistema de archivos de memoria como tmpfs.

6

Si no necesita saber si hay un registro existente en tiempo real (es decires importante que el registro entre, pero no es necesario que informe si era nuevo o existente para el usuario), puede estructurar su base de datos de manera que permita tiempos de escritura extremadamente rápidos sin la necesidad de un base de datos de memoria, que conlleva muchos problemas potenciales si los servidores se caen o los procesos de trabajo se reinician.

Cree dos tablas en su base de datos para cada tabla que estén involucradas con este flujo de escritura pesada. Una tabla debe ser su tabla "en vivo" y debe estar optimizada para escritura tanto como sea posible (es decir, sin índices y nunca se lee, excepto cuando se mueve a la tabla de lectura). Su otra tabla debe ser su tabla de lectura optimizada, indexada según corresponda para cualquier consideración de informes, etc.

Cuando escriba en su tabla activa, ignore todo lo relacionado con si un registro es nuevo o existente, o cualquier cosa más allá de solo poner esos datos en la mesa lo más rápido posible y salir de la base de datos. Configure un trabajo programado que mueva los registros de la tabla activa a la tabla de lectura optimizada, y preocúpese de hacer coincidir allí los registros existentes. Idealmente, esto se haría durante las horas no pico, pero de lo contrario es posible que desee considerar una tercera tabla de etapas para que no haya contención en la tabla activa en ningún momento.

+0

¿Qué pasa si los datos de la tabla en vivo deberían estar disponibles para su lectura relativly rápida? (es decir, no puedo esperar hasta que el trabajo programado transfiera datos nuevos a la mesa de lectura) – kilonet

0

No conozco las bases de datos que menciona, pero si el contenido de la base de datos (o al menos la tabla importante) cabe en la memoria, oracle puede fijarlo en la memoria caché, por lo que básicamente se comporta como un en la base de datos de memoria

También verificaría la configuración del nivel de aislamiento de su base de datos. Si puede relajarlos, tal vez pueda reducir el bloqueo.

Considere la posibilidad de eliminar restricciones únicas o deshabilitarlas para las horas punta.

1

En mi opinión, debe poder acomodar su carga de trabajo con un RDBMS que tenga un caché de un tamaño de usuario. Veo en el orden de 10000 registros indexados por segundo con un sencillo RDBMS invocable en C++ con hardware ordinario. Eso incluye commit to disk. Además, dado que puede estar viendo solo un campo pequeño en un registro, busque una base de datos orientada a columnas, una que almacene datos en la columna. No tiene sentido leer en una fila completa si solo está interesado en un campo.

1

La optimización de su esquema de base para las escrituras en lugar de lee, como se ha mencionado por muchos otros, es su primer punto de escala, aunque supongo que has estado allí ya

Antes de investigar las bases de datos en memoria, es posible que desee echar un vistazo a algunos de los ORM que están disponibles, particularmente NHibernate.

NHibernate mantiene algunos datos en la memoria y le permitirá controlar la actualización de los datos de la memoria y sincronizarlos con la base de datos.

Puede que valga la pena echarle un vistazo.

2

No relacionado con la programación, pero definitivamente ayudaría: Obtenga algunos de los discos de estado sólido más nuevos.

Sí, son caros para el tamaño, pero dado que el disco IO es el cuello de botella, cambiar las unidades de disco duro actuales por algunas unidades SSD mejoraría en gran medida el rendimiento.

1

Editar: Concentrar estrictamente en el disco E/S ...

  1. Desgarra tantos índices innecesarios como sea posible. Los índices no se obtienen de forma gratuita: espacio O tiempo.
  2. Expulse cualquier activador o restricción especial que no necesite.
  3. Elimine cualquier relación de entidad/operadores de integridad relacional que no sean absolutamente críticos.
  4. Si su DBMS actual lo admite, separe las tablas de transacciones en varios discos (por ejemplo, round-robin).
  5. Considerando agregar más servidores de base de datos de forma independiente uno del otro (es decir, sin replicación); para hacer esto, necesita un planificador para decidir qué servidor aceptará la transacción y un esquema/proceso separado que consolida las transacciones.

Minimizar la cantidad de lógica de la base de datos y agregar servidores lateralmente (a diferencia de la tecnología de servidor de punta) es básicamente el enfoque adoptado por ebay.

2

Aquí es una idea extraña: no utilice una base de datos para la captura inicial. Diseñe dos o tres archivos indexados a toda velocidad, cuyo formato no necesita cambiar muy a menudo. Capture los datos en esos archivos.

Escriba algún software que se active apropiadamente que copie los datos capturados en una base de datos, pero que no retrase al usuario interactivo. Marque los datos copiados para evitar copias duplicadas y para reciclar espacio en el archivo.

Ahora puede diseñar la base de datos con la idea de compartir datos entre múltiples usos, en lugar de con la idea de mantenerse al día con el proceso de captura. Después de todo, compartir datos es donde realmente brillan las bases de datos.

+0

Esta es la idea básica de cómo funciona la herramienta de seguimiento distribuido Dapper de Google. Las aplicaciones escriben en los archivos de lcoal y los coleccionistas las copian más perezosamente en BigTable. – fumanchu

Cuestiones relacionadas