[script] Mise en cache des pages PHP - V2

WRInaute passionné
A la demande générale (ben oui 2 membres sur185832 incrits sur WRI, c'est [presque] l'unanimité :mrgreen: ) je publie aujourd'hui la version 2 de mon script de mise en cache.

En effet, l'ancien script avait quelques inconvénients (en vrac)

- difficulté a intégrer des données dynamiques (données de session par exemple)
- consommation importante et inutile d'espace disque (les données étaient mise en cache avec le code HTML)
- toute modification de "l'habillage du site" (charte, css,structure ...) impose de vider le cache en totalité

J'ai donc réfléchi à l'époque a un système qui ne cacherait que les données. J'ai tout d'abord réalisé la mise en cache à l'aide de fichiers XML (cela élimine certaines restrictions mais reste gourmand en espace disque et demande un traitement plus lourd qui consomme des ressources processeur)

Le système a fonctionné sans problème sur Fan de Cinéma pendant 1 ans. Mais je suis un puriste et j'ai cherché la solution ultime (pour qu'un script me satisfasse il faut qu'il marche mais aussi qu'il soit beau ! :mrgreen: )

J'ai fini par trouver la solution en utilisant la sérialisation des données en PHP. Le résultat est un système de cache léger, performant et totalement indépendant de la mise en forme des données coté HTML/PHP

Pas d'impatience, voyons d'abord les conventions utilisées :

  1. 1 -on suppose que votre serveur web (apache, lighttpd, nginx ou autre) et PHP fonctionne sous le compte www:www (utilisateur www du groupe www)
  • 2 - on suppose que la racine de l'arborescence de votre serveur web est /home/www/
  • 3 - pour illustrer l'exemple, on suppose que nous avons une vidéothèque à gérer dont la BDD est la suivante:

    table dvd : iddvd, titre, date,durée,format, synopsis
    table personnalites : idperson, nom, prenom
    table casting : iddvd, idperson

1 ère étape : on crée un dossier nommé cache hors de la racine du serveur web (par exemple /home/cache/) sous le compte www:www (php peut y acceder en lecture et ecriture mais pas votre serveur web par mesurede sécurité). on peut structurer l'arborescence de ce dossier comme on le souhaite et selon ses besoins. Par la même occasion créons le dossier /home/classes/ pour stocker nos fichiers classes PHP

2 éme étape on crée des classe PHP qui aura en charge la lecture des données en BDD, la mise en cache et l'envoi des données aux scripts PHP. Une classe permet d'obtenir les données relative à un DVD, l'autre d'obtenir la liste des DVD ou figure une personnalité donnée (on fait simple) Dans notre exempe, les données relatives aux DVD seront cachées dans /home/cache/dvd/ et les données relatives aux personnalité seront cachées dans /home/cache/person/

Code:
<?php
class DVD {
	var $vars = array(); // c'est le tableau qui contiendra les données de la classe
	
	fonction DVD($titre) {
		if(file_exists("/home/cache/dvd/".clean($titre).".txt")===false) {   
		// on verifie si le fichier de données est en cache; 
		// la fonction clean permet de nettoyer les caractères spéciaux, son code est donné plus bas
		// le fichier n'est pas en cache
		// on fait ici le traitement pour lire la BDD et on stoque le résultat dans un tableau de la forme :
		// Array {
		//	[Erreur] => true si le DVD n'existe pas, false sinon
		//	[Iddvd] => xxxx
		//	[Titre] => blablabla
		//	[Date] => blablabla
		//	[Annee] => xxxx
		//	[Format] => blablabla
		//	[Casting] => Array {
		//		[0] => Array {
		//			[Nom] => blablabla
		//			[Prenom] => blablabla
		//		}
		//		[1] => Array {
		//			[Nom] => blablabla
		//			[Prenom] => blablabla
		//		}
		//		[2] => Array {
		//			[Nom] => blablabla
		//			[Prenom] => blablabla
		//		}
		//	}
		//	on stoque ce tableau dans $this->vars
		// il n'y a plus qu'à sérialiser le tableau et le stoquer dans le cache
			$temp=serialize($this->vars);
			$fd = fopen("/home/cache/dvd/".clean($titre).".txt","w");
			if ($fd) {
				fputs($fd,$temp);
				fclose($fd);
			}
		} else {  //  le fichier est en cache
		// on lit le fichier cache pour en extraire le contenu
			$temp=implode("",@file("/home/cache/dvd/".clean($titre).".txt"));  
		// on désérialize le contenue et on le stocke dans le tableau $vars
			$this->vars=unserialise($tmp);	
		}
	}
	// on implémente une méthode pour lire les données de la classe
	function getAllVars() {
		return $this->vars;
	}
	// on implémente une méthode pour lire un élément du tablau
	function getVars($name) {
		return $this->vars[$name];
	}
}
?>

