2012-04-17 30 views
7

Estoy desarrollando un sitio web. Actualmente, estoy en el alojamiento compartido cheapo. Pero un niño puede soñar y ya estoy pensando en lo que sucede con un mayor número de usuarios en mi sitio.

Los visitantes requerirán escrituras ocasionales en la base de datos, ya que se registra su progreso en el juego en el sitio.

Pensé en minimizar las consultas escribiendo el progreso y otra información en vivo en la variable $_SESSION. Y solo cuando se destruye la sesión (cierre de sesión, cierre del navegador o tiempo de espera), deseo escribir el contenido de $_SESSION en la base de datos.

Preguntas:

  1. es posible? ¿Hay alguna manera de ejecutar una función cuando las sesiones se destruyen por tiempo de espera o cierre del navegador?

  2. ¿Eso es sensato? Son un par de cientos de consultas SQL concurrentes un problema para un servidor compartido y la idea de utilizar $_SESSION como un búfer va a aliviar algo de esto.

Respuesta

5

No es una buena idea escribir datos cuando se destruye la sesión. Dado que los datos de la sesión podrían destruirse a través de un recolector de basura configurado por su proveedor de servicios de alojamiento, no tiene idea de cuándo la sesión realmente se cierra hasta que la cookie del usuario no esté actualizada.

Entonces ... Le sugiero que use un sistema de caché de memoria compartida (RAM) como Memcache (si su proveedor de alojamiento lo ofrece) o un sistema de caché basado en disco.

Por cierto, si sus consultas están optimizadas, las columnas correctamente indexadas, etc., su alojamiento compartido podría llevar toneladas de consultas al mismo tiempo.

+1

Memcache es definitivamente el camino a seguir, itll aligerar los mocasines más que la sesión de almacenamiento/escritura. – gorelative

+4

No optimice hasta que sepa que tiene un problema. Para el momento en que tenga suficiente carga como para que esto sea un problema, su servidor lo habrá movido a su propio servidor dedicado de todos modos. –

+0

De acuerdo. Voy a desechar esa idea entonces. ¡Gracias amigos! – Ryan

6

¿Hay alguna manera de ejecutar una función cuando las sesiones se destruyen por tiempo de espera o cierre del navegador?

Sí, pero puede que no funcione de la forma en que te imaginas. Puede definir su propio manejador de sesión personalizado usando session_set_save_handler, y parte de la definición suministra las funciones de devolución de llamada destroy y gc. Estos dos se invocan cuando una sesión se destruye explícitamente y cuando se destruye debido a que han caducado, por lo que hacen exactamente lo que usted solicita.

Sin embargo, la caducidad de la sesión debido al tiempo de espera no no ocurre con precisión de reloj; puede pasar mucho tiempo antes de que una sesión expirada sea realmente "recogida de basura". Además, la recolección de basura desencadena probabilistically por lo que en teoría existe la posibilidad de que las sesiones expiradas nunca sean basura recolectada.

¿Eso es sensato? Son un par de cientos de consultas SQL concurrentes que van a ser un problema para un servidor compartido y la idea de utilizar $ _SESSION como un búfer va a aliviar algo de esto.

Realmente no haría esto por varias razones:

  • optimización prematura (antes de medir, no simplemente asumir que será "mejor").
  • Es posible que la sesión nunca se recolecte basura; incluso si esto no sucede, no controla cuando se recopilan. Esto podría ser un problema.
  • Existe la posibilidad de perder todo lo que contiene una sesión (por ejemplo, reinicios del servidor), que incluye el progreso del reproductor. A los jugadores no les gusta perder el progreso.
  • Sesiones concurrentes para el mismo usuario serían imposibles (¿quién gana y permanece en la base de datos los "datos guardados"?).

¿Qué pasa con las alternativas?

Bueno, como estamos hablando del alojamiento compartido el cheapo, definitivamente no vas a tener el control del servidor, por lo que todo lo que involucre extensiones PHP (por ejemplo, memcached) es condicional. El almacenamiento en caché del lado de la base de datos tampoco va a volar. Además, la carga en su servidor se verá afectada por variables que están fuera de su control, por lo que no puede hacer ninguna planificación de capacidad.

En cualquier caso, comenzaré asegurándome de que la base de datos está estructurada de manera óptima y que el código está escrito de forma que minimice la carga en la base de datos (rendimiento gratuito simplemente escribiendo cosas en un editor).

Después de eso, puede introducir caché de solo lectura: generalmente hay muchas cosas que debe mostrar pero no tiene la intención de modificar. Para los datos que "casi nunca" se actualizan, un caché de sesión que invalide siempre que lo necesite podría ser una mejora fácil y muy efectiva (incluso puede tener falsos positivos con respecto a la invalidación, siempre que no sean demasiados en el gran plan de cosas).

Finalmente, puede agregar caché por solicitud (en variables) si le preocupa extraer los mismos datos de la base de datos dos veces durante una sola solicitud.

+0

genial, no lo sabía. estaba buscando algo similar por mucho tiempo :) gracias! – heximal

1

En realidad podría usar $ _SESSION como buffer para evitar lecturas duplicadas, esto me parece una buena idea (incluso mejor que eso), seguramente no para retrasar la escritura (que es mucho más complejo y debe ser manejado por el db);

usted podría utilizar un hash simple que se guarda en $ _SESSION

$cache = array(); 
$_SESSION['cache'] = $cache; 

continuación, cuando se tiene que hacer una consulta

if(isset($_SESSION['cache'][$id]){ 
    //you have a cache it 
    $question = $_SESSION['cache'][$id]; 
}else{ 
    //no cache, retrieve your $question and save it in the cache 
    $_SESSION['cache'][$id] = $question ; 
} 
2

Es que sensical? Son un par de cientos de consultas SQL concurrentes un problema para un servidor compartido y la idea de usar $ _SESSION como un búfer va a aliviar algo de esto.

No. Primero y ante todo, nunca se sabe lo que ocurre con una sesión (cierre de sesión es obvio, en un tiempo de espera es casi indetectable), así que no es un mecanismo de almacenamiento en caché de confianza en todo caso. Si hay resultados que consulta varias veces en el lapso de algunas solicitudes, que no cambian con demasiada frecuencia, guarde los resultados de esas consultas en un mecanismo de caché dedicado, como APC, o memcached.

Ahora, tengo entendido que su servidor web no proporcionará estos sistemas de almacenamiento en caché, pero es probable que pueda hacer cosas diferentes para optimizar su sitio. Para empezar, mis productos de software más complejos (que son bastante complejos) consultan la base de datos unas 6 veces por página, en promedio. Si el resultado es reutilizable, tiendo a usar el almacenamiento en caché, por lo que se reduce el número de consultas.

Además de eso, escribir decente consultas es más importante; la calidad de su diseño y consultas es más importante que la cantidad. Si obtiene el esquema, los índices y las consultas correctos, 10 consultas son más rápidas que una consulta que no está optimizada. Invertiría mi tiempo investigando cómo escribir consultas eficientes, y leer en la indexación, en lugar de tratar de superar el problema con una "solución", como el almacenamiento en caché en una sesión.

Buena suerte, espero que su sitio se vuelve tan grande de un éxito Se necesitan realmente el consejo anterior;)