
Dans un environnement de production, Solr peut être soumis à des charges de requêtes concurrentes intenses, d’autant plus lorsque des opérations d’indexation et de recherche sont réalisées simultanément. Sans mécanisme de contrôle, ces situations peuvent entraîner une saturation critique des ressources (CPU, mémoire, threads) et conduire à une dégradation sévère des performances, voire à des interruptions de service.
Pour répondre à ces enjeux, Solr intègre deux mécanismes complémentaires permettant de réguler l’utilisation des ressources système et de préserver la stabilité de l’infrastructure:
- Les « Request Rate Limiters » (disponibles depuis la version 8.7), pour limiter le nombre de requêtes concurrentes autorisées.
- Les « Circuit Breakers » (disponibles depuis la version 9.0 et améliorés en version 9.4), pour empêcher l’exécution de requêtes lorsque certains seuils critiques (mémoire, CPU, charge) sont dépassés.
Cet article présente ces deux mécanismes, ainsi que leurs principales configurations et cas d’usage.
Request Rate Limiters
La documentation commence par indiquer que l’objectif est de pouvoir limiter le nombre de requêtes concurrentes selon qu’il s’agisse de recherches ou de mises à jour. Elle précise cependant que l’implémentation actuelle permet de limiter uniquement les requêtes de type recherche et donc pour libérer des ressources pour les opérations d’indexation.
Les limites sont contrôlées au niveau de la JVM et du threadpool de requêtes et elles s’appliquent donc à l’ensemble des replicas des collections hébergées sur un nœud SolrCloud ou tous les core d’un serveur Solr.
La documentation indique également que les limites ne s’appliquent qu’aux requêtes qui incluent un header « Solr-Request-Type: QUERY ».
Lorqu’une requête est rejetée, une réponse 409 (Conflict) est retournée par Solr.
Pour le détails de la configuration, se référer à la documentation « Request Rate Limiters Solr ».
Circuit Breakers
L’objectif est ici de protéger un nœud Solr contre des surcharges critiques de consommation des ressources mémoire et CPU en rejetant des requêtes avec une réponse 429 (Too Many Requests) ou 503 (Service Unavailable) selon la version de Solr.
Les trois métriques système qui peuvent être utilisée afin de configurer des rejets de requêtes sont :
- L’utilisation de la mémoire heap de la JVM en positionnant un seuil en % de -Xmx
- L’utilisation de la CPU en positionnant un seuil en % du de CPU utilisée
- Le load Average (nombre de processus utilisant ou en attente d’un processeur) sur 1 minute : le seuil doit être positionné en fonction du nombre de processeur (par exemple 2 fois le nombre de cœurs CPU). Disponible à partir de la version 9.4.
Il est possible de configurer un ou plusieurs de ces seuils. Lorsqu’un seuil est atteint, les requêtes sont rejetées.
Les Circuits Breaker se configurent indépendamment pour les requêtes de types Query et Update.
Contrairement aux Request Rate Limiters qui se configurent au niveau de la JVM donc pour toutes les collections ou pour tous les cores, les Circuit Breakers se configure soit également globalement pour un noeud Solr dans le fichier solr.in.sh ou une propriété système, soit au niveau d’une collection dans le fichier solrconfig.xml. C’est la configuration sur une collection qui est appliquée prioritairement avant la configuration globale.
Les Circuit Breaker peuvent être configurés en mode « warn only » pour ne générer qu’une trace dans les logs. Cela peut être utile pour détecter les dépassements de seuil sans réellement bloquer les requêtes et donc déterminer les seuils à configurer avant d’activer réellement les blocages.
Pour le détails de la configuration, se référer à la documentation « Solr Circuit Breakers ».
Conclusions
Ces deux fonctionnalités peuvent permettre pour des environnements à haute disponibilité ou à fort trafic d’éviter des instabilités des nœuds Solr et donc du cluster. Cependant, elles présentent des limites et ne garantissent une stabilité à toutes épreuves du cluster Solr.
Afin de pallier à la limite de la fonctionnalité Request Rate Limiters qui ne peut contrôler que les requêtes de type recherche, il faut commencer par travailler sur l’optimisation des indexations en jouant sur les types de réplica et privilégier les types TLOG dès que cela est compatible avec les besoins fonctionnels. Il est possible également d’essayer de dédier des nœuds Solr au tâches d’indexations et d’autres aux tâches de recherches. Cette objectif n’est pas simple à atteindre, mais avec suffisamment de nœuds Solr et avec des replicas de type TLOG complétés éventuellement par des replicas PULL, cela est possible en utilisant le Replica Placement Plugins.
En ce qui concerne, les Circuit Breakers, le pourcentage de CPU utilisé ne semble pas être un critère pertinent de déclenchement. En effet, il est fort possible qu’une utilisation ponctuelle de 100% de CPU ne soit pas un réel problème si conjointement le load average reste limité. De même, l’utilisation CPU peut ne jamais dépasser 70% en cas de forts d’I/O disques (manque de mémoire hors heap) et qui va s’accompagner un load average elevé. C’est donc plus sur le critère Load average sur lequel il convient de positionner un Circuit Breaker. De même, positionner un circuit breaker sur l’utilisation de la mémoire heap ne garantit pas qu’il ne peut pas y avoir des erreurs out of memory surtout si le schéma de la collection n’est pas optimisé ou si les requêtes ne sont pas correctement construites.
Nos recommandations pour optimiser et maîtriser l’usage des ressources :
- Privilégier le déclenchement des Circuit Breakers par load average, plus représentatif de la saturation CPU que le seul usage de la CPU.
- Configurer les Circuit Breakers d’abord en mode « warnOnly », pour observer sans bloquer, puis affiner les seuils.
- Spécialiser si cela est possible et pertinent les rôles des nœuds Solr (indexation versus recherche) en jouant sur le type des replicas et en utilisant le Replica Placement Plugins pour une distribution maîtrisée des charges.
- Mais surtout, anticiper les problèmes en adoptant des bonnes pratiques :
- Optimisez vos schémas (docValues, indexed, stored, champs inutiles…)
- Optimiser vos configurations (cache, listener, …)
- Optimiser vos requêtes (filter query, champs retournés, highlight, facettes, …)
- Disposer de suffisamment de mémoire hors-heap pour une bonne mise en cache des index
Dans un contexte où les systèmes doivent rester disponibles et performants sous des charges variables, Solr offre avec les Request Rate Limiters et les Circuit Breakers deux leviers efficaces pour maîtriser la consommation des ressources et anticiper les défaillances. Bien que perfectibles, ces mécanismes permettent de renforcer la résilience des clusters Solr les plus sollicités.
Cependant, ces fonctionnalités ne remplacent pas une architecture bien pensée, une surveillance continue et une optimisation proactive des index et des requêtes. Couplés à une stratégie de déploiement adaptée (spécialisation des rôles des nœuds, placement des réplicas), ces outils constituent une première ligne de défense contre les effets indésirables des pics de charge et des dérives de consommation de ressources.