2012-04-17 18 views
7

Sto sviluppando un sito Web. Attualmente, sono su hosting condiviso cheapo. Ma un ragazzo può sognare e sto già pensando a cosa succede con un numero maggiore di utenti sul mio sito.

I visitatori richiederanno occasionali scritture di database, man mano che i loro progressi nel gioco sul sito vengono registrati.

Ho pensato di ridurre al minimo le query scrivendo progresso e altre informazioni dal vivo nella variabile $_SESSION. E solo quando la sessione viene distrutta (disconnessione, chiusura del browser o timeout), voglio scrivere il contenuto di $_SESSION nel database.

Domande:

  1. è possibile? C'è un modo per eseguire una funzione quando le sessioni vengono distrutte dal timeout o dalla chiusura del browser?

  2. È sensato? Sono un paio di centinaia di query SQL simultanee che costituiranno un problema per un server condiviso ed è l'idea di utilizzare $_SESSION come un buffer per alleviare alcuni di questi problemi.

risposta

5

Non è una buona idea scrivere i dati quando la sessione viene distrutta. Poiché i dati della sessione potrebbero essere distrutti tramite un garbage collector configurato dal tuo hoster, non hai idea se la sessione è veramente chiusa fino a quando il cookie dell'utente non è aggiornato.

Quindi ... ti suggerisco di utilizzare un sistema di cache di memoria condivisa (RAM) come memcache (se il tuo hoster lo offre) o un sistema di cache basato su disco.

A proposito, se le query sono ottimizzate, le colonne sono indicizzate correttamente, ecc., Il tuo hosting condiviso potrebbe richiedere tonnellate di query "nello stesso momento".

+1

memcache è sicuramente la strada da percorrere, itll alleggerire i mocassini più di quanto sessione di stoccaggio/scrittura. – gorelative

+4

Non ottimizzare finché non si è certi di avere un problema. Nel momento in cui si ha abbastanza carico che questo è un problema, il tuo host ti ha fatto spostare comunque sul tuo server dedicato. –

+0

OK. Scarto quell'idea allora. Grazie gente! – Ryan

6

C'è un modo per eseguire una funzione quando le sessioni vengono distrutte dal timeout o dalla chiusura del browser?

Sì, ma potrebbe non funzionare come si immagina. È possibile definire il proprio gestore di sessione personalizzato utilizzando session_set_save_handler e parte della definizione fornisce le funzioni di callback destroy e gc. Questi due vengono richiamati quando una sessione viene distrutta in modo esplicito e quando viene distrutta a causa della sua scadenza, quindi fanno esattamente quello che chiedi.

Tuttavia, la scadenza della sessione a causa del timeout è non con precisione di clockwork; potrebbe essere un bel po 'di tempo prima che una sessione scaduta sia in realtà "raccolta dei rifiuti". Inoltre, la procedura di garbage collection innesca probabilistically così nella teoria c'è la possibilità che le sessioni scadute corrispondano a mai a.

È sensato? Sono un paio di centinaia di query SQL simultanee che vanno a per essere un problema per un server condiviso ed è l'idea di usare $ _SESSION come buffer per alleviare alcuni di questi.

Io davvero non farei questo per diversi motivi:

  • ottimizzazione prematura (prima di misurare, non dare per scontato che sarà "migliore").
  • La sessione potrebbe non essere mai raccolta dati inutili; anche se ciò non accade, non si controlla quando vengono raccolti i dati. Questo potrebbe essere un problema.
  • C'è una possibilità di perdere tutto ciò che una sessione contiene (ad esempio il riavvio del server), che include il progresso del giocatore. Ai giocatori non piace perdere i progressi.
  • Le sessioni simultanee per lo stesso utente sarebbero impossibili (i cui "dati salvati" vince e rimane persistente nel database?).

E le alternative?

Bene, dato che stiamo parlando dell'hosting condiviso di el cheapo, non si ha il controllo del server, quindi tutto ciò che comporta estensioni PHP (ad esempio memcached) è condizionale. Anche il caching sul lato database non ha intenzione di volare. Inoltre, il carico sul tuo server sarà influenzato da variabili esterne al tuo controllo, quindi non puoi davvero fare alcuna pianificazione della capacità.

In ogni caso, inizierei assicurandomi che il database stesso sia strutturato in modo ottimale e che il codice sia scritto in modo da minimizzare il carico sul database (prestazioni gratuite semplicemente digitando materiale in un editor).

Successivamente, è possibile introdurre la cache di sola lettura : in genere ci sono molte cose che è necessario visualizzare ma non si intende modificare. Per i dati che "quasi mai" vengono aggiornati, una cache di sessione che si annulla ogni volta che è necessario potrebbe essere un miglioramento facile e molto efficace (si possono anche avere falsi positivi per quanto riguarda l'invalidazione, purché non siano troppi nel grande schema di cose).

Infine, è possibile aggiungere il caching per richiesta (in variabili) se si è preoccupati di estrarre gli stessi dati dal database due volte durante una singola richiesta.

+0

fico, non lo sapevo. stavo cercando qualcosa di simile per lungo tempo :) grazie! – heximal

1

In realtà si potrebbe usare $ _SESSION come buffer per evitare letture duplicate, mi sembra una buona idea (memcached anche meglio di così), sicuramente non per ritardare la scrittura (che è molto più complessa e dovrebbe essere gestita da il db);

si potrebbe usare un semplice hash che si salva in $ _SESSION

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

poi, quando si deve fare una query

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

È quello sensical? Sono un paio di centinaia di query SQL simultanee che costituiranno un problema per un server condiviso ed è l'idea di utilizzare $ _SESSION come un buffer per alleviare alcuni di questi problemi.

No. In primo luogo, non si sa mai cosa succede a una sessione (Logout è ovvio, in cui un time-out è quasi impercettibile), quindi non è un meccanismo di caching affidabile in ogni caso. Se vi sono risultati che si verificano più volte nell'arco di alcune richieste, che non cambiano troppo spesso, salvare i risultati di tali query su un meccanismo di caching dedicato, come ad esempio APC o memcached.

Ora, ho capito che il tuo webhost non fornirà questi sistemi di memorizzazione nella cache, ma, probabilmente, puoi fare cose diverse per ottimizzare il tuo sito. Per cominciare, i miei prodotti software più complessi (che sono piuttosto complessi) interrogano il database circa 6 volte per pagina, in media. Se il risultato è riutilizzabile, tendo a utilizzare la memorizzazione nella cache, in modo da ridurre il numero di query.

Inoltre, scrivere domande decenti è più importante; la qualità del tuo design e delle tue query è più importante della quantità. Se ottieni correttamente schemi, indici e query, 10 query sono più veloci di una query non ottimizzata. Investirei il mio tempo indagando su come scrivere query efficienti e leggendo sull'indicizzazione, piuttosto che cercare di superare il problema con una "soluzione alternativa", come il caching in una sessione.

Buona fortuna, spero che il sito diventa così grande di un successo che sarà effettivamente bisogno di consigli di cui sopra;)