Quel est le bon équilibre entre la réutilisation de champs et la création de nouveaux champs dans le contexte de l'évolutivité des champs?


34

J'ai lu la phrase suivante sur un site web:

Au lieu d’ajouter de nouveaux champs à un type de contenu, l’ajout de champs existants est une meilleure option pour réduire la complexité du système et améliorer l’évolutivité.

Et quelques doutes surgissent.

Dans le système que nous développons, nous avons la possibilité de réutiliser un champ dans 3 ou 4 types de contenu, mais au lieu d'améliorer l'évolutivité comme le dit la phrase citée, je crains que cela ne le diminue, car le tableau du champ deviendrait plus rapidement un goulot d'étranglement. (du moins c'est mon raisonnement dans ce cas, car toutes les valeurs de ce domaine réunies seraient de quelques millions par an et cela rendrait le tableau trop volumineux). Êtes-vous d'accord?

Combien de lignes serait un maximum raisonnable à viser lors de l’architecture? De cette façon, nous pourrions décider quand réutiliser des champs et quand en créer de nouveaux (même si la possibilité de les réutiliser existe).


6
J'aimerais que les réponses soient sauvegardées avec des métriques réelles.
mpdonadio

Pensez que nous avons recueilli des commentaires très constructifs et informatifs autour de cette question. Cependant, j'attendrai un ou deux jours avant de marquer, car quelque chose en moi insiste sur le fait que garder un ou deux champs plus lourds séparés (bien qu'ils puissent être réutilisés) pourrait être une bonne idée :) ... spécialement en sachant ceux les dépôts de documents pourraient facilement augmenter de 5, 10 ou 20 millions d’articles par an.
Rafamd

Réponses:


24

La quantité de données dans un champ ne pose généralement pas de problème. Si cela vous inquiète, cherchez des plug-ins de stockage alternatifs ou écrivez les vôtres. Par exemple, MongoDB , qui peut traiter à peu près tout ce que vous y mettez. Il est par exemple utilisé sur http://examiner.com .

Un problème réel est cependant le nombre de champs que vous avez. Dans la version actuelle de Drupal 7, la configuration complète de tous les champs, qu'ils soient chargés ou non, est extraite du cache à chaque requête.

J'ai vu des sites avec plus de 250 champs, où charger et désérialiser la configuration de champs prend 13 Mo + en mémoire.

