Scalabilité & haute disponibilité


Faire évoluer une installation TOSIAM vers un déploiement de production consiste à traiter séparément les deux couches décrites dans Composants et couches : la couche IAM se scale horizontalement en dupliquant des nœuds identiques et sans état, la couche de données se scale par réplication — et pour le Core Token Store, par sharding, seule technique qui permette d’absorber une charge d’écriture qui croît linéairement avec le nombre d’utilisateurs actifs.

1. Ferme de serveurs TOSIAM

Le concept de Site

TOSIAM reprend la notion de Site héritée d’OpenAM : un site regroupe l’ensemble des nœuds placés derrière un même load balancer et partageant une URL de site unique (l’URL publique du LB). Cette URL de site est celle utilisée dans les redirections, les cookies et la validation des redirect_uri — chaque nœud doit savoir qu’il fait partie d’un site pour ne pas générer de redirections vers sa propre URL interne.

# Créer un site
ssoadm create-site --sitename production --siteurl https://sso.example.com

# Rattacher un ou plusieurs nœuds existants au site
ssoadm add-site-members --sitename production --servernames https://node1.internal:8443

# Vérifier la composition d'un site
ssoadm show-site-members --sitename production

# Lister tous les sites déclarés / voir le détail d'un site
ssoadm list-sites
ssoadm show-site --sitename production

Mise en place de la ferme

  1. Provisionner N nœuds identiques. Même version, même configuration applicative, connectés au même Config Store (voir Composants et couches) — la configuration étant partagée, un nœud rejoint la ferme sans étape de synchronisation manuelle.
  2. Rattacher chaque nœud au site avec add-site-members une fois le premier nœud initialisé.
  3. Configurer le load balancer :
    • Sonde de santé sur un point de contrôle dédié (GET /tosiam/isAlive.jsp200 OK avec « Server is ALIVE » si le Config Store répond, exception non interceptée → 500 sinon). À noter : cette sonde ne vérifie que la connectivité au Config Store (lookup LDAP sur ou=services), pas celle au User Store ni au CTS — elle ne suffit donc pas, seule, à garantir qu’un nœud est pleinement opérationnel.
    • Répartition de charge round-robin ou least-connections ; aucune affinité stricte n’est requise puisque le CTS est partagé et accessible par tous les nœuds.
    • Persistance de session (cookie) recommandée mais optionnelle : elle réduit le nombre d’allers-retours vers le CTS pour les flux d’authentification multi-étapes (chaînes, graphes avec plusieurs nœuds d’interaction), mais un nœud peut à tout moment traiter la requête d’un utilisateur initialement servi par un autre nœud, car tout l’état pertinent est en CTS.
    • Terminaison TLS au LB ou pass-through selon la politique de sécurité ; si TLS est terminé au LB, transmettre les en-têtes X-Forwarded-Proto/X-Forwarded-Host pour que TOSIAM reconstruise des URL cohérentes avec l’URL de site.
  4. Répéter sur chaque site géographique si le déploiement est multi-datacenter : chaque datacenter a son propre site TOSIAM, son propre load balancer local, et partage (ou non, voir sharding CTS ci-dessous) la même couche de données selon la stratégie choisie.

2. Réplication des bases

Config Store

Faible volume, faible taux d’écriture : une topologie en réplication multi-maître (MMR) simple entre 2 ou 3 instances TosDJ suffit largement, y compris répliquée entre datacenters. Chaque nœud TOSIAM référence la liste complète des réplicas dans son pool de connexion (primaire + secours), avec bascule automatique en cas de perte d’un réplica.

dsreplication s’utilise en deux temps : enable déclare la relation de réplication entre les deux instances (ports, ports de réplication dédiés, ACIs), puis initialize copie effectivement les données de la source vers la destination — enable seul ne suffit pas, la seconde instance reste vide tant que initialize n’a pas été lancé.

