2008-10-08 14 views
11

Tengo un sitio web impulsado por una base de datos que sirve alrededor de 50,000 páginas.Inicie sesión en un archivo mediante PHP o inicie sesión en la base de datos MySQL, ¿qué es más rápido?

Deseo hacer un seguimiento de cada golpe de página web/registro. Haré esto creando registros y luego procesando por lotes los registros una vez al día. No me preocupa cómo haré el proceso por lotes, solo con la forma más rápida de iniciar sesión.

¿Cómo iniciar la sesión, que cree usted que es más rápido:

a) Uso de PHP para añadir al final de un archivo de registro de texto.

b) Use MySQL para INSERTAR EN una tabla de registro no indexada.

Respuesta

2

Creo que un archivo plano será más rápido de escribir.

0

En el archivo será más rápido, pero en DB será mejor.

4

Use una base de datos, es la única opción que tiene sentido. Incluso si lleva un poco más de tiempo. Una vez que comience con los archivos de registro, se encontrará en una pista donde le causará dolor, por ejemplo, mover servidores, permisos de archivos, imposibilidad de balanceo de carga, etc. ...

Si tiene la base de datos abierta entonces creo que probablemente sea más rápido insertar una sola fila.

Sin embargo, con toda esta actuación relacionada con la única manera de estar seguro es escribir una prueba sencilla y medirlo ....

Actualización: Me he hecho una prueba rápida - y por supuesto si usted tiene que abrir y cerrar el archivo es aproximadamente la misma velocidad o más lento con una prueba de 10,000 líneas:

Sin embargo, cuando comienza a tener múltiples procesos haciendo esto, se ralentiza como se puede ver a continuación. Esto es con 10 procesos concurrentes (todas las sincronizaciones en segundos)

DB time: 2.1695 
DB time: 2.3869 
DB time: 2.4305 
DB time: 2.5864 
DB time: 2.7465 
DB time: 3.0182 
DB time: 3.1451 
DB time: 3.3298 
DB time: 3.4483 
DB time: 3.7812 
File open time: 0.1538 
File open time: 0.5478 
File open time: 0.7252 
File open time: 3.0453 
File open time: 4.2661 
File open time: 4.4247 
File open time: 4.5484 
File open time: 4.6319 
File open time: 4.6501 
File open time: 4.6646 
Open close file time: 11.3647 
Open close file time: 12.2849 
Open close file time: 18.4093 
Open close file time: 18.4202 
Open close file time: 21.2621 
Open close file time: 22.7267 
Open close file time: 23.4597 
Open close file time: 25.6293 
Open close file time: 26.1119 
Open close file time: 29.1471 

function debug($d) 
{ 
    static $start_time = NULL; 
    static $start_code_line = 0; 

    if($start_time === NULL) 
    { 
     $start_time = time() + microtime(); 
     $start_code_line = $code_line; 
     return 0; 
    } 

    printf("$d time: %.4f\n", (time() + microtime() - $start_time)); 
    $fp = @fopen('dbg.txt','a'); 
    fprintf($fp,"$d time: %.4f\n", (time() + microtime() - $start_time)); 
    fclose($fp); 

    $start_time = time() + microtime(); 
    $start_code_line = $code_line; 
} 

function tfile() 
{ 
    $fp = @fopen('t1.txt','a'); 
    for ($i=0;$i<10000;$i++) 
    { 
     $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:"; 
     fwrite($fp,$txt); 
    } 
    fclose($fp); 
} 
function tfile_openclose() 
{ 
    for ($i=0;$i<10000;$i++) 
    { 
     $fp = @fopen('t1.txt','a'); 
     $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:"; 
     fwrite($fp,$txt); 
     fclose($fp); 
    } 
} 

