Accueil
Bio
Articles
Projets
Contact

Article

De la refonte du panneau de gestion à la refonte de tout le système cellulaire

551 8

[Cellul'z] publié le 11/07/2012 à 15h42
"L'homme est à la recherche d'un nouveau langage auquel la grammaire d'aucune langue n'aura rien à dire." - Guillaume Apollinaire

Probablement la plus grosse mise à jour de Cellul'z depuis ses débuts : les optimisations sur le panneau de gestion ne suffisent pas, il faut voir plus loin.

Avertissement : Cet article a été publié il y a déjà un certain moment.
Il se peut que son contenu ne reflète plus exactement ma pensée actuelle.

J'en parle depuis trois jours sur Twitter,

Je me suis lancé dans le développement d'une mise à jour conséquente de tout le système cellulaire de Cellul'z. Vous vous souvenez sans doute des problèmes du panneau de gestion et de son chargement extrêmement long ? Il était clairement inutile d'essayer d'optimiser quoi que ce soit, le système n'était pas compatible avec ce qu'il est possible de réaliser pour un site web1 : un nombre de requêtes proportionnel au nombre de cellules, ça sature très rapidement.
Dans ce billet, je vais décrire sans honte les choses qui ont été réalisées et qui posent aujourd'hui problème et vous exposer les solutions qui ont été trouvées. Je vais faire en sorte que ce ne soit pas trop technique quand même. Le cas échéant, n'hésitez pas à poser vos questions !

Les problèmes du système en place


Au chargement du panneau de gestion, une première requête SQL sélectionne toutes les infos se rapportant à vos cellules : nom, id, date de naissance, état, ressources possédées, durées associées, ribosomes, etc. Elle s'alourdit avec le nombre de cellules mais ce n'est pas conséquent. Le problème réside dans la mise à jour des données : chaque cellule étant très individualisée (ses propres ressources, ses propres délais..), il faut les mettre à jour une par une. Une requête SQL par cellule, c'est une calamité quand vous en avez des centaines.. et c'est ce qui fait que votre page met 150 ans à charger.

Image utilisateur
fig.1 Sans optimisation, ça crashe très tôt.


Les phases d'optimisation (la dernière y a 4-5 jours) consistaient à diminuer les requêtes SQL nécessaires par cellule afin d'obtenir une courbe un peu moins croissante.. mais nécessairement, à un moment donné, ça crashe quand même. Rajoutez à ceci les situations ponctuelles comme l'activation de cellules après la mitose ou la mise à mort après asphyxie et ce sera lent encore plus rapidement.

Image utilisateur
fig.2 C'est mieux mais la finalité est toujours la même.


Comme si ça ne suffisait pas; il était également impossible d'envisager un système de chargement alternatif mêlant Ajax et cache puisque toutes les données doivent être rechargées pour un affichage correspondant exactement à la situation à l'instant t -et non pas daté d'il y a 30 minutes ou chargé à la demande de l'utilisateur.

Bref, vous comprenez la situation : il ne faut pas un système qui dépende du nombre de cellules.

Tout globaliser ? Non !


Avec Fab, nous nous sommes retrouvés face à la solution la plus évidente : il faut se détacher du système individualisé côté cellules. On résume simplement le nombre de cellules possédées à un nombre associé au membre et pas de détail à la cellule. L'interface pourrait être contenue en une phrase : "vous possédez x cellules".. et en fonction de ça, les quantités de molécules à fournir.
C'est bien beau puisque ça prend pas de place en base de données, niveau algorithmique c'est enfantin et côté chargement, même le devblog serait lourd en comparaison. Néanmoins, avec un tel système, ce serait beaucoup de choses annexes qui sautent : plus de couleur -donc plus de concours !!-, plus de ribosomes indépendants... Bref, rien. Et ça, ce n'est pas encore envisageable, on s'est attaché à ce système et c'est devenu l'objectif principal de Cellul'z d'avoir ses cellules.
Ceci dit, j'avais déjà souligné l'idée d'une globalisation à la fermeture de la beta 2 le 11 Mars dernier :

Je réfléchis à cette idée depuis quelques jours : les cellules sont-elles trop individualisées dans Cellul'z ? Chaque cellule a un nom, un âge, etc. N'est-ce pas un peu trop maintenant que le jeu prend une dimension plus importante.. et que les élevages sont gigantesques ? Cela peut aussi être une des raisons des ralentissements de certaines pages : trop de détails inutiles à afficher.. et tout n'est pas encore fait. Imaginez un système immunitaire par dessus toutes ces cellules : on fonce un peu dans le mur.
Citation : Flavio46


Du brainstorm au brainshake : la solution intermédiaire


On est vraiment resté buté sur cette idée : impossible de continuer avec le système actuel et impossible de passer au système précédemment décrit.
Or, voilà qu'il y a trois jours, j'ai eu l'idée de génie : on peut faire du semi-globalisé ; alléger le système tout en conservant autant d'informations et autant de fonctionnalités. Ce système est basé sur plusieurs points : les cellules ont de nombreuses informations mais une partie d'entre elles est constante (nom, couleur, date de naissance,..) et une autre partie est variable (données relatives à la respiration cellulaire). Ainsi, en globalisant seulement les données variables, on peut garder les cellules en tant qu'entités individuelles et alléger le traitement de la respiration cellulaire.
En gros, au lieu de gérer la respiration cellulaire au cas par cas, il faudra admettre que vous gérerez la respiration cellulaire de tout l'élevage à la fois.. ce qui est quasiment déjà le cas puisque personne ne s'amuse à alimenter ses cellules individuellement2. Pas de perte réelle de fonctionnalités, et une seule requête SQL à faire lors du traitement de la respiration cellulaire : modifier les valeurs une fois pour tout l'élevage.

Image utilisateur
fig.3 Le nombre de requêtes est faible et constant : ça ne crashe plus avec les gros élevages !


C'est la solution idéale à ce niveau : on peut toujours "voir" ses cellules avec leurs petits détails, leurs petites statistiques et elles vivent sur des paramètres communs -et non plus variables- entre elles.

L'interface a déjà été modifiée en conséquence, ça permet de prendre plus de libertés (moins de données à afficher, autant en profiter !) et dans la configuration choisie, d'afficher l'élevage de façon visuelle -bye bye le tableau dégueulasse.

Image utilisateur
fig.4 Aperçu du panneau de gestion -le it's something affichera l'âge de la cellule par exemple.


C'est quand même plus sympa non ?

Les autres avantages de ce système, c'est la possibilité de toujours pouvoir envisager les futurs systèmes de la même façon qu'avec le système que vous avez connu -ce qui aurait été loin d'être le cas avec le système globalisé totalement. J'ai d'ailleurs pondu une liste importante des avantages de ce système à Fab et ça n'a pas fait un pli -pour une fois que nous tombons d'accord du premier coup !-, c'est vraiment le meilleur chose que je dois tenter de développer.

Les difficultés qu'il reste à surmonter


Ça aurait été trop beau s'il avait suffit de modifier un script de 40 lignes. Il est acquis que la page du panneau de gestion ne pose plus de problèmes au chargement -tout n'est pas fait mais je suis confiant, c'est pas deux requêtes qui vont tout faire sauter.
Les problèmes annexes résident dans le fonctionnement des ribosomes3 : comme pour la respiration, chaque cellule possède un ribosome avec de nombreux paramètres variables comme la chaîne d'ARN en traitement ou les acides aminés traduits. Quand on demande aux ribosomes de travailler ou que les acides aminés sont comptabilisés, chaque ribosome est traité individuellement et au chargement, ça se remet à ramer : plus d'une minute pour 4000 cellules4.. parce que 4000 requêtes SQL, c'est excessivement trop.
Je réfléchis actuellement à des solutions alternatives, je me retrouve dans la même configuration qu'il y a quelques jours : impensable de tout globaliser et impensable d'éliminer un tel aspect du jeu.
Alors que faire ? Stocker les ARN dans des fichiers .txt ? Le problème, c'est que ça pèse vite plusieurs Mo.. même si la solution reste tentante5. Trouver un moyen de globaliser de façon transparente le traitement de l'ARN ? C'est ce que je voudrais, je cherche la meilleure manière d'y parvenir.. d'autant qu'afficher tout cet ARN, ce n'est rien du tout, ça fonctionne déjà très bien sur le nouveau panneau de gestion. Je vais peut-être trouver la solution avant d'avoir écrit la fin de ce billet, ce n'est pas impossible smiley ! Toujours est-il qu'en attendant, et depuis hier, c'est ma préoccupation principale.

Bilan de ces changements


Malgré la question des ribosomes, je ne peux m'empêcher de penser que cette évolution est loin d'être une impasse. Un contretemps dans le développement ? On peut considérer ça comme ça dans la mesure où de simples optimisations auraient bien plus rapides à mettre en place. Mais pour le coup, il n'y avait plus le choix. Au-delà du stockage dans la BDD, je souhaite vivement qu'il n'y ait pas de limites dans le nombre de cellules pouvant être créées. Avant cette évolution, on pouvait espérer tenir jusqu'à 2000 cellules. Aujourd'hui, je veux repousser la limite à 10.000 cellules, ce qui n'est franchement pas rien en comparaison. Plus encore ? Je doute que ce soit nécessaire -puis là, la base de données souffrirait vraiment, mais je veux que dans la théorie, ce soit envisageable, malgré les chiffres énormes impliqués. Et cette amélioration le permet peut-être très largement.
En outre, en dehors des performances, il permet de ramener Cellul'z aux éléments essentiels de la gestion en supprimant des éléments qui semblent aujourd'hui totalement désuets, tout en remettant en avant des choses qui n'avaient pas pu l'être : je prends les paris, aussitôt le jeu réouvert et les concours relancés, vous serez contents de voir votre élevage prendre quelques couleurs.

Un dernier point positif ? J'aimerais toujours mettre en place les fameux élevages cogérés. Ce sera bien plus simple de le faire avec un tel système smiley ! Il en va d'ailleurs de même pour la mise en place du cœur.. si c'est un contretemps, disons que c'est un petit mal pour un grand bien !

Conclusion


Cela retarde encore un peu le reste mais comme vous l'avez déjà constaté, l'avancement est observable et ne concerne pas uniquement que le code. Ça rend la chose plus intéressante, même pour moi qui suis à la place de développeur, de voir que ça progresse concrètement.
Je vous recommande vivement de suivre attentivement mon compte Twitter si vous souhaitez avoir les screenshots en temps réel.

J'écrirai certainement un billet dans peu de temps pour vous tenir au courant. D'ici là, à bientôt !

1. Ou en informatique en général.
2. On dit merci les fonctions globales.
3. Pareil pour la mitose mais il se contourne plus facilement celui-ci.
4. Il était impossible d'afficher 4000 cellules sur l'ancien panneau de gestion. Aujourd'hui, les doigts dans le nez.
5. Traiter un fichier, c'est plus rapide que traiter en base de données si je ne dis pas de conneries.

Autres articles dans la même catégorie :
Orchestre symphorganique (20/01/2014)
Période de développement, session hiver 2014 (12/01/2014)
L'Amino-Loto (13/06/2013)

Commentaires

Smarties
11/07/12, 11h39

smiley

Tab41
12/07/12, 11h12

Salut Flavio, content de voir que ça avance bien de ton coté, j'ai vu l'ouverture du forum va falloir que j'aille y faire un tour smiley

Par contre petite question concernant ton soucis de ribosomes "plus d'une minute pour 4000 cellules.. parce que 4000 requêtes SQL, c'est excessivement trop". Je ne connais pas la structure de ta base, mais en ayant tes 4000 cellules à la base tu as leur id je pense et du coup tu pourrais une requête SQL qui te retourne les 4000 lignes, après faut voir le temps de traitement en PHP...

Sinon fichier ou base c'est kiffe kiffe si la base est bien faite, faut juste vérifier les index, éviter les énumérations et utiliser pas mal les clés, classique quoi.

Flavio46
12/07/12, 06h28

@Smarties : ça ne me fait même plus sourire, surtout sur un billet comme ça.


Salut Tab41, ça faisait presque longtemps smiley !

Sélectionner 4000 cellules/ribosomes ne pose aucun souci puisque ça se fait en une requête.. c'est le fait d'enregistrer 4000 molécules d'ARN ou 4000 quantités d'acides aminés différentes qui l'est plus -c'est déjà bien plus long que ça ne devrait l'être- et, à moins que je sois mal informé, je ne peux pas faire autrement qu'une requête répétée en boucle. Le traitement en PHP quant à lui est tout à fait bidon donc ça ne pose pas de problèmes.

Flavio46
13/07/12, 12h27

Bonne nouvelle,

J'ai vérifié suite à ton commentaire et effectivement, je me suis rendu compte qu'il pouvait manquer un index -ça m'a déjà fait gagner un temps fou- et j'ai réussi à caser une requête préparée dans le lot, qui manquait clairement. Fini l'attente d'une minute (70 à 80 secondes), ça charge maintenant en 3-4 secondes smiley !

Ça veut dire que je n'ai pas besoin de revoir mon système à hauteur de 4000 cellules -ouf !-, je vais pouvoir tester avec quelque chose comme 8500 cellules.. voir si le double est encore tenable ou si SQL se couche. Mais je suis déjà bien satisfait de pouvoir dire que gérer 4000 cellules, c'est faisable les doigts dans le nez !

Chris
13/07/12, 01h12

Ca devient de l'optimisation de base de données après, mais y'a des techniques ou même des bases spécialement prévue pour ça. Ce qui est couteux pendant un insert, c'est la mise à jour des index.
Pour des très gros insert (plusieurs millions de lignes), une des technique consiste à détruire les indexes, insérer en bloc, et les recréer. Après, je pense pas que Cellulz en soit là ;)