# 1. Déclarer la réplication entre les deux instances TosDJ du Config Store
dsreplication enable --adminUID admin --adminPassword ***** --baseDN dc=tosit,dc=org \
  --host1 cfg1.internal --port1 4444 --bindDN1 "cn=Directory Manager" --bindPassword1 ***** \
  --replicationPort1 8990 \
  --host2 cfg2.internal --port2 4444 --bindDN2 "cn=Directory Manager" --bindPassword2 ***** \
  --replicationPort2 8990 \
  --trustAll --no-prompt

# 2. Initialiser cfg2 à partir de cfg1 (copie des données existantes)
dsreplication initialize --adminUID admin --adminPassword ***** --baseDN dc=tosit,dc=org \
  --trustAll --hostSource cfg1.internal --portSource 4444 \
  --hostDestination cfg2.internal --portDestination 4444 -n

# Vérifier l'état de la réplication
dsreplication status --hostname cfg1.internal --port 4444 --adminUID admin --adminPassword *****

À noter : --baseDN porte ici sur le suffixe racine complet de l’instance (ROOT_SUFFIX, ex. dc=tosit,dc=org), pas sur un sous-conteneur — chaque base (Config Store, CTS, User Store) est une instance TosDJ à part entière avec son propre root suffix répliqué en bloc, pas une branche partagée au sein d’une même instance. --replicationPort1/--replicationPort2 sont les ports dédiés au flux de réplication (distincts du port d’administration) ; --trustAll évite une confirmation interactive de certificat, nécessaire dès lors que le script tourne en mode non interactif avec des certificats internes.

Points d’attention : surveiller le retard de réplication (replication lag), dimensionner la purge du changelog en fonction de la fenêtre de tolérance aux coupures réseau, et prévoir une sauvegarde régulière indépendante de la réplication (la réplication propage aussi les suppressions accidentelles).

User Store

  • TosDJ interne : même mécanisme de réplication MMR que le Config Store.
  • Annuaire externe (Active Directory, LDAP tiers) : la réplication est gérée par l’infrastructure existante (réplication multi-DC AD, par exemple). TOSIAM n’a besoin que d’une liste de serveurs de secours par realm, avec pool de connexions et heartbeat de détection de panne — configurée sur le service Identity Store (ldapv3) du realm, pas dans un fichier .properties :
Attribut du service ldapv3Rôle
sun-idrepo-ldapv3-config-ldap-serverServeur(s) LDAP (host:port), avec bascule vers les suivants en cas d’indisponibilité
sun-idrepo-ldapv3-config-connection_pool_min_size / ..._max_sizeTaille du pool de connexions
openam-idrepo-ldapv3-heartbeat-interval / ..._timeunitFréquence de la sonde de connexion active, pour détecter un contrôleur en panne

Ces attributs se configurent via la console d’administration (Identity Stores du realm) ou ssoadm update-datastore, pas via des clés Java arbitraires.

Comme le User Store est majoritairement lu, il tolère bien l’ajout de réplicas en lecture seule pour absorber la charge des requêtes d’authentification et de profil sans surcharger l’annuaire maître.

3. Sharding du Core Token Store

Pourquoi shardé le CTS

Le CTS concentre le trafic d’écriture le plus élevé de toute l’installation : une entrée créée à chaque authentification, mise à jour à chaque validation ou renouvellement, lue à chaque introspection de token stateful. Au-delà d’un certain volume d’utilisateurs actifs simultanés, la réplication seule (qui multiplie les écritures sur chaque réplica) ne suffit plus : il faut répartir l’espace des tokens sur plusieurs ensembles CTS indépendants, chacun ne portant qu’une fraction du trafic.

Le mécanisme réel : partitionnement hors-ligne d’un export LDIF

Il n’existe pas de commande ssoadm dédiée au sharding du CTS. Le mécanisme réellement fourni est un outil CLI autonome, LdifPartitioner (module tosiam-cli-impl, package org.tst.tosiam.sharding) :

java org.tst.tosiam.sharding.LdifPartitioner <répertoire-source> <nombre-de-répliques> <répertoire-sortie>