function tdb() 
{ 
    $db = mysql_connect('localhost','tremweb','zzxxcc'); 

    $select_db = mysql_select_db('scratch'); 

    if (!$select_db) 
     die('Error selecting database.'); 

    for ($i=0;$i<10000;$i++) 
    { 
     $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:"; 
     mysql_query("INSERT INTO tlog values('".$txt."')"); 
    } 
} 

debug(""); 

tfile(); 
debug("File open"); 

tfile_openclose(); 
debug("Open close file"); 

tdb(); 
debug("DB"); 
+0

Es por eso que los diferentes procesos deberían escribir en diferentes archivos ... Agregar más tarde. Todo lo que tiene que preocuparse con la apertura/cierre es almacenar los registros en intervalos de registro (una vez por hora probablemente esté bien para este tipo de carga). – SquareCog

+0

De hecho, sin embargo, no escribiría en ningún archivo de registro. Una vez que comienzas a hacer cosas como tener que agregar y rotar, se convierte en el tipo de proceso que irá mal, y con pocos beneficios en términos de CPU en el primer caso. Las bases de datos son buenas para almacenar y recuperar datos .... –

+0

OP aquí, esto me parece convincente, junto con el inserto retrasado –

0

me gustaría recomendar ensayo, en presencia de unos casos de prueba.

Supongo que un archivo plano sería más rápido, b/c eso es realmente lo que hace el DB, es solo escribirlo en un archivo. La única ventaja que se me ocurre es que si la base de datos se puede ejecutar simultáneamente, es posible que obtenga mejores resultados.

6

Yo usaría una inserción retrasada en MySQL. De esta manera, no tiene que esperar a que finalice el inserto.

+0

Interesante, no había oído hablar de estos insertos retrasados, parecen perfectos para el registro. –

+3

Excepto que no hay garantía de que realmente se inserten. La mayoría de las veces, lo harán ... pero dado que esto es un registro, probablemente quiera saber sobre los casos excepcionales incluso más que los regulares. – SquareCog

+0

Es cierto que no sabrá si la inserción falla. Pero si los registros son solo para estadísticas en la vista de páginas y él ya tiene una conexión db, la inserción diferida debería ser buena. Si los registros son críticos para él, entonces no es una buena solución. –

0

Todo depende de su infraestructura y limitaciones. Si el disco es lento, la escritura será lenta. Si el servidor SQL está retrasado por las solicitudes, la inserción será lenta. El archivo plano es probablemente el mejor camino a seguir, pero escribiría su código o usaría el código existente (PEAR :: Log) para que pueda cambiar el proveedor y el método de almacenamiento a voluntad.

7

Usted podría intentar ambos sentidos usando log4php, que apoya:

  • de configuración a través de archivo XML y propiedades (misma estructura que log4j).
  • Archivo, RollingFile, DailyFile, Echo, Consola, Correo, PEAR :: Db, Error de PHP, eventos Syslog o NT y complementos de socket.
  • Diseños simples, TTCC, Pattern, Html y Xml.
  • Contextos de diagnóstico anidados (NDC) y asignados (MDC).
  • Depuración interna conmutable.

En cuanto al inicio de sesión en un archivo, puede mejorar el rendimiento almacenando en búfer las solicitudes de escritura.

17
  1. Escribir en archivo. Gira los registros.

  2. Lote carga el archivo en la base de datos de forma programada.

Hay muchas, muchas razones para elegir esta arquitectura - facilidad de escalamiento (escribir a muchos registros, cargarlos en dB), la falta de confianza en una SPOF en la base de datos (si algo va mal, simplemente acumule registros durante un tiempo), capacidad de realizar análisis de limpieza y no triviales en tiempo de carga sin sobrecargar sus servidores de producción, y más.

0

