2009-07-10 11 views
5

Je développe une application web multi-locataire en utilisant LAMP. Toutes mes données de session utilisateur sont actuellement stockées dans mysql avec le type de table InnoDB.Approche de table de session MySQL

Est-il possible d'utiliser le type de table MEMORY (used to HEAP) pour stocker les sessions en cours et utiliser la fonction garbage collector du gestionnaire de session pour déplacer des sessions entre InnoDB (table standard) et) Table MEMORY?

Est-ce que cette configuration affecte de quelque façon que ce soit quand je veux mettre en grappe & configuration maître-esclave à un stade ultérieur?

Merci à l'avance, ocptime

Répondre

6

L'écriture d'un custom session handler est étonnamment facile, mais je pense qu'il ya probablement de meilleures façons de stocker les données de session que MEMORY tables.

Un schéma quelque chose comme (soulevé avec les changements des 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; 

alors vous auriez juste pour définir vos fonctions de gestionnaire de session, comme indiqué dans le lien ci-dessus ou dans ce tutorial. Si vous souhaitez enregistrer vos informations de session lors de la récupération de place, vous devez créer une table identique à celle ci-dessus en utilisant le moteur INNODB et ajouter un bit à la fin de la fonction gc() qui copie la ligne des tables MEMORY à INNODB. Cependant, les tables MEMORY ont des limites assez importantes. Ils ne peuvent pas utiliser les colonnes BLOB ou TEXT - c'est pourquoi j'ai cette moche varchar(20000) ci-dessus. Ils ont une taille maximale de 16 Mo. Si vous avez beaucoup d'utilisateurs, gardez beaucoup d'état, ou avez des problèmes avec la récupération de place, vous pouvez atteindre cette limite et planter. Une meilleure idée est d'utiliser le memcache session handler, surtout si vous n'avez pas besoin de stocker des informations de session dans un futur lointain. Je suis assez sûr que memcached est plus rapide que n'importe quel SGBDR serait (même avec MEMORY tables) et il s'échelonne bien par conception. De plus, vous n'aurez pas à écrire vos propres fonctions de gestionnaire de session.

+1

Il est possible d'augmenter la taille maximale de la table en ajustant la variable système [max_heap_table_size] (https://dev.mysql.com/doc/refman/5.5/en/server-system-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) 

J'utilise (gs), donc je ne peux pas memcache, mais ce serait mieux. Personnellement, j'envisageais d'utiliser MEMORY, mais je ne savais pas si les avantages en termes de performances permettraient d'écarter le coût des limites de taille, etc. J'ai donc fait ce que tout bon programmeur doit faire pour optimiser: je l'ai profilé.

Ma page php en question sont mises en cache dans Smarty, les seules opérations qui se déroulent sont une recherche regex sur l'URL et une poignée de session SQL pour vérifier si l'utilisateur est connecté.

Quoi qu'il en soit voici les résultats : Avec InnoDB, je recevais ~ 40 millisecondes en attente d'une demande. (J'ai mesuré cela en chrome avec les outils de développement.) Après avoir basculé la table en mémoire, j'ai obtenu ~ 20 millisecondes par demande. Hou la la! 50% d'amélioration! Mais attendez ... qu'en est-il de MyISAM? J'ai essayé cela et j'ai obtenu ~ 22-23 millisecondes par demande. Oh.

Ceci est juste moi le test, pas une application à grande échelle.Une application réelle aurait des milliers de personnes qui écrivent à cette table chaque seconde, et MyISAM verrouille au niveau de la table, ce qui pourrait être mauvais (Which MySQL database engine is better for storing sessions and session data: MyISAM or InnoDB?).

Alors je m'en tiens à la mémoire, pour le moment. C'est une amélioration considérable pour ces pages en cache, mais je vous encourage à le profiler! Si votre site Web reconstruit chaque page, les 10 millisecondes peuvent ne pas avoir d'importance.

+0

Comment le verrouillage au niveau de la table affecterait-il les performances sur une application à plus grande échelle? Serait-il bloquer efficacement les utilisateurs lorsque quelqu'un essaie d'écrire à la session comme sur un login? – Lightbulb1

+0

@ Lightbulb1, * chaque * page doit mettre à jour la table de session sur la base de données pour mettre à jour la dernière heure consultée (pour savoir quand expirer la session et quand les sessions peuvent être récupérées). Si deux personnes obtiennent une page au même moment, une personne doit attendre que l'écriture de l'autre personne soit terminée car Mysql se bloque jusqu'à ce que l'écriture soit terminée (sauf si vous faites une [LOW_PRIORITY] (http: //dev.mysql .com/doc/refman/5.0/fr/update.html), ce qui résoudrait le problème). Mais ce n'est vraiment qu'une optimisation prématurée. Si votre site est occupé, pensez à memcached. – andychase

+0

Merci pour l'information. Je n'ai jamais utilisé Memcache auparavant, donc c'est quelque chose que je dois faire plus de recherches. Il sera correctement la solution pour l'avenir. – Lightbulb1

0

Utilisez la table InnoDB pour la session. J'ai entendu cette table de mémoire tout en insérant des verrous toute la table tandis qu'InnoDB verrouille seulement la rangée particulière qui doit être manipulée.

Questions connexes