2009-07-10 16 views
5

Sto sviluppando un'applicazione web multi-tenant utilizzando LAMP. Tutti i dati della mia sessione utente sono attualmente memorizzati in mysql con il tipo di tabella InnoDB.Approccio tabella sessione MySQL

È possibile utilizzare il tipo di tabella MEMORY (utilizzato per HEAP) per archiviare le sessioni correnti e utilizzare la funzione di garbage collector del gestore di sessione per spostare le sessioni tra InnoDB (tabella normale) e (in) Tabella MEMORY?

Inoltre questa configurazione influisce in qualche modo quando desidero clustering & configurazione master-slave in una fase successiva?

Grazie in anticipo, ocptime

risposta

6

Scrivi custom session handler è sorprendentemente facile, ma penso che ci sono modi probabilmente meglio per memorizzare i dati della sessione di MEMORY tabelle.

Uno schema qualcosa di simile (sollevato con le modifiche da a previous question)

CREATE TABLE IF NOT EXISTS `session` (
    `id` char(32) NOT NULL, 
    `data` varchar(20000) NOT NULL, 
    `time_created` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `time_updated` timestamp NOT NULL default '0000-00-00 00:00:00' on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `time_created` (`time_created`), 
    KEY `time_updated` (`time_updated`) 
) ENGINE=MEMORY DEFAULT CHARSET=utf8; 

allora si era appena devono definire le funzioni di gestione delle sessioni, come indicato nel link qui sopra o in questo tutorial. Se si desidera salvare le informazioni sulla sessione durante la garbage collection, è sufficiente creare una tabella identica a quella sopra utilizzando il motore INNODB e aggiungere un bit alla fine della funzione gc() che copia la riga dalle tabelle MEMORY a INNODB.

Tuttavia le tabelle MEMORY presentano dei limiti piuttosto significativi. Non possono usare le colonne BLOB o TEXT - ecco perché ho quel brutto varchar(20000) sopra. Hanno una dimensione massima di 16 MB. Se hai un sacco di utenti, tieni un sacco di stato, o hai problemi con la garbage collection puoi raggiungere quel limite e andare in crash.

Un'idea migliore è utilizzare memcache session handler, soprattutto se non è necessario memorizzare le informazioni di sessione nel lontano futuro. Sono abbastanza sicuro che lo memcached sia più veloce di qualsiasi RDBMS (anche con le tabelle MEMORY) e si adatta bene alla progettazione. Inoltre non dovrai scrivere le tue funzioni di gestore di sessione.

+1

È possibile aumentare la dimensione massima della tabella modificando la variabile di sistema [max_heap_table_size] (https://dev.mysql.com/doc/refman/5.5/en/server-saria-variables.html#sysvar_max_heap_table_size). –

3
InnoDB: ~40 milliseconds Cons: (Slowest) 
MEMORY: ~22 milliseconds Cons: (16MB Max) 
MyISAM: ~25 milliseconds Cons: (Table-level locking) 

sto usando (gs), quindi non posso fare memcache, ma che sarebbe meglio.

Personalmente stavo considerando l'utilizzo di MEMORY, ma non sapevo se il vantaggio in termini di prestazioni avrebbe eliminato il costo dei limiti di dimensione ecc. Così ho fatto quello che ogni buon programmatore dovrebbe fare quando ottimizza: l'ho profilato.

La mia pagina PHP in questione viene memorizzato nella cache in Smarty, quindi le uniche operazioni andranno in scena qui sono una ricerca regex sul URL e una gru a benna sessione di SQL per verificare se l'utente è connesso.

Comunque ecco i risultati : Con InnoDB ricevevo ~ 40 millisecondi in attesa di una richiesta. (Ho misurato questo in chrome con gli strumenti di sviluppo.) Dopo aver cambiato la tabella in MEMORY ho ottenuto ~ 20 millisecondi per richiesta. Wow! Miglioramento del 50%! Ma aspetta ... che ne pensi di MyISAM? L'ho provato e ho ricevuto ~ 22-23 millisecondi per richiesta. Oh.

Questo è solo un test, non un'applicazione completa.Una vera applicazione avrebbe migliaia di persone che scrivono su quel tavolo ogni secondo, e MyISAM blocca a livello di tabella, il che potrebbe essere negativo (Which MySQL database engine is better for storing sessions and session data: MyISAM or InnoDB?).

Quindi mi sto attaccando alla memoria, per ora. È un grande miglioramento per quelle pagine memorizzate nella cache, ma ti incoraggio a creare un profilo! Se il tuo sito web sta ricostruendo ogni pagina, i 10 millisecondi potrebbero non avere molta importanza.

+0

In che modo il blocco a livello di tabella influisce sulle prestazioni di un'applicazione su più larga scala. Bloccherebbe effettivamente gli utenti quando qualcuno tentasse di scrivere nella sessione come su un login? – Lightbulb1

+0

@ Lightbulb1, * ogni * visualizzazione di pagina deve aggiornare la tabella di sessione sul database per aggiornare l'ultimo orario di accesso (per sapere quando scadere la sessione e quando le sessioni sono libere di essere garbage collection). Se due persone ottengono una pagina nello stesso momento esatto, una persona deve attendere che la scrittura dell'altro sia terminata perché Mysql blocca fino a quando la scrittura non è completa (a meno che non si faccia un [LOW_PRIORITY] (http: //dev.mysql .com/doc/refman/5.0/it/update.html), che risolvono il problema). Tuttavia, si tratta solo di un'ottica prematura. Se il tuo sito è così occupato, considera memcached. – andychase

+0

Grazie per l'informazione. Non ho usato memcache prima quindi è qualcosa su cui ho bisogno di fare ulteriori ricerche. Sarà propriamente la soluzione per il futuro. – Lightbulb1

0

Utilizzare la tabella InnoDB per la sessione. Ho sentito che la tabella di memoria durante l'inserimento blocca l'intera tabella mentre InnoDB blocca solo la riga specifica che deve essere manipolata.