algunas consideraciones:

  1. ¿Cree usted querrá unirse a los datos de registro con otros datos en la base de datos? Si es así, la sobrecarga de un inserto de db probablemente esté justificada, por lo que las relaciones existentes se pueden aprovechar fácilmente.
  2. ¿El registro de datos en la base de datos le permitirá reducir la cantidad de datos que está registrando en gran medida (debido a las relaciones existentes en el db)? Por ejemplo, un registro en la base de datos de la actividad del usuario podría ser simplemente una tabla que contenga un ID de usuario, ID de actividad y una marca de tiempo. Un archivo de registro tan delgado en un archivo no sería legible para el ser humano. Dependiendo de tus necesidades, necesitarías capturar al menos algunos de los datos del usuario en el archivo de registro para asegurar que puedan ser útiles y legibles por sí mismos.
  3. ¿Alguna posibilidad de que desee aprovechar estos datos de registro en el front end o mediante una herramienta de administración en el futuro? Si es así, es preferible escribir DB.
0

Como han mencionado otros, depende de muchas cosas, como el tráfico, la velocidad del disco, etc. Deberá probar los dos escenarios.

Al probar MySQL, pruebe tanto MyISAM como INNODB. En teoría, Innodb tendrá un mejor rendimiento, ya que tiene bloqueo de nivel de fila.

1

He hecho algo similar. Registro cada registro en un archivo separado, luego tengo un proceso por lotes que toma los archivos, los coloca en un archivo tar y los sube al servidor de registro central (en mi caso, S3 :)).

Genero nombres de archivo aleatorios para cada entrada de registro. Hago esto para evitar bloquear archivos para rotación. Es muy fácil de archivar/eliminar de esta manera.

Utilizo json como formato de registro en lugar de los típicos archivos de registro delimitados por espacios en blanco. Esto hace que sea más fácil analizar y agregar campos en el futuro. También significa que es más fácil para mí escribir una entrada por archivo que anexar varios registros por archivo.

También he usado log4php + syslog-ng para centralizar el registro en tiempo real. Tengo log4php log en syslog, que luego reenvía a los registros a mi servidor central. Esto es realmente útil en clusters más grandes. Una advertencia es que hay un límite de longitud para los mensajes de Syslog, por lo que corre el riesgo de que los mensajes más largos se trunquen.

0

Si se trata de un sitio conducido base de datos, ¿por qué no acaba con el construido en capacidades de registro de Apache o IIS, y una herramienta de información adecuado, tal como AWStats y más allá de eso, siempre hay Google Analytics

AWStats y el registro del servidor web es mi preferencia; en esencia, lo obtienes de forma gratuita, incluso si no buscas el análisis de tráfico, aún podrías considerar analizar el archivo de registro de acceso de Apache por ti mismo para el procesamiento por lotes que necesites hacer.

1

leí un artículo en el Diario de Usuarios de C++, hace años, sobre la marcha autenticarte. Ya sea que use DB o archivos, lo mejor que puede hacer es escribir datos sin formato que puedan "inflarse" en datos significativos cuando (y más probablemente si) necesita ver los registros. La gran mayoría del costo del registro está informando las cadenas que se escriben en el destino, y la mayoría de las veces ese costo se desperdicia: los registros nunca se leen.

Puedo encontrar la referencia del artículo si es útil para usted.

1

Si está utilizando el registro basado en archivos o el registro basado en la base de datos, su mayor impacto en el rendimiento será el bloqueo de archivos/tablas. Básicamente, si el cliente A y el cliente B se conectan dentro de un marco de tiempo relativamente pequeño, el cliente B queda bloqueado esperando que se libere el bloqueo en el archivo/tabla de aciertos antes de continuar.

El problema con un mecanismo basado en archivos es que el bloqueo de archivos es esencial para garantizar que sus hits no se corrompan. La única forma de evitarlo es implementar una cola para hacer una escritura diferida en el archivo.

Con el registro de base de datos, al menos puede hacer lo siguiente [usando MyISAM MySQL]:

INSERT DELAYED INTO `hits` ... 

Ver 12.2.5.2. INSERT DELAYED Syntax para más información.

+1

ahora obsoleto, según MySQL v5.6 –

Cuestiones relacionadas