L'évolution des plateformes d'observabilité est passée de grands entrepôts de données cloisonnés et d'indices propriétaires coûteux à des architectures lakehouse unifiées qui combinent la flexibilité des lacs de données avec la performance des entrepôts. Les premiers fournisseurs d’observabilité SaaS s’appuyaient sur des clusters Elasticsearch ou Splunk, qui faisaient face à des courbes de coûts exponentiels à l'échelle du pétaoctet et avaient du mal à garantir une véritable isolation multi-locataire. L'émergence de formats de table ouverts comme Apache Iceberg et Delta Lake a permis des transactions atomiques et un voyage dans le temps sur le stockage d'objets, tandis que des moteurs de requêtes comme Trino ont maturé pour fournir un SQL interactif sur le stockage cloud. Cette convergence a créé la possibilité de servir des milliers de locataires à partir d'une infrastructure partagée unique, mais a introduit de nouveaux défis pour maintenir une latence inférieure à une seconde tout en imposant des frontières de sécurité strictes et en optimisant les coûts de stockage grâce à un tiering intelligent.
Le défi principal réside dans la réconciliation des exigences conflictuelles : ingérer des millions d'événements par seconde provenant d'agents divers (Fluentd, Prometheus, OpenTelemetry) tout en fournissant des performances de requête interactives sur des exaoctets de données historiques. Les bases de données traditionnelles sans partage s’effondrent sous le bruit de requêtes inter-locataires, tandis que les silos par locataire créent une surcharge opérationnelle prohibitive. Une isolation stricte exige que les requêtes du locataire A ne puissent pas physiquement analyser les données du locataire B, mais les filtres de sécurité au niveau des lignes introduisent souvent des pénalités de performance. De plus, stocker toutes les données sur des SSD chauds est économiquement impossible, mais déplacer les données froides vers Amazon S3 Glacier risque de violer le SLA inférieur à une seconde lorsque les données archivées sont soudainement interrogées. Le service de catalogue — qui suit les partitions et l'évolution du schéma — doit rester décentralisé pour éviter de devenir un point de défaillance unique ou un goulet d'étranglement de débit pendant l'ingestion à haute vélocité.
Architecturer un lakehouse en plusieurs niveaux utilisant Apache Iceberg comme format de table assis sur Amazon S3, Azure Data Lake Storage, ou Google Cloud Storage. Ingérer des flux via Apache Kafka ou Amazon Kinesis, en traitant à travers Apache Flink ou Spark Streaming pour placer les données dans le niveau approprié : chaud (local NVMe SSD sur les nœuds de requête), tiède (S3 Standard), ou froid (S3 Glacier Instant Retrieval). Déployer Trino ou Presto comme moteur de requête distribué, configuré avec Apache Ranger ou AWS Lake Formation pour des politiques de sécurité au niveau des lignes et des colonnes qui imposent des frontières entre locataires au niveau des scans. Mettre en œuvre un catalogue fédéré utilisant la fédération Hive Metastore ou AWS Glue avec des répliques régionales pour éviter les goulets d'étranglement centralisés. Le tiering automatisé est piloté par un analyseur de carte thermique basé sur l'IA qui surveille les journaux de requêtes, promouvant les données froides fréquemment accédées vers un stockage tiède et rétrogradant les données chaudes obsolètes, tout en maintenant des pointeurs de métadonnées dans Iceberg pour assurer la transparence des requêtes entre les niveaux.
Exemple détaillé :
NebulaObservability, un fournisseur SaaS servant 12 000 clients entreprises, a dû remplacer son ancien cluster Elasticsearch coûtant 2 millions de dollars par mois pour 8 To de stockage. Chaque client génère 2 à 10 To/jour de journaux et de métriques, nécessitant une analyse SQL ad hoc avec des temps de chargement de tableau de bord inférieurs à une seconde. Les exigences réglementaires imposent une isolation stricte, où le Client A ne peut pas déduire l'existence des données du Client B par le biais d'attaques par temporisation ou d'erreurs de requête. La rétention des données est imposée pour 13 mois, mais 95 % des requêtes touchent uniquement les dernières 72 heures. L’architecture précédente souffrait de problèmes de « voisin bruyant » où une grande requête d'agrégation d'un client dégradait la performance des autres.
Solution 1 : Clusters ClickHouse sharded
Le déploiement de vastes clusters ClickHouse avec sharding basé sur les locataires a été envisagé. Les avantages incluaient une performance exceptionnelle pour une requête unique et un support SQL mature avec exécution vectorisée. Cependant, les inconvénients étaient sévères : complexité opérationnelle de la gestion de clusters à l'échelle du pétaoctet, difficulté de mise en œuvre de la sécurité au niveau des lignes sans dégradations de performance, et incapacité à échelonner indépendamment le stockage par rapport au calcul. De plus, la reprise du sharding des clusters ClickHouse lors de l'intégration de nouveaux locataires nécessitait des heures d'arrêt et d'intervention manuelle.
Solution 2 : PostgreSQL par locataire avec TimescaleDB
La provision d'instances PostgreSQL isolées avec des extensions TimescaleDB pour chaque locataire offrait une isolation de sécurité parfaite et des stratégies de sauvegarde simples. Les avantages étaient évidents : sécurité au niveau des lignes native, suppression facile des locataires pour le GDPR, et aucune interférence inter-locataire. Cependant, les inconvénients rendaient cette approche impossible : le cauchemar opérationnel de la gestion de 12 000 instances de base de données, les cycles de correction, et l'épuisement des pools de connexions. Les coûts de stockage exploseraient en raison de l'absence de compression par rapport aux formats en colonnes, et les analyses inter-locataires pour les propres insights d'utilisation du fournisseur devenaient impossibles.
Solution 3 : Lakehouse fédéré avec stockage en plusieurs niveaux
La mise en œuvre du lakehouse basé sur Apache Iceberg avec Trino et un tiering automatisé a fourni l'équilibre optimal. Les avantages incluaient des économies d'échelle d'infrastructure partagée, le partitionnement caché de Iceberg prévenant les erreurs d'utilisateur, et la montée en charge infinie de S3. La sécurité au niveau des lignes via Apache Ranger permettait des politiques granulaires sans modifier les requêtes. Le tiering automatisé a réduit les coûts de stockage de 70 % en déplaçant les données froides vers S3 Glacier, tout en maintenant les métadonnées chaudes. Les inconvénients impliquaient une complexité de tuning significative : la planification des requêtes nécessitait un soin particulier sur la taille des partitions et l'algorithme de tiering avait besoin de données d'entraînement pour éviter le thrashing.
Solution choisie et pourquoi :
La solution 3 a été choisie car elle répondait de manière unique à la exigence d’échelle planétaire tout en maintenant une isolation stricte. La capacité du format Iceberg à mettre à jour atomiquement les métadonnées de la table permettait l'évolution du schéma sans verrouillage, ce qui est critique pour les déploiements sans temps d'arrêt. L'architecture des connecteurs de Trino a permis de pousser des prédicats vers S3, réduisant les données scannées. Le tiering automatisé, utilisant des fonctions AWS Lambda déclenchées par des journaux de requêtes Athena, a assuré l'optimisation des coûts sans intervention manuelle. Cette approche a découplé le stockage du calcul, permettant un échelonnement indépendant lors des pics de trafic.
Résultat :
Le système a atteint une latence de requête p99 de 650 ms sur 12 To de données actives, prenant en charge 50 000 requêtes concurrentes lors des heures de pointe. Les coûts de stockage ont diminué de 68 % par rapport à l'architecture Elasticsearch précédente, économisant 1,36 million de dollars par mois. Le tiering automatisé a correctement prédit 94 % des modèles d'accès aux données, avec des « erreurs de cache » vers le stockage froid ne se produisant que 0,3 % du temps. Aucun incident de sécurité lié à des fuites de données inter-locataires n’a été enregistré au cours des 18 premiers mois de fonctionnement, validé par des tests de pénétration trimestriels. L'intégration d'un nouveau locataire est devenue une opération purement liée à la métadonnée prenant moins de 30 secondes.
Comment empêchez-vous les explosions de latence des requêtes lorsque l'algorithme de tiering automatisé rétrograde incorrectement les données « tièdes » qui sont soudainement accédées par un rapport de lot programmé ?
Les candidats suggèrent souvent un caching réactif sans considérer le mécanisme de prédiction. La réponse détaillée nécessite de mettre en œuvre un système de tiering prédictif utilisant un lissage exponentiel sur les journaux d'accès aux requêtes, maintenant un niveau « tiède » intermédiaire sur S3 Standard-IA avec une latence au premier octet de milliseconde avant la rétrogradation vers Glacier. De plus, déployer Alluxio comme une couche de cache distribuée entre Trino et S3 absorbe les pics d'accès inattendus. Le détail critique est de mettre en œuvre « la promotion à la lecture » : lorsque des données froides sont accédées, le système les copie asynchrone vers le niveau tiède tout en servant la requête actuelle à partir de S3 Glacier Instant Retrieval, garantissant que les requêtes suivantes atteignent un stockage plus rapide.
Comment maintenez-vous la cohérence ACID pour l'évolution du schéma (ajout de colonnes) à travers des milliers de tables de locataires sans qu’un coordinateur de transactions global ne devienne un goulet d'étranglement ?
La plupart des candidats proposent un verrouillage distribué, ce qui viole l'exigence de « goulets d'étranglement centralisés ». L'approche correcte exploite le contrôle d'optimisme de la concurrence et le superposition de métadonnées d'Apache Iceberg. Chaque table de locataire a un fichier metadata.json indépendant. Les changements de schéma ajoutent un nouveau fichier de métadonnées avec un numéro de séquence incrémenté ; le catalogue (par exemple, AWS Glue) ne stocke que le pointeur vers le fichier de métadonnées actuel. Pendant le commit, l’écrivain vérifie si le pointeur a changé (conflit) et réessaie si nécessaire. Cela élimine le besoin de verrous globaux car les tables de locataires sont des espaces de noms indépendants. Pour les rares mises à jour de schéma inter-locataires (par exemple, ajout d'une colonne universelle), utilisez un patron de saga avec des opérations DDL idempotentes plutôt que des transactions atomiques.
Comment architectez-vous la couche de sécurité au niveau des lignes pour empêcher un « super-locataire » d’effectuer un scan complet de la table qui affame les ressources CPU pour d'autres locataires, violant ainsi le SLA inférieur à une seconde ?
Les candidats manquent souvent des mécanismes de gouvernance des ressources. La solution implique une isolation hiérarchique des ressources utilisant les groupes de ressources de Trino avec des limites de CPU et de mémoire fixes par classe de locataire (premium vs standard). Mettez en œuvre un contrôle d'admission qui estime le coût de la requête en utilisant l'optimiseur basé sur les coûts de Trino ; les requêtes dépassant les seuils spécifiques au locataire sont mises en file d'attente ou rejetées plutôt que exécutées. Utilisez des quotas de ressources Kubernetes pour isoler les pods du moteur de requêtes dans des pools de nœuds spécifiques aux locataires, empêchant ainsi la famine de CPU. Enfin, mettez en œuvre des politiques de suppression de requêtes pour les scans de longue durée qui dépassent les coûts prédits, couplées avec des vues matérialisées pour des agrégations coûteuses courantes, garantissant que même des scans complets malveillants ou accidentels ne peuvent pas affecter la latence des autres locataires.