Flavio46
13/07/12, 03h01

Un million de cellules, c'est pas si long que ça à obtenir smiley !..

Pour le coup, j'ai pas de problèmes d'index, les updates que je fais n'y touchent pas du tout mais comme ça accélère la sélection de données qui se fait juste avant, le fait d'en rajouter judicieusement peut me faire gagner.. beaucoup plus de temps que je ne l'aurais cru !
En revanche, la requête préparée que j'ai ajoutée a l'air de ralentir plus qu'autre chose, peut-être à cause des valeurs des variables que je dois changer à chaque fois.
Tout le souci est là en fait, il faut déterminer quelles solutions sont intéressantes !

Maelia
29/07/12, 11h10

Hello,
Je viens de lire ton article, et je me permet de te poster une petite idée.
Je ne sais pas comment c'est géré dans ta base de données, mais pour éviter d'avoir a updater de très nombreuses fois ta base de données, tu peux stocker des date au lieu d'entiers.
Exemple : Ta cellule gagne 4 glucose par heure.
Tu stockes en base une dateDebut qui correspond au moment ou ta cellule à 0 glucose.
Puis, à l'affichage, quand tu demandes combien de glucose ont tes cellules, tu fais juste un select de toutes tes cellules, puis coté php, tu fais le calcul de glucose entre la date_heure du moment et la dateDebut. Rien à updater.
Ce n'est juste quand tu va utiliser du glucose par exemple, que tu va "repousser" la dateDebut d'autant qu'il le faut...
Je sais pas si j'ai été clair et si cela peut s'appliquer à ton cas...
a+ smiley