La classe DVD est terminée, passons à la classe Person :

Code:
<?php
class Person {
	var $vars = array(); // c'est le tableau qui contiendra les données de la classe
	
	fonction DVD($nom,$prenom) {
		if(file_exists("/home/cache/person/".clean($nom).",".clean($prenom).".txt")===false) {   
		// on verifie si le fichier de données est en cache; 
		//la fonction clean permet de nettoyer les caractères spéciaux, son code est donné plus bas
		// le fichier n'est pas en cache
		// on fait ici le traitement pour lire la BDD et on stoque le résultat dans un tableau de la forme :
		// Array {
		//	[Erreur] => true si la personne n'existe pas, false sinon
		//	[Nom] => blablabla
		//	[Prenom] => blablabla
		//	[Dvds] => Array
		//		[0] => Array {
		//			[Titre] => blablabla
		//			[Date] => blablabla
		//			[Annee] => xxxx
		//			[Format] => blablabla
		//		}
		//		[1] => Array {
		//			[Titre] => blablabla
		//			[Date] => blablabla
		//			[Annee] => xxxx
		//			[Format] => blablabla
		//		}
		//		[2] => Array {
		//			[Titre] => blablabla
		//			[Date] => blablabla
		//			[Annee] => xxxx
		//			[Format] => blablabla
		//		}
		//	}
		//	on stoque ce tableau dans $this->vars
		//	
		// il n'y a plus qu'à sérialiser le tableau et le stocquer dans le cache
			$temp=serialize($this->vars);
			$fd = fopen("/home/cache/person/".clean($nom).",".clean($prenom).".txt","w");
			if ($fd) {
				fputs($fd,$temp);
				fclose($fd);
			}
		} else {  //  le fichier est en cache
		// on lit le fichier cache pour en extraire le contenu
			$temp=implode("",@file("/home/cache/person/".clean($nom).",".clean($prenom).".txt"));  
		// on désérialize le contenue et on le stocke dans le tableau $vars
			$this->vars=unserialise($tmp);	
		}
	}
	// on implémente une méthode pour lire les données de la classe
	function getAllVars() {
		return $this->vars;
	}
	// on implémente une méthode pour lire un élément du tablau
	function getVars($name) {
		return $this->vars[$name];
	}
}
?>
Le petit code de la fonction clean qui permet de fabriquer des noms de fichier conforme aux règles Unix
Code:
	function clean($src){
		$accents = "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ";
		$pasaccents = "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn";
		$dest=(strtr($src,$accents,$pasaccents));
		$dest=strtolower($dest);
		$dest=ereg_replace("[^/[:alnum:]]"," ",$dest);
		$dest=str_replace("  "," ",$dest);
		$dest=str_replace("  "," ",$dest);
		return (str_replace(" ","-",$dest));
	}

Voilà pour les classe que l'on met dans un fichier /home/classes/ma_classe.php