Edit: le cache d’informations sur les champs a été amélioré (voir http://drupal.org/node/1040790 pour plus de détails) avec Drupal 7.22, seuls les champs des ensembles affichés sur une certaine page sont chargés à partir du cache et entrées de cache séparées. Cela ne fonctionne que s'il n'y a pas d'appels d'API erronés qui demandent des instances sur plusieurs bundles.


Bonjour Berdir, merci pour ta réponse. Je ne connaissais pas cette surcharge pour le nombre de champs. Nous devrions donc essayer de réutiliser le plus possible, mais ne devrions-nous pas essayer de séparer ceux que nous savons être les plus lourds? Je ne connais pas grand chose au mongo, mais est-ce vraiment qu'ils ne se soucient pas de la taille d'un groupe à interroger? Merci !
Rafamd

Je ne sais pas réellement. Ça dépend, je suppose. Faire un test comme suggéré par MPD pourrait ne pas être une mauvaise idée. Vous pouvez même le comparer à très bas niveau directement dans Mysql. Créez deux tables avec la même disposition et les mêmes index que les tables de données de champ, écrivez 10 m (assurez-vous d'utiliser des valeurs différentes pour entity_id) dans une ligne et 5 m dans la seconde. Comparez ensuite les performances d’écriture et les performances de lecture (en fonction de l’entité entity_id, également appelée index). Je soupçonne que les performances en lecture seront presque égales grâce à l'index, mais les performances en écriture pourraient faire la différence.
Berdir

Cela dit, avoir une poignée de champs plus ou moins ne fera pas vraiment une différence, donc si vous vous sentez plus à l'aise de cette façon, cela ne devrait pas poser de problème.
Berdir

Les écritures sont la partie la plus délicate, d’où ma recommandation de faire un test. Ce qui peut être contre-intuitif est le fait que MySQL supprime les entrées en cache basées sur table et non sur ligne (la dernière fois que j'ai vérifié). Je ne suis pas sûr de ce qui serait un impact plus important: la surcharge de mémoire de plusieurs champs et tables ou les erreurs de cache dues aux écritures dans la même table. Cela dépend sûrement du trafic et de l'utilisation. Les systèmes avec plusieurs caches (cache Drupal, code d'opération APC, utilisateur APC, cache de requête MySQL, memcached, vernis, etc.) rendent les décisions intestinales très difficiles sans profilage.
mpdonadio

Ce n'est plus le cas: drupal.org/node/1040790
jackbravo

13

Je suis totalement d'accord avec berdir. Voici mon expérience avec un projet avec des millions de lignes et 30 à 40 champs sur certains types de nœuds.

  1. Le nombre de lignes dans une table de champs n'est pas un gros problème pour les performances de lecture, car tous les champs sont extraits par la clé primaire.
  2. Le nombre de champs par type de nœud peut rapidement dégénérer en gros problèmes de performances lors de l'écriture de nouveaux nœuds. Avoir plus de 30 champs pour un type de nœud donne plus de 60 instructions INSERT lorsque vous créez un nouveau nœud. Cela prend quelques secondes à compléter. Si vous créez beaucoup de données, vos performances en souffriront. Les insertions en bloc de 1 000 nœuds prendront presque une heure. Si vous devez mettre à jour 100 000 nœuds, c'est un gros problème.
  3. Si vous pensez que le problème de nombre de champs va vous toucher, vous devriez sérieusement songer à écrire votre propre espace de stockage ou simplement ne pas utiliser de champs. (Vous pouvez toujours faire en sorte que votre noeud utilise des vues avec un effort supplémentaire.)
  4. Un mot sur MongoDB. C'est un projet très intéressant et j'espère qu'il fera partie de l'olympique des grandes DB. Malheureusement, comparé à la maturité de MySql ou de PgSql, c'est un bébé. Soyez prêt à faire face à un très jeune produit.

Bonjour @ BetaRide, merci pour votre perspicacité. À propos de 2), nous essayons déjà de minimiser le nombre de champs par type de contenu et ce n’est pas exactement ce dont nous discutons ici. La vraie affaire est la suivante: dois-je réutiliser aveuglément des champs chaque fois que cela est possible ou dois-je essayer de garder (au moins) le ou les deux plus lourds séparés (même s'ils peuvent facilement être identiques, par exemple: ils portent en fait le même nom, etc.). Ouais, le mongo devrait être notre dernière alternative pour le moment :)
rafamd

5

Si vous vous inquiétez vraiment de ce qui va arriver, alors je pense qu'une simulation est en ordre.

Obtenez un compte sur Rackspace Cloud, Amazon, Linode ou ailleurs, vous pouvez facilement créer un VPS. Faites deux instances identiques. Installez Drupal sur chacun. Créez des types de contenu factice et configurez les champs d'une manière dans un système et d'une autre dans l'autre. Utilisez le module de développement pour créer un chargement de contenu. Ajustez les paramètres de performance pour vous assurer que Drupal met en cache si nécessaire. Exécutez mysqltuner et ajustez MySQL sur chacune des recommandations. Vérifiez deux fois les paramètres PHP et APC afin de ne pas frapper le swap et de ne pas vider le cache APC.

Une fois que vous obtenez une bonne configuration de base pour chacun, commencez à simuler le trafic (visiteurs normaux et mises à jour administratives) avec wget et drush, puis profilez.

Les simulations ne sont jamais parfaites, mais elles peuvent vous faire avancer dans la bonne direction.


2

Un problème d’évolutivité dans les champs lors de l’utilisation d’index sur chaque champ de table dans chaque champ créé dans la table. L'index en cluster de clé primaire est un composite de la plupart des champs, puis il a créé des index distincts sur chaque champ. Les index créent une tonne d'écritures supplémentaires pour la base de données et, dans la plupart des cas, ne sont jamais utilisés.


2

Un autre conseil: avoir un grand nombre de champs causera également des problèmes avec de nombreux modules différents. L’interface graphique de jetons, par exemple, retardera votre navigateur pendant quelques minutes si vous essayez d’éditer des alias d’URL, par exemple. Ce comportement est visible sur toutes les pages où le jeton sera chargé et affiché (y compris devel - dpm (), etc.).

Il n’ya aucun avantage en termes de performances à fractionner ces données entre plusieurs tables lorsqu’on utilise InnoDB (MyISAM est différent en raison du verrouillage de la table). Donc, si vous savez que vous aurez beaucoup de types de contenu similaires avec des champs similaires (les configurations seront également identiques, peut-être différeront-elles par leur étiquetage uniquement), réutilisez vos champs!

Cela pourrait également faciliter la création de modèles en raison d'attributs de nœud similaires.


1

Tout en partageant mon histoire, nous utilisons Drupal Commerce et avons environ 40 champs dans nos variantes de produits (sku), puis 460 autres (oui, fou) dans notre affichage des produits. Nous avons eu des comparaisons de produits qui porteraient sur tous ces domaines. Sans la mise en cache, le chargement de certaines pages peut prendre jusqu'à une minute!

Cependant, cela a fonctionné. Si vous utilisiez la mise en cache et Varnish, le temps d'attente des utilisateurs n'était pas si mauvais.

Le principal problème que nous avons rencontré avec tant de champs concerne Display Suite, car cela deviendrait très lent (parfois non réactif) si nous essayions de réorganiser ou de déplacer un champ.

Heureusement, nous avons décidé de retarifier un peu nos produits afin que nous puissions espérer avoir notre nombre maximum de champs dans la gamme 200-250 pour nos produits les plus complexes (nous sommes en instrumentation scientifique, des mesures et spécifications précises sont donc nécessaires). .


0

C'est une question intéressante. J'ai déjà pensé à cela, parfois, réutiliser un champ peut être pratique pour ne pas avoir des charges de champs similaires "traîner", mais il semble idiot de faire en sorte qu'un certain type de contenu doive sélectionner parmi une grande quantité de données savoir n'est pas destiné à être retourné dans le résultat.

J'aurais besoin d'un peu plus d'informations sur le projet pour vous conseiller sur les meilleures pratiques en matière de dimensionnement. Quel est le trafic attendu, combien de ces utilisateurs doivent être connectés, etc.? Par exemple, si tout le trafic, à l'exception de celui de vos utilisateurs administrateurs, n'est pas authentifié et mis en cache de manière anonyme.


Bonjour @ Drupaljoe, merci pour votre réponse. Le trafic attendu est difficile à estimer car il s’agit d’un tout nouveau site. Il est développé avec beaucoup de soin et nous attendons un succès, disons que nous parvenons à avoir quelques centaines d'utilisateurs simultanés (la plupart d'entre eux authentifiés). C’est exactement ce que je pensais: interroger cette immense table doit être une tâche difficile, alors nous devrions peut-être l’architecte réutiliser les champs qui ne grossiront pas trop et séparer ceux qui contiendront plus de données. Qu'est-ce qui pourrait être trop considéré? 1 million ? 100 millions ? 300 millions ? ...
rafamd

Je pense que les commentaires des deux autres sur le fait que cela ne devrait pas avoir trop d'importance parce que les sélections sont sur la clé primaire sont de bons points. J'imagine que je dirais simplement d'y aller pour le moment, mais assurez-vous que vous avez bien lu vos options pour l'avenir, notamment pour les champs, etc. Vous ne pouvez pas toujours deviner tout ce qui concerne l'avenir de votre site
joevallender

0

Jusqu'à présent, j'ai toujours réutilisé les champs, mais j'envisage maintenant d'utiliser des champs uniques par type de nœud pour un nouveau projet. En fait, je veux que tout soit bien séparé (champs, vues, règles, contextes, etc.) pour chaque groupe d'entités. Cela a donc soulevé la question de l'évolutivité qui m'a amené ici. Je suis rassuré par l'édition de Berdir (le cache d'informations de champ a été amélioré ( pour plus de détails, voir http://drupal.org/node/1040790 ) avec Drupal 7.22, seuls les champs des ensembles affichés sur une certaine page sont chargés à partir de le cache et leurs entrées de cache distinctes. Cela ne fonctionne que s'il n'y a pas d'appels d'API erronés qui demandent des instances sur plusieurs bundles).

Je tiens simplement à souligner qu’il existe un module très intéressant que j’utilise depuis des mois sur plusieurs sites complexes: https://www.drupal.org/project/render_cache . C'est un de ces joyaux cachés à mon avis.

Comme il est indiqué sur la page du projet, la partie commentaires est en fait utilisée sur DO lui-même.

Alors, avec tout cela à l'esprit, cela tournerait-il le consensus en faveur de champs séparés? La mise en garde à propos de DS est toujours une déception, cependant. C’est super agaçant de savoir comment il enregistre via ajax au lieu, par exemple, de la façon dont l’interface d’administration des blocs principaux gère les commandes. Je pense que cest un problème ds, cependant ...


-3

Selon ma suggestion, utiliser les mêmes champs dans des types de contenu distincts est une bonne idée. Parce que cela améliorera les performances de votre site. Dans Drupal 7, lorsque vous utilisez cette opération, l’utilisation de champs identiques dans le type de contenu est vraiment utile pour votre site Drupal7.


1
Dans Drupal 7, ils ont commencé à utiliser Doctrine ORM ... non. Drupal 8 n'utilise même pas Doctrine
Clive

"Doctrine renvoie toujours l'objet à partir de toutes les données mappées", est également une fausse déclaration. Les objets peuvent être annotés pour indiquer à la doctrine que le comportement par défaut ne convient pas. Non, ce n'est pas très pertinent, étant donné que, comme le dit Clive, Drupal n'utilise pas Doctrine.
Létharion
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.