Flavio46
30/07/12, 12h22

C'est comme ça que ça fonctionne -et que ça a toujours fonctionné pour le coup- mais merci du commentaire, ça fait plaisir de lire des idées constructives smiley !

Pour préciser, y a bien une date qui gère la consommation (et donc ce fameux calcul de différence entre l'heure actuelle et l'heure que tu appelles dateDebut pour obtenir l'avancement). Elle est mise à jour (s'aligne) à chaque consommation de glucose, ce n'est pas ça qui était lourd à traiter en soi.. c'est le fait que cette opération devait être répétée plusieurs milliers de fois avec des dates différentes !
Avec la mise à jour -effectuée maintenant-, j'ai ramené le nombre d'exécutions de cette opération qui était variable (une fois au début puis très vite 1000, 2000, 4000 fois..) à un nombre fixe ce qui fait que, quelque soit le nombre de cellules et la consommation de glucose correspondante, l'opération se déroule toujours de la même façon et donc à la même vitesse. En gros, au lieu d'avoir un dateDebut par cellule, j'ai un dateDebut pour tout l'élevage et foncièrement, ça ne change rien au fonctionnement du jeu.

Encore une fois, merci du message et à bientôt peut-être smiley !

Pseudo :
Recopier « ocaipl » à l'envers :