optimisation site web / mysql

WRInaute accro
Bonjour,

Je suis a 2 doigts de partir en vacance donc pas sur que ce soit le bon moment d'ouvrir un nouveau sujet mais bon ça fait 15 jours que je me triture les neurones sans résultat (beurk c'est sale) et je me dis que peut être l'un de vous a déjà la solution et est prêt a la partager sur le plan théorique.

Bref , ...

contexte :
Je customise mon CMS et j'en suis a la phase 2 qui consiste a virtualiser totalement le CMS.
Dans un premier temps j'ai adapté ce qu'il fallait pour me débarrasser de nombreux fichiers en utilisant la réécriture d'url.
Dans un second temps je souhaite pousser le jeu un peut plus loin en virtualisant les domaines.
CAD que de multiple domaines genre truc.com et bidule.fr pointent tous sur le même dossier du même serveur et le CMS fait le reste.

Pour cela, que ce soit en mode mono domaine, ou multi domaine j'ai mis en place un composant frontal (genre contrôleur) qui intercepte tout et réagi en fonction.
A la sortie du contrôleur j'ai le nom de domaine, le document voulu, l'extension désirée (xml, html, php, wml, txt, asp etc ...) J'y gère aussi le cache, les sessions, la compression, les stats, les anti aspi, le blacklistage sélectif, ... brefs tous les gadgets utiles qui peuvent servir mais :

Mais je souhaite alléger le truc car a ce moment je dois transmettre les infos nécessaires et utiles aux classes du modéle pour ensuite générer la vue (si document pas en cache par exemple ou simplement que le cache est sur OFF voir qu'on arrive en POST donc que le document va changer).

A ce moment donc le contrôleur va chercher en base l'information concernant le document a savoir l'id de la base le contenant (bases généralement limitées a 100 Mo donc possibilité de ranger les documents d'un même site ou de plusieurs sites dans différentes bases)

La structure et les données de la base contenant cette information fait que j'ai une marge d'environ 15 000 000 de pages possibles (tous domaines confondus) donc pour elle c'est cool les bases annexes elles contiendront le contenu et ne sont pas limitées en nombre donc pas de souci de "site qui déborde" .

seulement je sais par expérience que quand la base des pages va être un peut plus grosses cela va considérablement affaiblir la mécanique.

Donc je suis a la recherche d'une solution pas idiote et innovente qui me permettrait ne me dispenser d'une connexion a la base pour cette opération a chaque visite d'une page.

Pour donner un ordre de grandeur, le système est amené a gérer des petits domaines genre 20 pages jusqu'a des trucs de 200 000 pages (précision importante je pense quand on imagine remplacer un accès SGBD par un truc a base de fichier par exemple).

Si vous avez une idée je suis preneur.
 
WRInaute accro
FloBaoti a dit:
Ben tout système de cache fera l'affaire... memcached par exemple...
blog.plumbr.com/26-memcache-un-vrai-systeme-de-cache-performant-et-facile-a-utiliser-avec-php a dit:
Donc en gros, memcache un système de cache qui stocke les données en ram pour être rapide. On fait donc tourner un daemon sur notre serveur, on se connecte dessus (tcp) et lui envoie et/ou demande des données, c’est extrêmement simple.
memcache-un-vrai-systeme-de-cache-performant-et-facile-a-utiliser-avec-php
Pas possible de faire tourner un service sur le système hébergeant.

Donc je pense (sauf erreur) que ça exclus l'utilisation de la RAM pour mettre en cache quoi que ce soit de façon persistante. Comme je cherche a éviter la base (du moins a en éviter l'usage systématique) il reste que le fileSystem et là le souci est que n'ayant pas la possibilité d'avoir une quantité infinie de fichier (j'en ai forcement besoins d'un pour le contenu précalculé) il faut que je trouve autre chose ou que je mette tout dans un fichier facilement identifiable via l'url demandé.
 
WRInaute accro
zeb a dit:
(j'en ai forcement besoins d'un pour le contenu précalculé)
C'est la qu'est a mon avis la faille dans ton raisonnement ...

Oublie qu'un fichier est à usage unique et considère donc plutot un fichier comme un "blob" dans lequel tu range ce que tu veux ... rien ne t'empeche de regrouper plusieurs infos dans le meme fichier avec en entete du fichier un systeme d'adressage :

info1
offset1
taille1
info2
offset2
taille2
etc

(un peu à la façon des chaine pascal si tu as pratiqué)

Du coup le nombre de fichier redevient raisonnable.

Perso j'ai un de mes site basé exclusivement sur du stockage en .txt et qui si je devais le transposer en Bdd aboutirait à une bdd avec une trentaine de table dont une avec 5 millions de records et l'autre avec 1 million de records d'une 10zaine de chalmps chacune... (et je ne parle pas volontairement de slogs qui eux n'ont pas leur place en bdd)