Il relit des fichiers .ldif (typiquement un export du CTS) et répartit chaque entrée :

  • les entrées dont le DN contient coreTokenId= sont routées vers l’un des N fichiers de sortie cts-target-<i>.ldif, selon hash(DN) mod N (hachage du DN complet de l’entrée — pas d’un tokenId isolé, ni de fonction crc32) ;
  • toutes les autres entrées de l’export sont dupliquées dans chacun des N fichiers de sortie.

Il n’y a aucune distinction par type de token (SESSION/OAuth2/SAML2/UMA) : toute entrée coreTokenId= est traitée de façon uniforme, quel que soit le type de token qu’elle représente. Ce n’est pas non plus un routage en temps réel décidé requête par requête : c’est un traitement batch, destiné à préparer ou redistribuer les données CTS avant de charger chaque réplica de shard — typiquement lors d’une migration ou d’un re-partitionnement.

Je n’ai pas trouvé, dans le code exploré, de composant applicatif qui recalculerait un hash à chaque requête pour choisir dynamiquement un shard en fonctionnement normal — ce point (routage des lectures/écritures au quotidien, une fois les shards peuplés) mériterait d’être vérifié auprès de l’équipe TOSIAM avant d’être documenté plus précisément.

Chaque shard reste lui-même répliqué

Le sharding répartit la charge, la réplication assure la disponibilité : chaque shard CTS est donc lui-même un petit ensemble MMR (généralement 2 à 3 instances TosDJ), exactement comme le Config Store, mais dimensionné pour sa seule fraction du trafic.

                        ┌──────────────────────────┐
                        │   Ferme TOSIAM (Site)     │
                        └─────────────┬─────────────┘
                                       │  hash(DN) mod 4 (LdifPartitioner, hors-ligne)
              ┌────────────┬──────────┼──────────┬────────────┐
              │            │          │          │            │
        ┌─────┴─────┐┌─────┴─────┐┌───┴───┐┌─────┴─────┐
        │  Shard 0  ││  Shard 1  ││Shard 2││  Shard 3  │
        │ (MMR x2)  ││ (MMR x2)  ││(MMR x2)││ (MMR x2)  │
        └───────────┘└───────────┘└───────┘└───────────┘

Dimensionnement et bonnes pratiques

  • Capacity planning : estimer le nombre d’opérations CTS par seconde (créations + validations + renouvellements) attendu en pic, diviser par le débit soutenable d’une instance TosDJ (de l’ordre de quelques milliers d’opérations/s selon le matériel), et en déduire le nombre de partitions nécessaires.
  • Re-partitionner impose un nouveau passage de LdifPartitioner sur un export à jour, suivi du rechargement des shards — ce n’est pas une opération à chaud ; prévoir une fenêtre de maintenance et sur-dimensionner le nombre de partitions dès la conception limite la fréquence de ces migrations.
  • Isolation des pannes : la perte d’un shard entier (ses deux réplicas MMR simultanément) invalide uniquement les sessions/tokens qui s’y trouvent, pas l’ensemble de l’installation — c’est un compromis à documenter auprès des équipes applicatives.
  • Purge (reaper) : vérifier auprès de l’équipe TOSIAM comment le job d’expiration des tokens se comporte une fois le CTS partitionné sur plusieurs ensembles indépendants (ce détail n’a pas pu être confirmé dans le code exploré).

Check-list de déploiement HA

  • Config Store répliqué (MMR, 2+ instances), liste de secours configurée sur chaque nœud TOSIAM
  • User Store répliqué ou raccordé à un annuaire déjà hautement disponible, pool de connexions avec retry
  • CTS partitionné hors-ligne via LdifPartitioner (hachage du DN, sans distinction de type de token) si le volume de sessions le justifie
  • Chaque shard CTS répliqué en interne (MMR)
  • Ferme TOSIAM déclarée en Site, load balancer configuré avec sonde de santé dédiée
  • Capacity planning documenté (ops/s par shard, nombre de partitions, marge de croissance)
  • Supervision de la réplication (lag) et des jobs de purge CTS par shard
Modifier cette page sur GitHub