Fermer

mars 17, 2020

Traverser le gouffre des performances avec les utilisateurs / groupes de masse dans AEM


Dans mon article précédent, Amélioration de la création d'utilisateurs en masse dans AEM 200x j'ai expliqué comment nous avons amélioré un processus d'importation de milliers de groupes et d'utilisateurs dans Adobe Experience Manager. Cette accélération drastique a permis à notre projet de passer les tests de développement et nous nous sentions bien dans la production.

Malheureusement, dès que nous avons eu accès à l'ensemble des utilisateurs de la production, nous sommes tombés sur un autre piège de performance. Notre ensemble de données sur la non-production comprenait environ 2 000 groupes, tandis que la production en comptait plus de 4 000. Pire encore, il y avait un facteur moins d'associations de groupes d'utilisateurs <-> dans la non-production. Les données de production comportaient près de 100 000 000 d'associations de groupes d'utilisateurs <->tandis que la non-production n'en comptait que moins d'un dixième.

Alors que notre travail de création d'utilisateurs se terminerait en environ 30 minutes, le travail de synchronisation des membres du groupe a pris le relais.

En observant l'exécution du travail, le travail a toujours suivi le même schéma, le travail effectuerait des centaines de modifications / seconde pendant environ les 30 premières minutes, complétant jusqu'à la moitié des mises à jour, mais les performances chuteraient, conduisant à seulement une poignée de mises à jour par seconde pour le temps d'exécution restant, ce qui a pris des jours.

 Graphique des mises à jour au fil du temps

Notre première tentative a été d'optimiser le code existant, mais très vite nous avons constaté que les micro-optimisations n'allaient pas nous aider à surmonter le problème de blocage , il a fallu trop de temps pour ajouter les membres au groupe, nous avons donc fait preuve de créativité dans la recherche de solutions différentes.

Tentative de solution n ° 1 – Multithreading

Notre première tentative de correction a été de créer plusieurs threads, chacun pour gérer l'appartenance à un seul groupe, pensant que le problème était qu'il y avait des groupes particuliers à l'origine des performances. problèmes et si nous pouvions contourner ces groupes, nous pourrions résoudre le problème.

Sur nos environnements locaux, par rapport aux données de non-production, cela semblait être un correctif, cependant, il était déchiqueté lors de l'exécution contre l'ensemble de données de production et

Il est intéressant de noter que cela provoque en fait un blocage important des E / S en raison de lectures excessives, malheureusement, notre surveillance limitée n'a pas pu déterminer ce qu'était . tant lu.

Tentative de solution n ° 2 – importXML

Sachant que nous étions confrontés à un problème d'E / S, nous avons recherché des options pour réduire la quantité d'E / S. Après enquête sur le code Jackrabbit Oak, nous avons découvert que Group.addMembers parcourait la totalité des membres du groupe sur chaque ajout pour détecter si l'autorisable était déjà membre du groupe.

Pour remédier à cela, nous avons étudié en utilisant Workspace.importXML pour importer à la place une représentation XML Sysview entièrement formée du groupe et de l'appartenance au groupe.

Encore une fois, cela s'est révélé extrêmement prometteur lors des tests locaux:

 ] Graphique de la performance importXML

Et encore une fois, face aux données de production, importXML a été réduit à une exploration. Bien que plus rapide, il a fallu des jours pour terminer, bien en dehors de notre fenêtre de trois heures.

Eureka! Adhésion à un groupe dynamique!

Pendant ce temps, nous progressions régulièrement via Adobe, pour finalement obtenir du temps avec Adobe Engineering à Bâle. Lors de l'appel, Adobe Engineering a largué une bombe, il s'agit d'un problème connu avec AEM.

Le problème concerne le nombre de connexions de groupe d'utilisateurs <->. Plus précisément, avec la façon dont Jackrabbit Oak utilise en interne les index pour stocker l'appartenance au groupe et n'est pas quelque chose que nous pourrions optimiser. Après quelques allers-retours, l'équipe d'Adobe Engineering a proposé l'appartenance au groupe dynamique comme solution alternative.

l'appartenance au groupe dynamique fonctionne entièrement différemment de l'appartenance au groupe Jackrabbit Oak par défaut. Dans Dynamic Group Membership, les groupes d'utilisateurs sont stockés dans une propriété rep: externalPrincipalNames et résolus au moment de l'exécution.

Cette approche élimine le besoin d'ajouter les utilisateurs aux groupes, ce qui entraîne une augmentation massive des performances .

La meilleure chose est que cette option est facile à configurer, définissez le Identity Sync Type dans la configuration OSGi du gestionnaire d'authentification Adobe Granite SAML 2.0 sur Sync idp externe chêne pour SAML- authentification basée sur. Pour l'authentification basée sur LDAP, cochez la case Appartenance dynamique utilisateur dans le Gestionnaire de synchronisation par défaut Apache Jackrabbit Oak pour votre configuration LDAP.

Une fois que vous avez configuré l'appartenance au groupe dynamique, les informations pertinentes existantes les utilisateurs devront être resynchronisés (par exemple supprimés et rajoutés) car l'appartenance au groupe Jackrabbit Oak par défaut prévaudra.

 Configuration du gestionnaire d'authentification Granite SAML

Que faire si l'appartenance à un groupe n'est pas dans l'IDP?

L'implémentation par défaut de l'appartenance à un groupe dynamique, telle qu'implémentée dans le Granite SAML Authentication Handler suppose que l'assertion SAML contient toutes les informations pertinentes, y compris l'appartenance au groupe.

Malheureusement, dans notre cas, l'appartenance au groupe n'est pas stockée dans Active Directory car Active Directory est utilisé à l'échelle de l'entreprise, alors que ces groupes étaient spécifiques à notre application. Cela présentait un problème car l'attribut rep: externalPrincipalNames est protégé au niveau JCR et n'est accessible que par les services en liste blanche.

Entrez le fournisseur principal

Sous le capot, Dynamic Group L'adhésion enregistre un service PrincipalProvider pour exposer l'appartenance au groupe de l'utilisateur en fonction de l'attribut rep: externalPrincipalNames de l'utilisateur. L’interface du fournisseur principal fait partie de API de gestion principale de Jackrabbit Oak . Les implémentations de fournisseur principal sont appelées pour exposer les principaux (utilisateurs et groupes) et leur appartenance à un groupe.

Pour prendre en charge l'appartenance à un groupe externe à l'assertion SAML sans avoir à superposer des parties importantes du granit SAML Authentication Hander, nous avons simplement dû implémenter notre propre instance de fournisseur principal. Pour éviter tout impact lors des déploiements, nous l'avons implémenté en tant que bundle distinct du code de projet principal et l'activateur du bundle a défini le bundle Start Level sur 15.

 Diagramme de la solution de synchronisation des groupes d'utilisateurs

Qu'est-ce que cela signifie pour moi?

Pour les clients AEM qui doivent prendre en charge un grand nombre d'utilisateurs / groupes (100 000 + utilisateurs, plus de 2 000 groupes) le passage à l'appartenance à un groupe dynamique réduira considérablement le temps requis pour synchroniser les utilisateurs et les groupes par rapport à l'appartenance au groupe Jackrabbit Oak par défaut. ce qui est disponible à partir de l'IDP.




Source link