Bien évidemment je n'ai pas généré 6 millions de .txt sur le disque du serveur (je sais meme pas si c'est accepté !!). Au total, ca doit pas dépasser les 50.000 ou 60.000 txt bien rangés dans des repertoire et sous repertoire avec jamais plus de 2000 txt par repertoire (limite symbolique psychologique pour que ca soit pas trop lourd a manipuler).

Comme il ya bien sur des mises à jours et pour faciliter les sauvegardes, j'ai déjà regroupés tous les txt dans deux repertoire :

data_in : les données qui ne sont qu'en lecture (alimentées par une base de données externe locale)
data_out : les txt qui sont mouvementés par le site en dynamque (des messages, des saisies diverses, des historiques etc etc et justement des "caches maison") ...

Et ca roule du feu de dieu ...

A mon avis c'est ce type de piste que tu peux creuser.

PS : Bon c'ets vrai que je suis un peu déformé surement m'étant occupé durant des années de bases de données (au niveau structure interne et optimisation des table d'index s'entend) et du coup j'ai une facheuse tendance a considérer un simple doc .txt comme un espace de structuration de données :roll: :mrgreen: (et si tu y regardes de plus près toute base de données n'est in fine qu'un concaténation de petits bouts de machins organisés en blocs de petite taille ... même si c'est customisé pour donner une impression de truc global).
 
WRInaute accro
zeb a dit:
Bonjour,
Je suis a 2 doigts de partir en vacance
Bon oublie ce que j'ai dit ... va bronzer ... on en reparle à la rentrée parce que la c'est pas compatible avec neurones en vacances :mrgreen: :mrgreen:
 
WRInaute accro
Zecat a dit:
zeb a dit:
(j'en ai forcement besoins d'un pour le contenu précalculé)
C'est la qu'est a mon avis la faille dans ton raisonnement ...

Oublie qu'un fichier est à usage unique et considère donc plutot un fichier comme un "blob" dans lequel tu range ce que tu veux ... rien ne t'empeche de regrouper plusieurs infos dans le meme fichier avec en entete du fichier un systeme d'adressage :

info1
offset1
taille1
info2
offset2
taille2
etc
Genre codage d'une FAT ou approchant dans un header de fichier qui permet de trouver rapidement la position des données et leur taille. Pas idiot du tout.

Le souci (ou, là ou j'ai du mal a conceptualiser) c'est que regrouper toute les datas d'une page passe encore (en m'appuyant sur l'url je peut trouver facilement le fichier si il est nomé intelligemment et je peut y écrire tout ce que je veux sous n'importe quelle forme) mais je ne voie pas comment choisir le fichier où se trouve les datas désirées sans un index quelconque (qui soit pas en base) et ceci a la volé si je suis dans un cas "cachable" (donc pas en post ou en présence d'une page ne possédant pas de cache pour l'instant (première visite ou cache purgé))

Dans la structure que tu montre, si je suis a la recherche de info12 et que chaque fichier contient 10 info il va falloir ouvrir le fichier 1 lire l'entête, et passer au suivant avant de trouver l'offset et la taille des data 12. Donc si j'ai bien compris ton idée je vais devoir brasser beaucoup de fichier avant de trouver l'info que je cherche, et encore une fois si j'ai bien compris, je suis pas certains d'être plus éfficent que MySql sur ce coup.
 
WRInaute accro
A toi d'organiser tes datas de façon efficace pour ce que tu veux en faire (perso je considère que l'on doit arriver a tructurer l'info de telle sorte que si tu sais a quelle data tu veux accéder, tu dois savoir dans quel txt ca se trouve en un coup et donc pouvoir mettre en place un accès direct un peu comme tu le ferais avec des pointeurs ...

