2011-05-17 26 views
40

Bueno, esta es la cosa. Digamos que mi futuro PHP CMS necesita manejar 500,000 visitantes diariamente y necesito registrarlos todos en la base de datos MySQL (referencia, dirección IP, hora, etc.). De esta manera, necesito insertar 300-500 filas por minuto y actualizar 50 más. El principal problema es que la secuencia de comandos llama a la base de datos cada vez que quiero insertar una nueva fila, que es cada vez que alguien golpea una página.La mejor práctica para grabar gran cantidad de éxitos en la base de datos MySQL

Mi pregunta, ¿hay alguna forma de almacenar en caché local hits primero (y cuál es la mejor solución para esa aplicación, csv ...?) Y periódicamente enviarlos a la base de datos cada 10 minutos, por ejemplo? ¿Es esta una buena solución y cuál es la mejor práctica para esta situación?

+1

Además, ¿cuál es la mejor manera de seguir ** ** visitantes únicos (por dirección IP) en ese gran mesa? – livelygreen

+0

SELECT DISTINCT ( ip ) DE access_log' – genesis

Respuesta

22

500k diarios son solo 5-7 consultas por segundo. Si cada solicitud será servida por 0.2 segundos, entonces tendrá casi 0 consultas simultáneas, por lo que no hay nada de qué preocuparse.
Incluso si tiene 5 veces más usuarios, todos deberían funcionar bien.
sólo puede utilizar INSERT DELAYED y afinar su mysql.
Acerca de sintonía: http://www.day32.com/MySQL/ - no hay guión muy útil (va a cambiar nada, sólo le mostrará las puntas cómo optimizar la configuración).

Puede utilizar Memcache o APC para escribir ingrese allí primero, pero con el uso de INSERT DELAYED MySQL hará casi mismo trabajo, y lo hará mejor :)

No utilice archivos para esto. DB servirá bloqueos mucho mejor que PHP. No es tan trivial escribir mutexes efectivos, de modo que dejemos que DB (o memcache, APC) haga esto.

+0

+1 para obtener una respuesta más completa y discusión de 'INSERT DELAYED' –

18

una solución utilizada con frecuencia:

Se podría implementar un contador en el que memcached incrementas en una visita, y empujar una actualización de la base de datos por cada 100 (o 1000) golpea.

+4

Tener una memoria caché en lugar de caché de archivos (como en otra respuesta) es, de lejos, más rápido! +1 –

4

Hacemos esto almacenando localmente en cada servidor en CSV, luego teniendo un trabajo cron minuciosamente para insertar las entradas en la base de datos. Esto es para evitar la necesidad de una base de datos MySQL altamente disponible más que nada: la base de datos debería ser capaz de manejar ese volumen de insertos sin ningún problema.

3

Guárdelos en una base de datos basada en directorio (o archivo plano, depende) en algún lugar y en un momento determinado, utilice un código PHP para insertarlos/actualizarlos en su base de datos MySQL. Su código php se puede ejecutar periódicamente usando Cron, por lo que debe verificar si su servidor tiene Cron para que pueda establecer el horario para eso, por ejemplo, cada 10 minutos.

Echa un vistazo a esta página: http://damonparker.org/blog/2006/05/10/php-cron-script-to-run-automated-jobs/. Algunos códigos se han escrito en la nube y están listos para su uso :)

+0

El archivo crontab.php no se puede descargar en la página http://damonparker.org/blog/2006/05/10/php-cron-script-to-run-automated-jobs/ " – xuesong

+0

Así que intente encontrar una secuencia de comandos diferente en su lugar :) Hay miles de eso en Internet. –

+0

publicación en el blog ya no existe .... – Malachi

0

Para un alto número de operaciones de escritura y este tipo de datos que puede encontrar mongodb o couchdb más adecuada

+0

Y para informes sensatos, necesitará SQL. Esto no es un "alto número de operaciones de escritura" Intente hacer GROUP BY en XXXdb (reemplace XXX por su número de cuenta favorito) – MarkR

2

Una forma sería la de use Apache access.log. Puede obtener un registro bastante fino utilizando cronolog utilidad con apache. Cronolog se encargará del almacenamiento de una gran cantidad de filas en los archivos, y puede rotarlo según el día, el año, etc. del volumen. Usar esta utilidad evitará que su Apache sufra de escrituras de registro.

Luego, como dijeron otros, utilice un trabajo basado en cron para analizar estos registros y enviar los datos resumidos o en bruto que desee en MySQL.

Puede pensar en utilizar una base de datos dedicada (o incluso servidor de base de datos) para trabajos de escritura intensiva, con configuraciones específicas. Por ejemplo, es posible que no necesite almacenamiento InnoDB y mantenga un MyIsam simple. Y hasta se podría pensar en otro almacenamiento de base de datos (como lo dice @Riccardo Galli)

2

Si es absolutamente necesario para conectarse directamente a MySQL, considerar el uso de dos bases de datos. Uno optimizado para inserciones rápidas, lo que significa que no hay claves más que posiblemente una clave primaria auto_increment. Y otra con las claves de todo lo que estarías buscando, optimizado para búsquedas rápidas. Un trabajo programado copiaría visitas de la base de datos solo de inserción a la base de solo lectura de forma regular, y terminarás con lo mejor de ambos mundos. El único inconveniente es que las estadísticas disponibles solo serán tan recientes como la ejecución de "copia" anterior.

2

También he visto anteriormente un sistema que registra los datos en un archivo plano en el disco local en cada servidor web (tenga cuidado de hacer solo adjuntos atómicos si usa múltiples procesos), y periódicamente los escribe asincrónicamente en la base de datos usando un proceso de daemon o trabajo cron.

Esto parece ser la solución optimium predominante; su aplicación web permanece disponible si la base de datos de auditoría está inactiva y los usuarios no sufren un bajo rendimiento si la base de datos es lenta por algún motivo.

Lo único que puedo decir es que asegúrate de tener control sobre estos archivos generados localmente; una acumulación definitivamente indica un problema y tus ingenieros de operaciones podrían no haberlo notado.

0

Dado que INSERT DELAYED solo es compatible con MyISAM, no es una opción para muchos usuarios.

Utilizamos MySQL Proxy aplazar la ejecución de consultas que coincidan con una determinada firma.

Esto requerirá un script Lua costumbre; example scripts are here y some tutorials are here.

El guión implementará una estructura de datos de la cola para el almacenamiento de cadenas de consulta y comparación de patrones para determinar qué consultas aplazar. Una vez que la cola alcanza un cierto tamaño, o una cierta cantidad de tiempo ha transcurrido, o cualquier evento que ocurra X, la cola de consulta se vacía ya que cada consulta se envía al servidor.

0

se puede utilizar una estrategia de cola usando planta de frijoles o IronQ

Cuestiones relacionadas