Voyons comment utiliser ces classes :
Code:
<?php
	// on commence par intégrer notre fichier classe à notre script
	include("/home/classes-v5/actualites-v5.class.php"); 
	// on initialise la classe avec un titre de DVD 
	$my_dvd = new DVD("nom du dvd");			
	// on peut maintenant obtenir les données relatives au DVD
	$my_dvd_datas=$my_dvd->getAllVars();			
	// le tableau $my_dvd_datas contient l'ensemble des données relatives au DVD
	// on peut vérifier si le DVD existe
	if($my_dvd->getVars("Erreur") {
		// le DVD n'existe pas
	} else {
		// le DVD existe
	}
	// on peut retrouver un élément particulier du DVD
	$my_dvd_casting=$my_dvd->getVars("Casting");	
	// le tableau $my_dvd_casting contient le casting du DVD sous forme d'une liste nom,prénom
	$my_dvd_format=$my_dvd->getVars("Format");	
	// la variable $my_dvd_format contient le format du DVD
	// on peut bien sur faire de même avec la classe Person
	// on initialise la classe avec nom prénom de personnalité
	$my_person = new Person("nom de la personne","prenom de la personne");			
	// on peut maintenant obtenir les données relatives à la personnalité
	$my_person_datas=$my_person->getAllVars();			
	// le tableau $my_person_datas contient l'ensemble des données relatives à la personnalité
	// etc, etc ...
?>

Cet exemple est très simple, son seul objectif étant de montrer le principe du système, je fais confiance à votre imagination. :wink:

Bon, si ce post passe pas en tête des recos, je bouffe mon avatar :mrgreen: :mrgreen: :mrgreen:
 
WRInaute accro
En gros c'est du cache de résultats MySQL, différent de ton script V1 qui enregistrait le code HTML d'output ?
 
WRInaute impliqué
spout a dit:
En gros c'est du cache de résultats MySQL, différent de ton script V1 qui enregistrait le code HTML d'output ?
Ca en a tout l'air. Mais est-ce qu'il ne vaudrait pas mieux un bon cache coté MySQL ?

L'accès aux fichiers prenant du temps, afficher une liste de 100 dvd risquerait d'être plus "gourmant" qu'une requete du type SELECT * FROM latable LIMIT 100 :?:
 
WRInaute accro
J'utilise souvent ce genre cache (avec CakePHP), ça décharge MySQL et ça boost bien les scripts.
Ex:
Code:
$cacheFile = 'countries_list';
if (($CountriesList = Cache::read($cacheFile)) === false){
	$CountriesList = $this->Country->find('list', array('fields'=>array('Country.code', 'Country.name')));
	Cache::write($cacheFile, $CountriesList);
}
 
WRInaute impliqué
Autant pour moi, j'ai une fois eu une mauvaise expérience avec un include dans une boucle :roll:
 
WRInaute passionné
seebz a dit:
spout a dit:
En gros c'est du cache de résultats MySQL, différent de ton script V1 qui enregistrait le code HTML d'output ?
Ca en a tout l'air. Mais est-ce qu'il ne vaudrait pas mieux un bon cache coté MySQL ?

L'accès aux fichiers prenant du temps, afficher une liste de 100 dvd risquerait d'être plus "gourmant" qu'une requete du type SELECT * FROM latable LIMIT 100 :?:

Mysql dispose déjà d'un cache mais c'est lui qui le gère, pas le webmaster contrairement à la solution proposée (et puis le cache de Mysql c'est aussi un fichier :lol: ). En ce qui concerne les liste, il suffit de faire un cache de ces listes ce qui ramène à 1 fichier par page :mrgreen:

L'intérêt de ce genre de cache c'est qu'il demeure même après coupure ou reboot du serveur physique ou du serveur web ou du serveur Mysql (ce n'est pas le cas du cache Mysql ni des systèmes de cache d'Opcode) et qu'il n'y aura plus aucune requete à Mysql tants qu'il n'y a pas de mise jour des données (il faut bien sur implémenter les fonctions de gestion des fichier cache coté back-office)

Je rajoute que les données contenues dans un fichiers cache peuvent provenir de plusieurs requêtes Mysql et de requêtes complexes avec jointure et tout et tout ...

De toute façon, ce système ne remplace ni le cache Mysql ni un éventuel cache d'Opcode mais s'y superpose.
 
WRInaute passionné
C'est fini d poluer mon post ! les enfants allez jouer ailleurs, c'est une discussion de spécialiste ici :mrgreen: :mrgreen: :mrgreen:
 
Membre Honoré
fandecine a dit:
C'est fini d poluer mon post ! les enfants allez jouer ailleurs, c'est une discussion de spécialiste ici :mrgreen: :mrgreen: :mrgreen:
Pour revenir au sujet :
fandecine a dit:
Mysql dispose déjà d'un cache mais c'est lui qui le gère, pas le webmaster contrairement à la solution proposée (et puis le cache de Mysql c'est aussi un fichier :lol: ). En ce qui concerne les liste, il suffit de faire un cache de ces listes ce qui ramène à 1 fichier par page :mrgreen:
Merci pour la précision.
fandecine a dit:
L'intérêt de ce genre de cache c'est qu'il demeure même après coupure ou reboot du serveur physique ou du serveur web ou du serveur Mysql (ce n'est pas le cas du cache Mysql ni des systèmes de cache d'Opcode) et qu'il n'y aura plus aucune requete à Mysql tants qu'il n'y a pas de mise jour des données (il faut bien sur implémenter les fonctions de gestion des fichier cache coté back-office)
Et là c'est très intéressant pour les entreprises qui ont des boutiques en lignes. Merci l'expert. :mrgreen:
 
WRInaute accro
Oh bin ça ça fait plaisir ! Merci 1000 fois fan de ciné !

Par contre pour le coup je n'ai -encore- rien compris :mrgreen: En gros il faut tout recoder pour intégrer ce cache ?
C'est plus efficace que ton cache V1 ?

Un grand merci pour le partage, j'ai comme l'impression que ce topic va battre des records de nombre de pages !
 
WRInaute passionné
milkiway a dit:
En gros il faut tout recoder pour intégrer ce cache ?

Oui, ça n'a rien a voir avec le V1 (sinon je l'aurais nommé V1.1 et pas V2 :mrgreen: )

milkiway a dit:
C'est plus efficace que ton cache V1 ?

Oui, mais c'est surtout bien plus souple et ça permet de conserver le côté dynamique de la page.

Et puis cela répond a la règle primordiale de l'informatique (et aussi des standards du WEB) qui est la séparation du contenu (les données) et de leur présentation (la page WEB) ce qui n'étais pas le cas de la V1.

seebz a dit:
L'accès aux fichiers prenant du temps, afficher une liste de 100 dvd risquerait d'être plus "gourmant" qu'une requete du type SELECT * FROM latable LIMIT 100

Avant tout, ne mélangeons pas le temps d'accès web à un fichier et le temps d'accès système. Accéder à un fichier en PHP est à peine plus gourmand que faire un include de fichier et n'a rien de comparable avec le temps d'accès à un fichier PHP depuis le WEB.

Ensuite, si tu dois vraiment afficher une liste de 100 DVD, tu fera un fichier cache de la liste en plus des 100 fichiers cache des DVD :wink: Et là, on va me répondre, quel intérêt si la liste change souvent ? hé bien si elle et aléatoire (cas d'un moteur de recherche) tu ne met pas en cache, si elle est mise à jour tous les 10 affichages en moyenne, tu gagne du temps et des ressources 9 fois sur dix ce qui reste toujours excellent. Maintenant, pense à toutes les pages qui ne sont modifiée mettons, qu'une fois par semaine, ou par mois voir jamais une fois qu'elles ont été crées !

Prends comme exemple le Forum de WRI. La première page d'un Topic lorsqu'elle est pleine n'est plus modifiée (sauf modération ou édition d'un Post). La première page du Topic concernant la V1 a été vue plus de 67000 fois. Avec ce système de cache, les ressources Mysql consommées sont réduites par 67000 (étalé sur plusieurs années bien sur) et si on multiplie par le nombre topics cela devient énorme en terme de gain. Par contre, l'intérêt d'un tel cache sur la page des dernier sujets de discussion est bien entendu bien moindre puisque le contenu change plus souvent.

Il faut donc structurer le cache intelligemment afin d'en tirer le quintessence (que je parle bien à 2h30 du matin moi :mrgreen: )

A cette heureci madri vient de se coucher, je suis seul sur le forum avec baidu, google, yahoo et MSN, et ils sont pas très causant :(
 
WRInaute accro
Ah mais ça je le fais avec la V1 la séparation données contenu.
La V1 j'utilise en combinaison avec un moteur de template.

Données : SQL
Présentation : template
Création dynamique : PHP
"Moteurs/fonctions" : PHP séparé

Et au choix, si cache, je file la dernière version HTML, sinon, je refais juste la version données, le moteur de template ayant son cache de compilation :D
Et si je vide tout, je regénère toutes les étapes.
 
WRInaute accro
Ahhhhh sympa comme système !!!

Je n'y aurais pas pensé... Et pourtant je l'utilise (la sérialisation) dans mes dévs. DotNet (mais en WinForms) ;)

Dans mes devs. web je préfère quand même "cacher" directement le code HTML (mais je n'ai pas non plus de sites avec des centaines de milliers de pages : l'impact n'est pas aussi important en terme d'espace disque, loin de là, et il n'est pas gênant de régénérer le cache de temps en temps)
 
WRInaute passionné
ba moi je reco ... ... ... ... mence :-) à tout coder : je passe à la v2 !

madri, met à jour le topic cirage de pompe (heu hommage) à fan de ciné avec le bon lien !
 
WRInaute impliqué
Bonjour,

Merci Fandecine. C'est à peu près ce que je fais, à savoir mettre les résultats MySQL dans des tableaux PHP qu'il faut rafraichir dès qu'il y a un update. Finalement, on se rapproche de plus en plus de la vue matérialisée proposés dans les grosses bases de données et qui est une solution 100% base de données que je souhaiterais voir apparaitre dans MySQL.
 
WRInaute passionné
steph@ne a dit:
à voir aussi memcached qui est le standard de facto

Memcached, c'est autre chose et son utilisation ne dispense pas d'utiliser un systéme de cache comme je le décris :wink:

D'autant que l'on parle ici de cacher des données sur le disque pas en mémoire :mrgreen:
 
WRInaute accro
Ah ben m... alors ! Faudra que je regarde la version de Cache_Lite que j'utilise, elle doit être préhistorique :mrgreen:

J'avais pas autant de fonctions dans "ma" version (qui sauf erreur ne faisait que le cache de bufferisation de sortie, enfin, l'équivalent à ob_start_content en php quoi, ou un truc du genre)
 
WRInaute discret
fandecine a dit:
steph@ne a dit:
à voir aussi memcached qui est le standard de facto

Memcached, c'est autre chose et son utilisation ne dispense pas d'utiliser un systéme de cache comme je le décris :wink:

D'autant que l'on parle ici de cacher des données sur le disque pas en mémoire :mrgreen:

[extraterrestre on]

Petite info memcached vient en complément de ce genre de cache et permet de soulager ton disque une fois que tu as tout manger avec tes accès aux caches fichiers. Il faut utiliser ce genre de scripts avec précaution sur des serveurs très chargés car les accès disques sont souvent ce qui fait ramer un serveur (je pense notamment au serveur de fichier et les file sort de mysql).

Memcached permet d'avoir une bande passante beaucoup plus grande qu'un disque est c'est une très bonne solution pour ce genre de "cache objet". Pour ceux qui disposent d'une seule machine il est préférable d'utiliser APC car les performances brutes sont plus grande (pas de gestion réseau) (CF:cache performance comparison).

Enfin pour apporter ma pierre à l'édifice je propose à ceux qui parlent couramment le php ++ (comme seebz, spout et fandecine) de me dire ce que vous pensez de ça : cache objet (si ça vous tentes bien sur :mrgreen:).
[extraterrestre off]

J'admire ton initiative fandecine (et ta patience), La communauté WRI te dois une fois de plus une fière chandelle. C'est trop rare ce genre de discussion sur les forums et c'est vraiment dommage.
 
WRInaute passionné
petitchevalroux a dit:
Petite info memcached vient en complément de ce genre de cache et permet de soulager ton disque une fois que tu as tout manger avec tes accès aux caches fichiers.

Certes, mais sur le site de mon profil (par exemple) le cache occupe 450 mo sur le disque. C'est pourquoi je ne le met pas en mémoire :wink:

Par contre j'utilise une autre classe (que je publierais peut-être un jour :mrgreen: ) qui gère un cache mémoire avec memcached (la première version se contentait de stocker dans le ramdisk /dev/shm/) dans lequel je cache les données pour les pages les plus vues avec un algorithme de type LRU (je garde en cache les données les plus souvent demandées).

Ensuite, le cache est structuré afin de ne pas faire plus de 3 appel de fichier cache par page (il y a des redondances) ce qui ne consomme pas plus d'accès disque qu'un include PHP.

Le tout est de trouver un bon compromis entre la puissance du serveur à disposition et les performances.

J'utilise également memcached de façon distante pour partager des données en serveurs :wink:

petitchevalroux a dit:
Enfin pour apporter ma pierre à l'édifice je propose à ceux qui parlent couramment le php ++ (comme seebz, spout et fandecine) de me dire ce que vous pensez de ça : cache objet (si ça vous tentes bien sur :mrgreen:).

Je vais faire plus que le regarder, je vais le tester :wink: (bien que je ne me sois jamais mis au MVC :oops: , faudrat donc que je l'adapte...)

petitchevalroux a dit:
J'admire ton initiative fandecine (et ta patience), La communauté WRI te dois une fois de plus une fière chandelle. C'est trop rare ce genre de discussion sur les forums et c'est vraiment dommage.

C'est aussi comme ça que j'apprends, en lisant des bouquins, en consultant des sites, des forums, en échangeant avec des amis informaticiens et j'ai aussi enseigné... dans le temps, et puis, j'aime bien l'exercice intellectuel car c'est également très formateur de rédiger des articles, de partager des connaissances. :wink:
 
WRInaute discret
fandecine a dit:
Certes, mais sur le site de mon profil (par exemple) le cache occupe 450 mo sur le disque. C'est pourquoi je ne le met pas en mémoire :wink:
C'est vrai que la mémoire est une ressource limitée mais si tu utilises plusieurs serveurs 450 Mo ce n'est pas si énorme que ça.

Si tu disposes d'une machine assez puissante (en générale les CPUs glandent pas mal sur nos machines) tu pourrais tenter d'utiliser la compression gz aprés serialize pour ton cache.

L'intérêt de cette compression c'est qu'elle permet d'avoir un cache objet plus petit et surtout les fichiers étant plus petits le nombre de bloc à lire sur disque est moins important. Au finale ça diminue donc les accés disques (Double effet kisscool :mrgreen: ).
fandecine a dit:
Par contre j'utilise une autre classe (que je publierais peut-être un jour :mrgreen: ) qui gère un cache mémoire avec memcached (la première version se contentait de stocker dans le ramdisk /dev/shm/) dans lequel je cache les données pour les pages les plus vues avec un algorithme de type LRU (je garde en cache les données les plus souvent demandées).

Ensuite, le cache est structuré afin de ne pas faire plus de 3 appel de fichier cache par page (il y a des redondances) ce qui ne consomme pas plus d'accès disque qu'un include PHP.

Le tout est de trouver un bon compromis entre la puissance du serveur à disposition et les performances.
L'avantage de memcached par rapport à /dev/shm c'est d'être distribué ce qui permet de ne pas dupliquer le cache. Au niveau perf pure je pense que /dev/shm est plus rapide (à vérifier) mais si on utilise plusieurs machines autant centraliser le cache ram en mémoire. Ma remarque sur memcached était juste pour signaler que le cache d'objet en mémoire n'était pas si différent que ça que ton système de cache fichier :wink:.
fandecine a dit:
Je vais faire plus que le regarder, je vais le tester :wink: (bien que je ne me sois jamais mis au MVC :oops: , faudrat donc que je l'adapte...)
Tu m'en vois ravi, pour information c'est du php5 mais je pense que le passer en php4 n'est pas la mer à boire (le seul problème que je vois c'est file_get_contents et file_put_contents). Pour l'adaptation à ton utilisation (vu que tu sembles utiliser des tableaux à la place de modèle) je pense que c'est assez simple. En faite si je compare mon code au tient la différence est plus sur la forme que dans le fond.

[je me la raconte on]
Je préfère ma forme (je ne suis pas du tout objectif là :mrgreen:) car le code de gestion du cache n'est qu'à un seul endroit (centralisation et maintenance plus facile) et les quelques fioritures en plus comme l'expiration du cache et le multiton sont assez efficaces :mrgreen:.
[je me la raconte off]

En relisant ton code je me demande pourquoi tu fais un implode ici (utilises tu php 4 ?):
Code:
$temp=implode("",@file("/home/cache/dvd/".clean($titre).".txt"));
 
WRInaute accro
petitchevalroux a dit:
Enfin pour apporter ma pierre à l'édifice je propose à ceux qui parlent couramment le php ++ (comme seebz, spout et fandecine) de me dire ce que vous pensez de ça : cache objet (si ça vous tentes bien sur :mrgreen:).
L'idée de gzipper le cache me semble nickel, gain de place énorme, mais avec un kimsufi j'aurais peur, ça ne bouffe pas trop de CPU ?
Si j'ai bien compris, chaque model doit extend ObjectCache, pas mal l'idée de sauvegarder les relations (tracks) aussi.
Bonne approche POO comme on aime :D

Tu utilises cette classe en production ?
Et pour tes requêtes SQL, tu utilises PDO ou un ORM (Doctrine) ?
 
WRInaute passionné
J'ai bien fait de pas continuer en fac d'info :p
En tout cas reco et merci à tous les codeurs ici de nous faire autant sentir qu'on n'est pas dans le même monde!
 
WRInaute discret
spout a dit:
petitchevalroux a dit:
Enfin pour apporter ma pierre à l'édifice je propose à ceux qui parlent couramment le php ++ (comme seebz, spout et fandecine) de me dire ce que vous pensez de ça : cache objet (si ça vous tentes bien sur :mrgreen:).
L'idée de gzipper le cache me semble nickel, gain de place énorme, mais avec un kimsufi j'aurais peur, ça ne bouffe pas trop de CPU ?
Si j'ai bien compris, chaque model doit extend ObjectCache, pas mal l'idée de sauvegarder les relations (tracks) aussi.
Bonne approche POO comme on aime :D

Tu utilises cette classe en production ?
Et pour tes requêtes SQL, tu utilises PDO ou un ORM (Doctrine) ?

PDO pour les requetes j'ai du mal avec les ORM.

J'utilise le gzip sur un RPS donc sur un kimsufi je pense que c'est super large à toi de voir mais je pense pas que tu vois la différence au niveau utilisation CPU ...

Et pour répondre à ta dernière question j'ai la même chose en prod depuis un long moment, mais ce ne sont pas exactement les même lignes de code ;). (Gestion d'un LRU dans le multiton ...)
 
WRInaute accro
Et puis cela répond a la règle primordiale de l'informatique (et aussi des standards du WEB) qui est la séparation du contenu (les données) et de leur présentation (la page WEB) ce qui n'étais pas le cas de la V1.
Oui et non, perso je pense que tu peu très bien sous traiter ce concept au niveau HTML / CSS qui dans ta version 1 ne posait pas de souci si tout était structuré a l'origine pour que la présentation soit entièrement sous le contrôle d'une feuille de style.

Sinon : étant en ce moment en plein dans cette problématique, j'interviens juste pour dire que les deux code que tu présentent ne me semblent pas intervenir du tout au même niveau.

La première version avait l'avantage de soulager la charge SQL et la charge liée à la mise en forme des données (sur un MVC, tu allégeait tant le travail du modèle que de la vue -> double impact et le controleur n'avait qu'a tester la présence du cache pour servir un contenu rapidement)
La version que tu propose (je ne l'ai pas décortiquée complètement), elle, semble parfaitement soulager le modèle mais pas la vue puisque la composition de la page n'est pas concernée (il me semble).

Il est vrai que la composition de la vue n'est pas forcement la partie la plus gourmande mais quitte a mettre en cache ... autant alléger au maximum.

Le point qui me chiffonne aussi est que la mise en oeuvre semble intimement lié au modèle (structure et nature des données) alors que le cache V1 était lui beaucoup moins lié à cela ce qui contredis un peut la valeur de séparation que tu met en avant ci dessus. puisque dans le script 1, peut importais ce que tu affichais.

Bref, je peut me tromper, mais deux très bonnes idées bien documentées mais qui semble dédiées a deux fonctions différentes.

Merci dans tous les cas :wink: .
 
WRInaute passionné
petitchevalroux a dit:
En relisant ton code je me demande pourquoi tu fais un implode ici (utilises tu php 4 ?):
Code:
$temp=implode("",@file("/home/cache/dvd/".clean($titre).".txt"));

J'utilise PHP 5. Pour ce qui est de l'implode, je le fais dans la classe uniquement pour uniformiser les fonctions de manipulation du cache (getVars et getAllVars).

@zeb : Tout a fait Thierry ! :wink:

L'implémentation de la version 2 est bien dépendante des données (le cache est géré avant la mise en forme des données) mais elle est indépendante de leur mise en forme. La version 1 est très facile à mettre en œuvre; la version 2 nécessite une refonte du code. La version 2 n'est donc pas une évolution de la V1 (je crois l'avoir précisé), c'est un autre concept pour atteindre le même résultat c'est à dire la diminution des ressources consommées par le serveur.

En fait, ce qui m'a poussé à développer la V2 c'est que je souhaitais faire en même temps du cache en mémoire et que la V1 consomme beaucoup de ressources de stockage inutiles et redondantes (la mise en forme). J'ai donc cherché à minimiser le volume du cache afin d'en déporter une partie en mémoire. Comme je l'ai évoqué, je superpose à ce cache disque un cache en RAM de taille fixe géré par un algo de type LFU afin ce cacher en RAM les données des pages les plus consultées.

Bien que le cache V2 fonctionne très bien tel quel, il est efficacement compété par un cache ram dont je publierais le source lorsque j'aurais un peu de temps libre :wink:
 
Nouveau WRInaute
Bonjour à tous,

Peut-être ai-je mal lu ce code qui m'interesse grandement mais j'y vois un inconvénient dans l'exemple utilisé :

Si le fichier cache d'un dvd existe et que l'enregistrement le concernant en BDD est modifié, ce sont les données de ce fichier qui seront affichées à l'affichage des informations du dit DVD et non les nouvelles infos stockées dans la BDD... cela veut-il dire qu'il faut supprimer les fichiers caches lors des mises à jours de données ?

P.S : bon je sais que les informations d'un DVD ne doivent pas changer tous les jours mais c'est surtout pour le fonctionnement de la méthode que se pose mon interrogation...

P.P.S : il ne serait pas génant sur un site de petite/moyenne ampleur d'avoir à supprimer les fichiers caches si le webmaster est la seule personne qui puisse mettre à jour les données mais pour les sites sociaux c'est rarement le cas (données utilisateur...)

D'avance merci du temps passé à me répondre ;-)
 
WRInaute passionné
LaFabriqueWeb a dit:
Bonjour à tous,

Peut-être ai-je mal lu ce code qui m'interesse grandement mais j'y vois un inconvénient dans l'exemple utilisé :

Si le fichier cache d'un dvd existe et que l'enregistrement le concernant en BDD est modifié, ce sont les données de ce fichier qui seront affichées à l'affichage des informations du dit DVD et non les nouvelles infos stockées dans la BDD... cela veut-il dire qu'il faut supprimer les fichiers caches lors des mises à jours de données ?

P.S : bon je sais que les informations d'un DVD ne doivent pas changer tous les jours mais c'est surtout pour le fonctionnement de la méthode que se pose mon interrogation...

P.P.S : il ne serait pas génant sur un site de petite/moyenne ampleur d'avoir à supprimer les fichiers caches si le webmaster est la seule personne qui puisse mettre à jour les données mais pour les sites sociaux c'est rarement le cas (données utilisateur...)

D'avance merci du temps passé à me répondre ;-)

Oui, il faut gérer le cache lors de la mise à jour de la BDD.

Il est évident que si tu utilise un CMS, la gestion du cache ne sera pas facile à mettre en œuvre. Si c'est du développement maison, rien de plus simple :wink:
 
Nouveau WRInaute
fandecine a dit:
Oui, il faut gérer le cache lors de la mise à jour de la BDD.

Il est évident que si tu utilise un CMS, la gestion du cache ne sera pas facile à mettre en œuvre. Si c'est du développement maison, rien de plus simple :wink:

Merci pour cette réponse, je n'utilise pas de CMS mais un développement maison permettant à des internautes inscrits de déposer des annonces, cependant je pense qu'il est possible de régler le soucis en automatisant la création des fichiers de cache lors de la validation d'un ajout d'annonce ainsi que lors de la modification (A force de réfléchir sur un soucis on lui trouve toujours une solution ;-))

Merci pour ce script bien utile
 
Discussions similaires
Haut