Je ne connais pas le détail de ton cas particulier mais par principe je ne connais pas de cas ou des datas ne sont pas structurable en txt dès lors qu'elle sont organbisable en bdd (c'est kif kif ... y a que le support qui change).

Ensuite faut tenir aussi compte des forces et faiblesses du langage mis en oeuvre pour attaquer les datas.

Bon même si en php je suis rank 1 (bon la j'exagère désormais un peu :wink: ), en modele de données, je me considère comme 8 ou 9 (normal après 30 ans de pratique ...). Mais bon j'ai déjà repéré en php que le couple "explode / for each" est plutot performant (toutes proportions gardée par rapport aux langages compilés) et donc faut en tenir compte dans la façon de structurer ... quitte a prevoire des explodes en cascade a 2 ou 3 niveaux :wink:

A mon avis dans la plupart des cas (pas tous mais la plupart) ca sera plus efficient pour la simpel raison que tu ne stocke et gere que les infos utiles à ton besoin alors que dès que tu mets en bdd, la bdd decide d'autorité de se préparer à répondre a tes demandes dévolutions (tiens et si on se tappait une recherche fulltexte, etc etc). C'est a mon avis la seule différence entre bdd et txt (avec txt la souplesse d'evolution est bien moindre et plus lourde ... mais pour un systeme figé ..)
 
WRInaute accro
Pour illustrer la chose, je ne sais pas si tu as vu passer un topic ou on discutairt avec jcaron d'un besoin que j'avais de gérer le sbits ...

Hypothèse 1 : Bdd mysql. Une table avec 8 millions de records, un champs bool pour dire traité / pas traité. et comme besoin juste de pouvoir tester si tel ou tel record est traité ou pas.

Hypothèse 2 : Un doc Mamap.txt de 1millions d'octets. Un bit par info de type oui/non. Pour tester si oui/non sur un record :
- accès a l'octet voulu pui sau bit et test ...

Pas sur que mysql aille plus vite ... et soit moins gourmand en place (moins gourmand en place c'est virtuellement impossible sauf a embarquer une compression/decompression temps réel mais la c'ets coté perf que ca va pêcher !)

PS : Un indcex n'est a nouveau qu'un vulgaire paquet de datas non ? Donc ca se structure aussi en txt si on veut. :mrgreen:
 
WRInaute accro
Zecat a dit:
Je ne connais pas le détail de ton cas particulier mais par principe je ne connais pas de cas ou des datas ne sont pas structurable en txt dès lors qu'elle sont organbisable en bdd (c'est kif kif ... y a que le support qui change).
Bah j'ai pas grand chose qui "sort du contrôleur" en fait.
Si on enlève toutes les datas lié au visiteur / navigateur etc (la littérature) Il me reste trois variables pour trouver le bon fichier et localiser les données :

le nom de domaine sous la forme : http://www.example.com
le nom de la ressource du style : dossier/sous-dossier/une-page-parmi-les-autres (décomposable mais pas forcement utile)
le nom de l'extension désiré du document du style : php ou asp ou txt ou html etc ...

donc rien de numérique a priori (a mois de jouer avec un Hash peut être) et je dois sortir un contenu lié au format demandé (en fonction de l'extension désiré) pour y appliquer éventuellement un traitement (gestion des parties forcement dynamiques)
 
WRInaute accro
Zecat a dit:
Hypothèse 1 : Bdd mysql. Une table avec 8 millions de records, un champs bool pour dire traité / pas traité. et comme besoin juste de pouvoir tester si tel ou tel record est traité ou pas.

Hypothèse 2 : Un doc Mamap.txt de 1millions d'octets. Un bit par info de type oui/non. Pour tester si oui/non sur un record :
- accès a l'octet voulu pui sau bit et test ...

oui là je voie bien si le record X est situé a l'emplacement X du fichier Map tu extrait vite l'info pas de souci.

Mais comment a partir d'une URL extraire ne serais ce qu'une valeur sur 8 ou 16 bits sur un ou plusieurs fichiers ??
 
WRInaute accro
zeb a dit:
Zecat a dit:
Hypothèse 1 : Bdd mysql. Une table avec 8 millions de records, un champs bool pour dire traité / pas traité. et comme besoin juste de pouvoir tester si tel ou tel record est traité ou pas.

Hypothèse 2 : Un doc Mamap.txt de 1millions d'octets. Un bit par info de type oui/non. Pour tester si oui/non sur un record :
- accès a l'octet voulu pui sau bit et test ...

oui là je voie bien si le record X est situé a l'emplacement X du fichier Map tu extrait vite l'info pas de souci.

Mais comment a partir d'une URL extraire ne serais ce qu'une valeur sur 8 ou 16 bits sur un ou plusieurs fichiers ??
tu aurais pas un cas concret parce que la dans le vide une valeur sur 8 ou 16 bits ... a 2h du mat en plus ...

Concret je veux dire du style : voila en entrée j'ai ca (mets 3 datas bidons qu'on voit bien) et je veux pouvoir obtenir ceci.
 
WRInaute accro
zeb a dit:
Mais comment a partir d'une URL extraire ne serais ce qu'une valeur sur 8 ou 16 bits sur un ou plusieurs fichiers ??
Peut etre si cette extraction est figée et identifiée, la générer en amont lors de la création des datas et donc la question n'ets plus d'aller extraire une info de plusieurs doc mais d'aller lire LE donc contenant les infos déjà extraite de façon redondahte en txt ... une sorte de reverse index ...

Enfin je sais pas si c'est adapté à ton cas, mais tout est creusable ...

Et de toute façon dès que tu gères des grosses cardinalités, si tu traque spas le bit et l amillisecondes tu aboutit a un systeme qui rame ou explose à un momemnt ou a un autre ... donc creuser pour creuser :mrgreen:
 
WRInaute accro
donc creuser pour creuser :mrgreen:

Lol oui.
Bref faut que je décroche pour ce soir, départ demains matin a la fraîche, merci pour tes pistes je te donnerai des news quand j'aurais creusé et trouvé.
En tous cas tu as raison faut s'organiser dans les donnée pour trouver la perf et je prendrai le temps qu'il faut pour y arriver.

C'est sûrement mon dernier Post de la quinzaine qui viens donc Merci a toi et au forum et bonne vacances à ceux qui ne sont pas encore parti, bon courage a ceux qui reviennent.
 
WRInaute accro
Zecat a dit:
zeb a dit:
Mais comment a partir d'une URL extraire ne serais ce qu'une valeur sur 8 ou 16 bits sur un ou plusieurs fichiers ??
Peut etre si cette extraction est figée et identifiée, la générer en amont lors de la création des datas et donc la question n'est plus d'aller extraire une info de plusieurs doc mais d'aller lire LE doc contenant les infos déjà extraite de façon redondahte en txt ... une sorte de reverse index ...

Oui c'est la solution que j'ai adoptée (merci pour les 1000 et une idées qui m'ont donné LA solution).

Pour conclure et peut être donner des idées a d'autres voici un récap du problème et de la solution adoptée.

- minimiser autant que faire ce peut l'usage de la base de données et si possible s'en passer dans certains cas.
- sauvegarder des données utilisables en un lieu facilement trouvable.

A l'entrée j'ai juste une URL demandée donc une référence a la déclinaison d'un document (txt, xml, html, ...)
Je dois faire a ce moment un choix de traitement en fonction de différents paramètres (POST / GET par exemple, ...)

sans le dispositif que je cherchais a mettre en place, le CMS fait de nombreuses requêtes pour trouver les paramètres nécessaires les traiter et accomplir les taches demandées en fournissant une vue comme résultat.
Le dispositif doit donc être capable de répondre rapidement a une demande utilisateur en GET (aucun traitement) ou de fonctionner normalement en minimisant les requêtes redondantes si d'autres traitements sont a prévoir.

Le dispositif doit donc permettre le stockage facile de variables et de contenu "standards".
J'ai donc décidé de stocker mes données sous cette forme dans un fichier php construit dynamiquement permettant suite a inclusion un traitement direct :
Dans ce fichier on trouve des variables simples (data1, data2, etc ...), une variable $base qui me permet de savoir dans quelle base de données sont mes datas (leur double en fait) (si vous avez tout lu vous aurez remarqué" que j'ai l'impératif d'avoir accès a plusieurs bases pour des tables similaires situées sur différents serveurs d'ou le besoins de la variable $base )

Code:
<?php
$data1 = "truc";
$data2 = "machin";
$base="123";

$vue['html'] ="<html ..... </html>";
$vue['xml'] ="<xml ..... </xml>";

etc ...

Un autre impératif serveur était de minimiser le nombre de fichier et de pouvoir héberger beaucoup de documents / pages.
Mon hébergeur me donne que 260 000 fichiers possible sur ce serveur (bonjour si il faut publier 400 000 pages).

j'ai donc du combiner un système pour regrouper les données de plusieurs pages dans un même fichier et le trouver facilement et rapidement (pour l'include)

en entrée j'avais une url donc un truc du genre http://www.example.com/dossier/document.ext

j'ai donc pris le parti de décomposer cela de la façon suivante :
www.example.com/dossier/document
et
ext
le Hash MD5 de http://www.example.com/dossier/document me donnera un code permettant d'identifier le document de façon unique
les 4 premiers caractères du Hash me donneront une clée permetant d'identifier le fichier contenant les infos cherchées et constitura le chemin d'accès au fichier.
Un exemple pour faire simple :

soit le Hash de mon url qui donne : ad24d7b76df52bd3a7101ef89dc8c784
le fichier php contenant les datas sera nommé : ad24.php
le chemin sur le filesystème sera : /mon-dossier-de-base/a/d/2/4/ad24.php

Cette technique engendre le fait que deux urls peuvent concerner le même fichier (en vérité si tout se répartie bien 6 urls vont exister dans chaque fichier vue que l'arbo de dossier va engendrer 65536 dossiers et sous dossiers pour mes 400 000 pages de postula, ce qui en fonction de la mémoire dispo et de la taille des données est gérable sur le serveur utilisé)

seulement la structure des fichier donnée en exemple ci dessus doit être modifiée pour pouvoir fonctionner (voir code ci dessus).

la nouvelle structure de données est donc la suivante :

Code:
<?php
$data1['ad24d7b76df52bd3a7101ef89dc8c784'] = "truc";
$data2['ad24d7b76df52bd3a7101ef89dc8c784'] = "machin";
$base['ad24d7b76df52bd3a7101ef89dc8c784']="123";

$vue['html']['ad24d7b76df52bd3a7101ef89dc8c784'] ="<html ..... </html>";
$vue['xml']['ad24d7b76df52bd3a7101ef89dc8c784'] ="<xml ..... </xml>";

$data1['ad24*******************************'] = "autretruc";
$data2['ad24*******************************'] = "autremachin";
$base['ad24*******************************']="13";

$vue['html']['ad24*******************************'] ="<html ..... </html>";
$vue['xml']['ad24*******************************'] ="<xml ..... </xml>";

$data1['ad24...................................................'] = "encoreuntruc";
$data2['ad24...................................................'] = "encoreunmachin";
$base['ad24...................................................']="6";

$vue['html']['ad24...................................................'] ="<html ..... </html>";
$vue['xml']['ad24...................................................'] ="<xml ..... </xml>";

etc ...

le fichier est constituée au fil de l'eau avec un fopen en mode 'append' donc les données vont s'ajouter au fur et a mesure en fonction des demandes formulées.

conclusion :

le contrôleur va en fonction de la situation charger le fichier en include, déclencher un traitement a partir des variable ou simplement faire un echo si la situation le permet et détruira le fichier si cela s'impose (genre attaque en POST donc modifications des données)

Un des souci est que qu'une modif entraîne la perte totale des données pour entre une et 6 pages (mais bon ...)

niveau rendement j'avais dans les cas les plus lourds jusqu'a 6 secondes pour avoir ma page, là avec ce système j'écourte un peut dans le cas de modification de données (temps divisé par presque deux) mais c'est carement de la folie dans les cas les plus standard (consultation simple) ou en moyenne le temps pour obtenir le document est divisé par 3 en comparaison d'opération full base.

Bref c'est pas miraculeux mais si ça peut donner des idées ce sujet ne sera pas peine perdue.

Merci a Zecat et aux autres pour le remue méninges qui m'a donnée cette soluce simple et pratique :wink:
 
Discussions similaires
Haut