Vue normale

Reçu avant avant-hier

How Perplexity.ai Is Pioneering The Future Of Search

7 mai 2025 à 14:40

Comment Perplexity.ai ouvre la voie à l'avenir de la recherche

Joanne Chen est General Partner chez Foundation Capital.
Sep 06, 2023, 06:02pm

Au cours des deux dernières décennies, les moteurs de recherche tels que Google et Bing ont été nos principales portes d'entrée sur Internet. Pourtant, au fil du temps, les "10 liens bleus" qui les caractérisent ont été de plus en plus noyés sous les publicités et les contenus optimisés par les algorithmes. Ces sites, qui reposent sur des modèles de revenus basés sur la publicité, ressemblent davantage à des commissaires priseurs de l'attention des utilisateurs qu'à des guides dignes de confiance sur le Web.

Aravind Srinivas et ses cofondateurs de Perplexity.ai construisent une alternative. Au lieu de saisir des mots clés et de trier un enchevêtrement de liens, les utilisateurs posent leurs questions directement à Perplexity.ai et reçoivent des réponses concises et précises, étayées par un ensemble de sources sélectionnées. Alimenté par de grands modèles de langage (LLM), ce "moteur de réponses" place les utilisateurs, et non les annonceurs, au centre de ses préoccupations. Cette évolution promet de transformer la manière dont nous découvrons, accédons et consommons les connaissances en ligne et, partant, la structure de l'internet telle que nous la connaissons aujourd'hui.

Arracher la loyauté des utilisateurs aux géants de la recherche n'est pas une mince affaire. Pourtant, Aravind, armé d'un doctorat de Berkeley et d'une expérience professionnelle chez OpenAI et DeepMind, m'a longtemps semblé être l'entrepreneur idéal pour relever ce défi. Dans cette conversation, éditée pour plus de clarté et de longueur, Aravind et moi discutons des origines de Perplexity, de son approche des opérateurs historiques et de la conception de l'interface, et de ses conseils aux autres fondateurs d'IA.

Commençons par votre parcours. Qu'est-ce qui vous a amené à fonder Perplexity ?

Je suis né à Chennai, en Inde. Notre culture valorise l'érudition, plus encore que la réussite financière. Prenons l'exemple du cricket, qui est le sport le plus populaire en Inde et qui est particulièrement apprécié à Chennai. Pour ma famille et mes amis, regarder le cricket n'est pas seulement une question de divertissement. Nous nous passionnons pour les statistiques, nous connaissons par cœur les moyennes, les taux de réussite et les taux d'économie de chaque joueur.

Cette volonté d'apprendre et de comprendre a façonné mon éducation. J'ai travaillé dur pour être admis dans les IIT (Instituts indiens de technologie) et j'ai ensuite plongé dans la recherche sur l'apprentissage profond, ce qui m'a conduit à mon doctorat à l'Université de Californie à Berkeley. Des films comme Pirates de la Silicon Valley et The Social Network ont éveillé très tôt mon intérêt pour l'entrepreneuriat. Mais une fois arrivé à Berkeley, je me suis rendu compte que la plupart des créateurs d'entreprises étaient des étudiants de la CJ. Je ne pouvais plus suivre cette voie. J'ai donc cherché des exemples d'entrepreneurs issus du monde universitaire dont je pourrais m'inspirer.

Un tournant s'est produit en 2019 lors de mon stage chez DeepMind à Londres. Ils avaient une bibliothèque incroyable et, le soir, lorsque j'avais fini de me concentrer sur mon projet, je lisais des livres sur les débuts de Google et j'ai été très inspiré par Larry Page. J'ai été fasciné par l'évolution du PageRank et par la façon dont elle a conduit à une entreprise capable de créer des avancées incroyables comme les transformateurs, une nouvelle architecture pour les modèles d'apprentissage profond. J'ai contacté l'inventeur des transformateurs, Ashish Vaswani, pour lui proposer un stage. Ensemble, nous avons travaillé au développement de modèles d'apprentissage profond pour la vision et à l'universalisation des transformateurs en tant que blocs de calcul.

Bien que ce travail soit fascinant, je n'avais pas d'idée de démarrage claire. L'apprentissage profond me semblait encore très académique. Pourtant, à l'été 2022, des startups d'IA générative comme Jasper et GitHub Copilot commençaient à générer des revenus réels. L'engouement croissant des utilisateurs grand public m'a convaincu que mes intérêts n'étaient plus seulement académiques. C'était enfin le bon moment pour créer une entreprise. J'ai eu la chance de bénéficier du soutien d'investisseurs comme Elad Gil et Nat Friedman, ainsi que de trois excellents cofondateurs, Denis (Yarats), Johnny (Ho) et Andy (Konwinski). Ils y croyaient tous quand il n'y avait rien de concret. C'est ainsi qu'est née Perplexity.

Qu'est-ce qui vous a attiré dans le problème de la recherche ?

Comme je l'ai dit, je suis un grand fan de Larry Page et de Google. J'ai toujours eu envie de faire quelque chose de la même ampleur et de la même ambition que Google. Être érudit, précis et sincère, avoir la réponse à portée de main et pouvoir en rappeler les sources : ce sont des choses que j'apprécie et que je m'efforce d'incarner. Construire un produit qui m'aide, ainsi que les gens qui m'entourent, à devenir plus intelligents chaque jour et à accroître le capital de connaissances de la planète revêt pour moi une signification personnelle profonde. C'est bien plus qu'un simple moyen de gagner de l'argent.

Avant d'opter pour la recherche, vous avez exploré d'autres problèmes.

Oui, nous nous sommes d'abord concentrés sur la traduction du langage naturel en langage SQL. C'est une idée qui nous a été proposée par notre premier investisseur, Elad Gil. Notre objectif était de construire un copilote pour les analystes de données. Étant moi-même un "data nerd", l'idée de permettre à un plus grand nombre de personnes d'être des "data nerds" a vraiment résonné en moi.

Pourquoi n'avez-vous pas poursuivi cette idée ?

À l'époque, la technologie n'était pas suffisamment avancée. Codex était impressionnant, mais il n'était pas à la hauteur des capacités de GPT-3.5 Turbo ou de GPT-4. En outre, le marché SQL est très fragmenté, ce qui rend difficile l'entrée et l'établissement d'un point d'ancrage sur ce marché. Les grandes entreprises d'entreposage qui pouvaient s'offrir nos services étaient souvent enfermées dans Snowflake ou Databricks, tandis que les petites entreprises ne disposaient pas de suffisamment de données pour s'éloigner des feuilles de calcul de base. Chaque entreprise avait également ses propres méthodes de stockage de données, ce qui compliquait nos efforts pour créer une solution unique.

Bien que cette idée n'ait pas abouti, l'expérience nous a permis de grandir. Nous avons partagé notre prototype, BirdSQL, sur Twitter, et les réactions ont été extrêmement positives. Il a si bien fonctionné que Jack Dorsey, bien qu'inactif sur la plateforme depuis longtemps, est soudain sorti de son hibernation et a tweeté à son sujet. Son soutien a attiré l'attention et le trafic sur notre produit et nous a aidés à surmonter le problème du démarrage à froid, personne ne sachant qui nous étions. Cette croissance virale précoce a été la clé de notre succès final.

Vous avez décrit Perplexity comme un "moteur de réponses". Pouvez-vous expliquer ce que vous entendez par ce terme et en quoi il diffère d'un moteur de recherche traditionnel ?

Bien sûr. L'approche traditionnelle de la recherche consistait à renvoyer dix liens bleus, que les utilisateurs devaient ensuite parcourir pour trouver l'information qu'ils recherchaient. Au cours des dernières années, ce modèle a évolué pour fournir des réponses directes aux questions des utilisateurs. C'est ce que j'entends par "moteur de réponse" : les utilisateurs peuvent poser n'importe quelle question directement et recevoir une réponse réelle, et pas seulement une liste de pages web qui peuvent ou non contenir la réponse. Google a commencé à s'engager dans cette voie vers 2020 en utilisant une simple extraction de texte. L'objectif de Perplexity est de répondre à des questions plus complexes qui nécessitent de synthétiser le contenu de plusieurs pages et de fournir des réponses rapides et précises à l'aide de LLM.

Pendant deux décennies, nous avons tous été conditionnés à utiliser des mots-clés pour effectuer des recherches sur le web, car c'est ainsi que les principaux moteurs de recherche ont été conçus. Aujourd'hui, les LLM changent la façon dont nous interagissons avec les ordinateurs pour trouver et consommer l'information. En plus de fournir des réponses directes et concises, les LLM peuvent poser des questions de clarification et jouer le rôle de copilote pendant que vous naviguez sur le web. Au fil du temps, ils pourront également vous aider à faire avancer les choses en exécutant des tâches. Telle est la vision de Perplexity : permettre à chacun d'accéder à une connaissance et à une productivité infinies, et améliorer leur vie en leur permettant d'interagir avec Internet de manière plus intuitive et plus efficace.

Les moteurs de recherche ont fortement influencé l'économie actuelle de l'internet, en l'optimisant essentiellement pour la publicité. Comment les moteurs de réponse pourraient-ils nous permettre de créer un modèle alternatif ?

Les LLM modifieront certainement la dynamique publicitaire actuelle du web - espérons-le pour le mieux ! En effet, ces modèles offrent un gain de pertinence plus important que toute autre technologie de ciblage antérieure. Il sera encore plus facile d'atteindre les gens, car les requêtes auront une plus grande intention. Si j'étais un annonceur, je m'efforcerais de décrire mon produit aussi précisément que possible sur mon site web, de manière à ce qu'un gestionnaire de droits d'auteur le considère comme digne d'être cité. Au lieu d'optimiser pour les clics, j'optimiserais pour un contenu de haute qualité.

J'essaie encore de comprendre ce que signifie une citation sponsorisée. En tant qu'ancien doctorant, j'aborde le problème d'un point de vue académique. Certaines revues publieront votre article si vous payez, mais leur réputation est bien moindre que celle des revues à comité de lecture. Dans la prochaine itération de l'internet, les sources d'information claires et fiables ne citeront idéalement que le contenu fourni par d'autres sources vérifiées. Dans ce scénario, le LLM sera le juge. Il existe également d'autres moyens par lesquels les gens voudront interagir avec les requêtes et les vérifier, au-delà des citations. J'y ai réfléchi, mais je n'ai pas encore tout à fait trouvé la solution.

Construire un moteur de réponses n'est pas une mince affaire. Comment avez-vous commencé ?

Nous avons commencé par créer une base de données en récupérant les données de Twitter et en alimentant la recherche à partir de ces données. C'est devenu BirdSQL. Nous nous appuyons également sur un index de recherche existant qui extrait le contenu du web et l'organise. Perplexity exploite une couche d'abstraction supplémentaire au-dessus de ce contenu, que nous synthétisons et organisons encore davantage. Au fur et à mesure de notre croissance, nous avons commencé à construire notre propre index.

Que pensez-vous des autres acteurs de l'écosystème de la recherche ?

C'est une excellente question. Permettez-moi de l'illustrer par une anecdote. Un vendredi après-midi, nous avons conclu un tour de table de démarrage avec notre société de capital-risque, NEA. Ensuite, je suis allé de Sand Hill Road à Blue Bottle à Palo Alto avec mon cofondateur, Denis, juste pour me détendre. Puis j'ai vu que quelqu'un m'avait envoyé un article de Verge contenant des fuites de captures d'écran de la nouvelle interface de chat de Bing. Denis et moi nous sommes immédiatement inquiétés. Nous nous sommes dit : "Oh, notre contrat contient une clause de diligence raisonnable de 30 jours ! La NEA va se retirer de l'affaire". Heureusement, notre associé, Pete Sonsini, nous a appelés le lendemain pour nous rassurer. Il nous a dit : "Nous vous faisons confiance, vous allez vous en sortir." Cela nous a donné la confiance nécessaire pour continuer.

En fin de compte, il ne s'est rien passé de grave. Notre croissance est restée exponentielle, tandis que celle de Bing a stagné. Nous avons eu l'impression qu'ils avaient raté une occasion, plutôt que d'être confrontés à des problèmes à cause de leur lancement.

Pourquoi pensez-vous que ce soit le cas ?

À mon avis, le produit Bing était confus. Il était également limité aux comptes Microsoft et au navigateur Edge, et n'était donc pas largement accessible. Il tentait d'intégrer plusieurs fonctionnalités dans un seul produit, comme la recherche, le chat et les conversations multi-tours utilisant le GPT-4, ce qui alourdissait l'expérience de l'utilisateur. En revanche, nous nous sommes concentrés sur la création d'un moteur de réponses avec des citations et avons évité les conversations libres. Cette orientation claire nous a permis de créer un produit utile, alors que le produit de Bing, malgré le battage médiatique, était moins clair quant à ses cas d'utilisation exacts.

À l'instar de Bing, Google est également confronté à un dilemme, car l'amélioration de l'expérience de recherche générative pourrait nuire à ses recettes publicitaires. Par exemple, une requête telle que "planifier un voyage à Tokyo" sur Google, même si la recherche générative est activée, affichera toujours des publicités parce que l'industrie du voyage paie beaucoup d'argent à Google pour distribuer ses liens. Nous avons réalisé qu'il serait possible de rivaliser avec Google parce qu'il a tout intérêt à protéger ses revenus publicitaires, ce qui limite sa capacité à fournir des réponses directes. Notre principal concurrent était Microsoft, mais cela semble désormais gérable.

Une plainte typique concernant ChatGPT est que ses réponses ne sont pas dignes de confiance. Comment Perplexity garantit-il l'exactitude des réponses ?

Nous disposons d'une incroyable équipe de recherche et d'IA, dirigée par Denis. L'exactitude des réponses est étroitement liée au classement des recherches, qui est un problème notoirement difficile. Chez Perplexity, nous utilisons une version plus moderne du PageRank pour construire une carte de confiance du web. Par exemple, des sites comme le New York Times sont généralement plus fiables que les articles de Substack, qui peuvent être plus orientés vers l'opinion. Nous utilisons l'heuristique et l'apprentissage basé sur les données des requêtes passées pour améliorer nos résultats. Si Google se concentrait uniquement sur la fourniture de réponses correctes, il pourrait améliorer considérablement son produit de recherche avec un minimum d'efforts. Ce sont les intérêts commerciaux qui l'en empêchent.

Avec chaque nouveau produit technologique grand public, il y a un point de basculement où il devient la norme pour un sous-ensemble de comportements. Combien de temps faudra-t-il, selon vous, pour que les alternatives à la recherche des grandes entreprises technologiques soient connues du grand public ?

J'espère que ce sera bientôt ! Pour l'instant, il semble que le monde soit toujours satisfait de Google, car son trafic n'a pas changé de manière significative. Tout comme Google et Facebook ont transformé la manière dont les gens consomment l'information, l'abandon des moteurs de recherche traditionnels finira par se produire. Cependant, jusqu'à ce que notre produit atteigne la parité totale avec la recherche Google, puis devienne 10 fois meilleur, les gens s'en tiendront au statu quo. Il faudra peut-être quelques mois ou un an pour y parvenir. Même dans ce cas, de nombreuses personnes continueront à utiliser Google par habitude, de la même manière qu'elles utilisent encore Yahoo et MSN. Des progrès constants et réfléchis nous aideront à nous intégrer dans les flux de travail quotidiens des utilisateurs.

Parlons de l'interface. ChatGPT était, à la base, une innovation en matière d'interface qui a stimulé l'adoption massive par les consommateurs. Que pensez-vous de l'interface utilisateur de Perplexity ?

Nous avons la chance d'avoir d'excellentes équipes de conception et de produits dirigées par des personnes très talentueuses, Johnny et Henry (Modisett). Notre approche générale consiste à minimiser le nombre de boutons et de choix que les utilisateurs doivent faire au cours d'une interaction donnée avec le produit. Google et Apple sont de grandes sources d'inspiration à cet égard. La recherche de base de Google est si simple, n'est-ce pas ? Les gens se plaignent parfois que Google n'ajoute pas assez de nouvelles fonctionnalités, mais ils ne se rendent pas toujours compte que cela crée plus de responsabilités et de confusion pour les utilisateurs.

Chez Perplexity, notre philosophie est de faire nous-mêmes le travail difficile pour rendre les choses aussi simples que possible pour nos utilisateurs. Nous préférons supprimer des éléments plutôt que d'en ajouter. Nous poussons les mises à jour vers la production et observons les modèles d'interaction. Si une fonctionnalité n'est pas utilisée, nous la supprimons, même si certaines personnes s'en plaignent. En tant que fondateur, il est essentiel d'avoir une boussole solide, qui vous donne le courage de dire "non" à certaines choses.

Un autre aspect essentiel de la conception d'une interface est son intuitivité. Les utilisateurs ne doivent pas avoir besoin d'un manuel pour utiliser votre produit. Il doit être explicite. C'est pourquoi, lorsque les gens trouvent Perplexity sur Google, ils sont directement dirigés vers notre produit, sans longues explications ni nécessité de se connecter. Une autre philosophie de l'entreprise consiste à éliminer le plus de frictions possible.

Pour l'instant, l'expérience de Perplexity se déroule principalement sur le web. Nous nous concentrons davantage sur le mobile et sur la création d'une expérience de recherche véritablement native pour le mobile. Des fonctionnalités telles que le glissement vers la gauche ou la droite pour supprimer des fils de discussion et l'interaction vocale ne peuvent être utilisées que sur mobile. La barre est très haute, car tout doit fonctionner de manière transparente.

Quel est le ou les éléments du produit Perplexity qui vous empêchent de dormir ?

J'utilise beaucoup notre produit, donc s'il ne fonctionne pas comme prévu, je le sais tout de suite. Au départ, j'avais la mentalité d'un hacker qui suggérait une solution pour chaque problème. Au fil du temps, après avoir été repoussé par l'un de nos cofondateurs, j'ai commencé à réfléchir à la situation dans son ensemble : comment pouvons-nous résoudre un plus grand nombre de problèmes à l'aide d'une solution plus générale ? C'est la meilleure façon d'apporter des améliorations évolutives et durables.

J'essaie toujours de voir les choses du point de vue de nos utilisateurs et de discuter avec le plus grand nombre d'entre eux possible. Lorsqu'il a créé Google, Larry Page avait pour philosophie que "l'utilisateur n'a jamais tort". C'est simple mais profond. Lorsque des personnes se plaignent que quelque chose ne fonctionne pas pour elles, je réponds au plus grand nombre possible de leurs messages DM. Et je fais de mon mieux pour insuffler cette mentalité à tous les employés de notre entreprise. Ne reprochez pas aux utilisateurs de ne pas formuler correctement leurs questions ou de ne pas savoir qu'il existe un bouton pour partager quelque chose. C'est à nous d'y remédier et de rendre le produit plus intuitif.

Une autre de mes grandes préoccupations est de faire connaître notre existence et d'élargir notre base d'utilisateurs. Nous voulons y parvenir en proposant un produit vraiment excellent sur lequel les utilisateurs peuvent compter. Certains disent qu'ils trouvent Perplexity génial, mais qu'ils hésitent à passer à autre chose parce que nous n'avons que quelques mois d'existence. Gagner la confiance des utilisateurs pour qu'ils se sentent à l'aise pour passer à autre chose est un défi important.

Si vous deviez repartir de zéro et fonder une entreprise qui exploite les LLM aujourd'hui, que construiriez-vous ?

Je referais la même chose. Il n'y a rien de plus ambitieux que de changer la façon dont les gens recherchent des informations et deviennent plus intelligents. Les manuscrits, la presse à imprimer, les bibliothèques, les moteurs de recherche, et maintenant les moteurs de réponse et les chatbots. C'est un moment qui n'arrive qu'une fois par génération.

Avez-vous un dernier conseil à donner à vos collègues fondateurs ?

Cela peut paraître cliché, mais commencez par ce que vous aimez. Il faut du temps pour trouver le juste milieu entre ce que vous aimez et ce que le marché demande. Vous finirez par converger vers ce point. Le marché vous y poussera. Mais il est préférable de partir d'un lieu de passion plutôt que de poursuivre ce qu'un investisseur en capital-risque ou le marché vous dit de faire. Par conséquent, donnez la priorité à ce qui vous passionne le plus au début. Si c'est déjà le cas, restez patient. La concurrence est féroce, et tout ce que vous construisez est probablement tenté par beaucoup d'autres. Restez concentré, poussez-vous et ayez un fort penchant pour l'action. Ne vous contentez pas d'élaborer une stratégie sur un tableau blanc. Mettez votre produit sur le marché, recueillez les réactions des utilisateurs et faites évoluer votre idée en public.


Permalien

Les bains publics, un luxe partagé | LOW←TECH MAGAZINE

10 avril 2025 à 19:20

Pas d’eau courante à domicile

Dans les sociétés industrielles, peu d’activités exigent autant d’intimité que le lavage et les soins corporels. Nous le faisons généralement seuls, dans nos salles de bains privatives, portes fermées à clé. Dans le passé, ce n’était pas la norme. Se baigner en présence d’autres personnes était la règle plutôt que l’exception. Jusqu’à la première moitié du XXe siècle, de nombreux foyers, même dans les sociétés les plus modernes, ne disposaient pas d’eau courante… Et encore moins d’une salle de bains privative. 1

Une salle de bains nécessite une alimentation en eau domestique, mais aussi une évacuation des eaux usées et une source d’énergie pour chauffer l’eau. Bien sûr, il est possible de prendre un bain chaud chez soi sans ces infrastructures. Depuis l’Antiquité, les plus riches ont construit des bains privatifs dans leurs maisons. Le plus souvent, ils pouvaient le faire parce que des personnes moins aisées – serviteurs ou esclaves – remplissaient et vidaient leurs baignoires avec des seaux d’eau et ramassaient du bois pour les chauffer.

Cependant, il était généralement plus pratique d’aller à l’eau au lieu de la faire venir. Certains se baignaient dans une rivière, un lac ou une source. D’autres, surtout en milieu urbain, se rendaient aux bains publics.


Permalien

Déployer un service hautement disponible grâce à Redis Replication (Publié dans Linux Pratique n°140)

31 décembre 2024 à 13:37

Redis est un système de stockage de données en mémoire de type NoSQL orienté hautes performances. Il est souvent utilisée comme base de données, système de cache ou de messages. Nous verrons dans cet article comment déployer un service hautement disponible grâce à Redis Replication.

1 Notre premier serveur Redis

Pour démarrer, commençons avec un mon serveur Redis. L’installation sera présentée pour Ubuntu 22.04 et devrait fonctionner sans trop d’adaptations pour Debian ou RHEL-like.

1.1 Installation

Redis est disponible dans les dépôts classiques de la distribution. Une configuration minimale peut être faite en installant simplement les paquets et en activant le service systemd.

sudo apt -y install redis-server
sudo systemctl enable --now redis-server

Vérifions maintenant que nous parvenons à nous connecter :

redis-cli
127.0.0.1:6379> ping
PONG

La CLI permet également de récupérer avec la commande INFO un certain nombre d’éléments sur le fonctionnement du serveur. Celle-ci s’appelle seule ou avec un argument pour obtenir les informations relatives à une catégorie particulière.

127.0.0.1:6379> INFO Server
# Server
redis_version:6.0.16
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:a3fdef44459b3ad6
redis_mode:standalone
os:Linux 5.15.0-73-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:11.2.0
process_id:596
run_id:7ea0cf9f46b211a64874d7a1c0a115be78c42e98
tcp_port:6379
uptime_in_seconds:61483
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:8771018
executable:/usr/bin/redis-server
config_file:/etc/redis/redis.conf
io_threads_active:0

Redis gère plusieurs types de données. Il est possible d’utiliser des chaînes de caractères, des ensembles, des hashs, des listes ainsi que d’autres types de données. Pour procéder à une première vérification de bon fonctionnement, nous allons ainsi écrire une donnée de type string, récupérer la valeur en indiquant la clé puis effacer cette donnée.

127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> get foo
"bar"
127.0.0.1:6379> del foo
(integer) 1
127.0.0.1:6379> get foo
(nil)

A ce stade, notre serveur est fonctionnel, toutefois sa configuration est très basique. Redis n’écoute que sur l’interface localhost ce qui est incompatible avec la notion de réplication que nous mettrons en place et il est préférable que systemd prenne en charge le service de manière explicite. Nous allons entreprendre donc nos premières modifications du fichier de configuration, /etc/redis/redis.conf et remplacer les paramètres bind et supervised par les valeurs suivantes :

bind 0.0.0.0
supervised systemd
protected-mode

Redémarrons le service redis et vérifions :

sudo systemctl restart redis-server
sudo netstat -lataupen |grep ":6379"
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      115        39165      3267/redis-server 0

En pratique, la plupart des options de Redis peuvent être définies avec la commande CONFIG SET. C’est peut-être moins classique ou confortable qu’un fichier de configuration mais c’est ce qui permet à Redis d’être entièrement reparamétré sans qu’il ne soit nécessaire de relancer le service et donc sans aucune interruption de service.

1.2 Gérer la persistance

Redis est une base de données en mémoire. Par conséquent si le service est arrêté, quelle qu’en soit la raison, les données sont perdues. Pour assurer la persistance des données, Redis permet d’utiliser deux mécanismes. Dans le premier, appelé RDB, Redis va générer des snapshots à intervalles réguliers de la base de données. Cela se configure avec save suivi de deux indicateurs, le premier consiste en une sauvegarde après n secondes si au moins un certain nombre d’écritures ont eu lieu. Ce paramètre est en outre multivalué .La politique par défaut est celle-ci :

save 900 1
save 300 10
save 60 10000

Généralement, on souhaite avoir au moins un snapshot récent même s’il y a peu d’écritures, d’où celui réalisé après 15 minutes à partir du moment où il y a eu une écriture. A l’inverse, en cas de forte charge, on souhaite également avoir des snapshots fréquents pour minimiser la perte de données, d’où le snapshot toutes les minutes dès 10000 clés modifiées. Ces seuils sont naturellement à adapter en fonction de l’activité de la base et afin de minimiser la perte de données admissible.

Dans le second mécanisme, AOF pour Append Only File, la persistance est gérée via l’utilisation d’un fichier de logs qui va historiser chaque écriture. Pour un maximum de fiabilité, les deux modes peuvent être utilisés conjointement. Naturellement, cela a un impact sur la consommation mémoire et les I/O disques car pour chaque écriture en base, une seconde est faite pour le journal AOB.

Pour utiliser l’AOF, ajoutons ces deux lignes dans le fichier redis.conf :

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

1.3 Un minimum de sécurité

Par défaut, Redis n’est pas joignable via le réseau. Pour que la mise en œuvre de la réplication à suivre soit possible, le service écoute désormais sur l’ensemble des interfaces réseau. Bien qu’il soit possible de restreindre à une ou plusieurs interfaces, l’accès au service à des fins de test s’est réalisé sans authentification. En définissant un mot de passe sur le paramètre requirepass, toute opération sur Redis nécessitera au préalable de s’authentifier avec la commande AUTH suivie du mot de passe. Dans la configuration redis.conf nous ajoutons donc :

requirepass SECRET

Et nous pouvons vérifier :

# redis-cli
127.0.0.1:6379> AUTH SECRET
OK

Pour assurer une meilleur sécurité, du TLS devrait être mis en œuvre et les ACL Redis 6 devraient être utilisées.

2 Assurer la haute disponibilité

2.1 Les mécanismes

Redis Replication est un système maître/esclave permettant de répliquer de manière asynchrone les données du master sur les slaves. En cas de perte de connectivité avec le master, les slaves vont tenter de resynchroniser l’écart de données dès que la connexion redevient disponible. Si cela n’est pas possible une resynchronisation complète est réalisée. Un slave peut servir de source de réplication à un autre slave et les répliquas peuvent servir de serveur en lecture pour répartir la charge et donc augmenter la performance.

En cas de perte du master, une procédure de failover doit être mise en œuvre pour promouvoir un slave comme master. Tant que cela n’est pas fait, le fonctionnement est en mode dégradé si ce n’est totalement interrompu. Redis Sentinel utilisé en complément permet de superviser le fonctionnement de Redis et en cas de panne du master, de promouvoir un nouveau master et de reconfigurer les repliquas pour qu’ils se répliquent depuis ce nouveau master. Dans ce type d’architecture, il est recommandé de disposer d’au moins 3 serveurs pour gérer le quorum.

Avec Redis Replication il est fortement recommandé d’activer la persistance. En effet, sans persistance et en cas de redémarrage du master, il se retrouvera vide de toute donnée. Dans un second temps, les slaves vont s’empresser de répliquer cela les vidant de leurs données.

Pour assurer la montée en charge horizontale, Redis Cluster offre des possibilités complémentaires. Dans ce mode, il s’agit toujours d’avoir une architecture master/slave mais avec gestion et failover automatique. L’espace de clés est divisé de sorte que chaque groupe de serveur ne gère qu’une partition de la base de données, cela s’appelle du sharding. La taille de la base de données peut ainsi être plus importante et la charge peut être répartie sur plus de nœuds. Un minimum de 6 nœuds est toutefois requis pour Redis Cluster ce qui prédispose ce mode à des infrastructures relativement conséquentes.
De fait dans cet article j’aborderai uniquement Redis Replication.

2.2 Configuration

La configuration mise en œuvre sur le premier serveur que nous appellerons db01 devra être reprise à l’identique sur nos deux slaves. Le serveur DB01 sera le master par défaut. Pour que la suite soit aisément compréhensible, voici les serveurs et adresses IP que je vais utiliser :

  • db01 : 192.168.69.81
  • db02 : 192.168.69.82
  • db03 : 192.168.69.83

Sur chacun de nos serveurs, nous allons définir la valeur de masterauth. En effet, nous avons exigé précédemment un mot de passe via requirepass, il faut donc s’authentifier pour avoir les droits pour répliquer :

masterauth SECRET

Et enfin, sur chaque slave, on indique depuis quel serveur notre slave doit se répliquer :

replicaof db01.morot.local 6379

Il suffit de redémarrer nos serveurs, il n’y a rien de plus à faire.

2.3 Vérification de la réplication

Dans un premier temps, envoyons la commande INFO Replication sur notre master. Si la configuration est correcte, alors on doit pouvoir avoir un rôle master, visualiser les deux slaves comme connectés ainsi que leurs adresses IP et enfin en fonctionnement nominal un statut online :

127.0.0.1:6379> AUTH SECRET
OK
127.0.0.1:6379> INFO Replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.69.83,port=6379,state=online,offset=1106,lag=0
slave1:ip=192.168.69.82,port=6379,state=online,offset=1106,lag=0
master_replid:75b55df27cafe6bfd7aec3114bfd63e77d45a8cb
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1106
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1106

A l’inverse, sur un slave, le rôle doit correspondre et le serveur doit être connecté au slave (master_link_status). Si master_sync_in_progress est à 0 alors la réplication est terminée. La section master_replid indiqué le dataset de ReplicationID qui doit être identique avec le master lorsque les masters et slaves sont synchronisés. Si une synchronisation était en cours, nous aurions des champs master_sync supplémentaires pour suivre la volumétrie à répliquer et les performances de réplication.

127.0.0.1:6379> INFO Replication
# Replication
role:slave
master_host:db01.morot.local
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:1288
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:75b55df27cafe6bfd7aec3114bfd63e77d45a8cb
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1288
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1288

2.4 Failover

Voyons désormais ce qu’il se passe lors d’une panne du master. J’ai simulé un crash du master en coupant violemment la VM qui porte le service. Sur chacun de mes slaves, la réplication indique que le lien avec le master est « down » avec le délai depuis lequel le lien est rompu.

127.0.0.1:6379> INFO Replication
# Replication
role:slave
master_host:db01.morot.local
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:3472
master_link_down_since_seconds:42

S’il s’agit d’un simple redémarrage du serveur master, la réplication devrait remonter dès que le serveur sera up. En cas de panne majeure, le service rendu est interrompu. Il faut manuellement reconfigurer les slaves pour rétablir le service.

Sur db03, nous allons donc indiquer que sa source de réplication est db02 :

127.0.0.1:6379> replicaof db02.morot.local 6379
OK

Pour autant, cela ne fait pas de db02 un master par magie. D’autant que Redis supporte la réplication d’un slave depuis un autre slave. Il faut donc indiquer que db02 est un master ce qui se configure en indiquant qu’il est le répliqua d’aucun serveur :

127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.69.83,port=6379,state=online,offset=3472,lag=0

2.5 Le retour du master

Se pose ensuite la question de la remise en service du serveur db01 lorsqu’il sera réparé. Avec le failover précédent il va se retrouver master sans slave et il sera aussi désynchronisé des autres serveurs Redis. Il est donc indispensable de le remettre en synchronisation avec le master qui a été promu. Cela se fait de la même façon que lors du failover précédent :

127.0.0.1:6379> replicaof db02.morot.local 6379
OK

Et c’est tout. Si toutefois vous tenez à remettre le serveur redis master « nominal » en tant que master, il faut alors :

  • Le resynchroniser sur le master et s’assurer que la réplication est terminée
  • Définir les slaves en état nominal (db02 et db03) comme replicaof db01
  • Indiquer que db01 n’est plus le répliqua d’aucun serveur.

Cela reste toutefois une opération à réaliser en période de maintenance car une courte rupture du service lors de la bascule est à prévoir.

3 Failover automatique avec Sentinel

3.1 Configuration

Nous venons de le voir, la réplication est simple à mettre en œuvre ou à reconfigurer. Elle a toutefois un énorme inconvénient en cas de perte du master, elle est manuelle. Nous allons donc mettre en œuvre un système complémentaire appelé Redis Sentinel qui viendra gérer automatiquement la promotion d’un nouveau master et la reconfiguration des slaves.
Commençons par installer sentinel :

sudo apt -y install redis-sentinel

Et configurer le service pour qu’il communique sur le réseau et non plus uniquement sur localhost. Au niveau firewall, le port 26379 devra autoriser les flux. Cela se fait via le fichier dédié /etc/redis/sentinel.conf :

bind 0.0.0.0
port 26379

Ajoutons un mot de passe de connexion, il s’agit du mot de passe d’authentification sur Sentinel :

requirepass SECRET

Enfin démarrons la configuration des règles de bascule. Nous monitorons l’adresse IP du master, 192.168.69. Un quorum de 2 serveurs est exigé, c’est à dire que si au moins deux slaves s’accordent sur le fait que le master est injoignable alors une bascule est enclenchée.

sentinel monitor mymaster 192.168.69.81 6379 2
sentinel auth-pass mymaster SECRET

Le master est considéré comme injoignable après une minute :

sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

Une redémarrage du service sentinel plus tard, vérifions l’état de notre service en se connectant via redis-cli sur le port de Sentinel cette fois :

redis-cli -p 26379
127.0.0.1:26379> AUTH SECRET
OK
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.69.81:6379,slaves=2,sentinels=4

Nous retrouvons bien le bon nombre de slaves. Si on souhaite des informations détaillées sur les slaves il est possible d’envoyer la commande sentinel slaves mymaster et pour les instances sentinel : sentinel sentinels mymaster. La sortie étant peu lisible, il s’agit de la configuration en mode clé valeur dans la base Redis, je ne vais pas l’inclure ici.

3.2 Test de bascule

Sur notre master, simulons une panne en arrêtant le service avec systemctl stop redis-server. En parallèle, regardons les logs de Sentinel dans /var/log/redis/redis-sentinel.log. Par lisibilité, je vais filtrer quelques peu les logs.

En premier lieu nous avons un event sdown, cela signifie que sentinel a détecté que le master n’était plus joignable :

37873:X 18 Jun 2023 21:33:04.343 # +sdown master mymaster 192.168.69.81 6379

Ensuite, nous avons un odown, c’est à dire que le serveur est vu comme injoignable par au moins le nombre de serveur du quorum, comme nous avons indiqué 2, il faut au moins les deux serveurs pour qu’une promotion d’un nouveau soit réalisée :

37873:X 18 Jun 2023 21:33:05.420 # +odown master mymaster 192.168.69.81 6379 #quorum 3/2

db03 a été élu comme nouveau master :

37873:X 18 Jun 2023 21:34:17.255 # +selected-slave slave 192.168.69.83:6379 192.168.69.83 6379 @ mymaster 192.168.69.81 6379
37873:X 18 Jun 2023 21:34:17.437 # +promoted-slave slave 192.168.69.83:6379 192.168.69.83 6379 @ mymaster 192.168.69.81 6379

db02 est reconfiguré comme slave de db03 :

37873:X 18 Jun 2023 21:34:17.453 * +slave-reconf-sent slave 192.168.69.82:6379 192.168.69.82 6379 @ mymaster 192.168.69.81 6379
37873:X 18 Jun 2023 21:34:17.510 * +slave-reconf-inprog slave 192.168.69.82:6379 192.168.69.82 6379 @ mymaster 192.168.69.81 6379
37873:X 18 Jun 2023 21:34:18.623 * +slave slave 192.168.69.82:6379 192.168.69.82 6379 @ mymaster 192.168.69.83 6379

Enfin, on peut le confirmer via la cli redis sur db03 :

127.0.0.1:6379> INFO REPLICATION
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.69.82,port=6379,state=online,offset=481996,lag=1

Félicitations, Redis s’est automatiquement reconfiguré sans intervention.
Que se passe-t-il désormais pour notre ancien master ? Au redémarrage de redis, il est devenu un slave. Cela se voit d’ailleurs dans les logs sentinel des autres serveurs. Il est possible de forcer via la cli sentinel un failover vers un autre serveur :
127.0.0.1:26379> SENTINEL failover mymaster
OK
127.0.0.1:26379> INFO sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.69.82:6379,slaves=2,sentinels=4

Il n’est toutefois pas possible d’indiquer expressément quel serveur sera promu. Une manière de le contrôler est d’utiliser la directive slave-priority pour favoriser un serveur avec une priorité plus faible.

4 HAProxy

Dans un monde idéal, votre client Redis aura un support de Sentinel. Il saura alors contacter sentinel pour connaître le master et s’y connecter. En récupérant la liste des serveurs, il sera en mesure de distribuer les requêtes en lecture sur les slaves pour répartir la charge. En cas d’anomalie du master, il saura enfin gérer le failover.

En pratique, on ne peut pas toujours connaître le niveau de support des clients notamment lorsque l’on fournit la plateforme à des développeurs tiers. Dans ce cas précis, je recommande d’utiliser le classique HAProxy qui sait tout faire en matière de répartition de charge que je vous laisse installer via les packages de la distribution.

Le cas particulier qu’il faut néanmoins gérer c’est la détection du master. De manière simple, si le port de destination répond, on considère souvent que le service est fourni par le backend. Dans notre cas, il va falloir identifier le serveur dont le rôle est le master, souvenez-vous nous avions l’information avec INFO Replication avec la CLI Redis. Il faut donc définir un TCP Check qui réalisera une authentification, enverra cette même commande est aura comme backend active celui dont le rôle est master :

frontend ft_redis
bind 0.0.0.0:6379 name redis
default_backend bk_redis

backend bk_redis
option tcp-check
tcp-check send AUTH\ SECRET\r\n
tcp-check send PING\r\n
tcp-check expect string +PONG
tcp-check send INFO\ Replication\r\n
tcp-check expect string role:master
tcp-check send QUIT\r\n
tcp-check expect string +OK
server r1 db01:6379 check inter 10s
server r2 db02:6379 check inter 10s
server r3 db03:6379 check inter 10s

Conclusion

C’est en terminé pour ce tour d’horizon de la haute disponibilité d’un service Redis Replication avec Sentinel. J’invite le lecteur curieux à compléter ce parcours pour utiliser les ACL et ajouter ce niveau de sécurité. J’ai volontairement écarté ce point pour légèrement simplifier la configuration et rester ciblé sur le sujet.

Galera, la solution pour des bases de données hautement disponibles (Publié dans Linux Pratique 137)

31 décembre 2024 à 11:27

Lorsqu’une application ne peut tolérer d’indisponibilités ou quand il devient nécessaire de fournir de la redondance au service de bases de données, il convient de mettre en place une architecture limitant les risques d’interruption de service. De même le besoin de performance peut se faire sentir avec la croissance du nombre d’utilisateurs. Galera est une extension pour MariaDB aidant à résoudre ces deux situations.

Galera est une extension pour Mariadb, MySQL et Percona XtraDB offrant des fonctionnalités de clustering multi-master. La réplication classique fonctionne en mode maitre-esclave, nécessitant donc en cas de panne ou de maintenance sur le master de mettre en œuvre un mécanisme de failover sur le slave pour le promouvoir. Cette opération est potentiellement complexe et manuelle.

Avec Galera il est possible de disposer de plusieurs serveurs master et donc disponibles en lecture comme en écriture. La réplication est opérée de manière synchrone et peut même être géo-répliquée.

Pour améliorer les performances, il devient possible d’augmenter le nombre de nœuds au sein du cluster, éventuellement complété d’une mise à l’échelle verticale, c’est à dire par ajout de vCPU et de RAM.

La haute disponibilité du service de bases de données devient donc native et ce, sans nécessiter de mettre en œuvre une opération de promotion du slave comme master. Le service est rendu tant qu’il y a au moins un nœud fonctionnel, toute question de capacité à tenir la charge mise à part.

Ensuite, Galera connaît très peu de limitations à la mise en cluster mais deux en particulier. La première a une portée en principe limitée, elle impose le moteur de stockage InnoDB, le moteur historique MyISAM est donc à oublier. La seconde, peut-être plus contraignante, est qu’une table doit avoir obligatoirement au moins une clé primaire. Cela peut donc demander du travail avec les développeurs qui vont coder avec cette base de données. Enfin, dernière limitation majeure mais ce n’en est pas une pour moi, Galera n’est disponible que sous Linux mais pas les autres systèmes supportés par MariaDB comme Windows.

Création du cluster

Un cluster Galera doit être composé d’un nombre impair de nœuds. Il n’est techniquement pas interdit de créer un cluster à seulement deux nœuds, ce n’est toutefois pas recommandé. En effet, on risque dans ce cas une situation de split brain. Un split brain est une situation où les nœuds qui composent le cluster se retrouvent isolés, par exemple en cas de coupure du réseau. Avec seulement deux nœuds, ils ne pourraient déterminer quel nœud se retrouve isolé. Cela impose donc au minimum de disposer de trois serveurs, sachant que l’ajout de nœuds au cluster est très aisé.
Pour la suite de cet article, je disposerai de quatre serveurs sous Ubuntu 22.04, trois serveurs de bases de données et un load balancer utilisé dans la suite de cet article :

  • db01 : 192.168.69.81
  • db02 : 192.168.69.82
  • db03 : 192.168.69.83
  • lb : 192.168.69.70

Installation de Mariadb

Dans un premier temps et sur chaque serveur composant le cluster, nous allons simplement y installer le service mariadb.

root@db01:~# apt -y install mariadb-server
root@db01:~# systemctl enable mariadb

Par défaut, MariaDB sous Ubuntu Server n’écoute que sur l’interface loopback. Comme les nœuds du cluster vont être accessibles et communiquer via le réseau, il faut faire en sorte que MariaDB écoute sur une socket accessible depuis les autres nœuds, idéalement en restreignant depuis une interface. Pour faire simple, nous allons le faire écouter sur toutes les interfaces :

root@db01:~# sed -i 's/^bind-address.*/bind-address = 0.0.0.0/g' /etc/mysql/mariadb.conf.d/50-server.cnf
root@db01:~# systemctl restart mariadb

Ajout du module Galera
Toujours sur chaque nœud, nous allons ensuite installer le module galera et éteindre mariadb

root@db01:~# apt -y install galera-4
root@db01:~# systemctl stop mariadb

Il faut maintenant activer la réplication avec le provider wsrep et surtout déclarer l’ensemble des nœuds participants au cluster. La configuration se fait dans le fichier /etc/mysql/mariadb.conf.d/60-galera.cnf :
wsrep_on active tout simplement la réplication Galera. Le nom du cluster doit quant à lui être identique sur l’ensemble des nœuds. Enfin, wsrep_cluster_address doit contenir les IP de tous les membres du cluster, séparés par une virgule.

[galera]
wsrep_on                 = ON
wsrep_cluster_name       = "MariaDB Galera Cluster"
wsrep_cluster_address    = gcomm://192.168.69.81,192.168.69.82,192.168.69.83
binlog_format            = row
default_storage_engine   = InnoDB
bind-address = 0.0.0.0
wsrep_slave_threads = 4
innodb_flush_log_at_trx_commit = 1
log_error = /var/log/mysql/error-galera.log

wsrep_slave_threads (wsrep_applier_threads) dans les versions plus récentes permet de gérer le nombre de threads pour traiter les write-sets, les transactions commités lors de la réplication. Généralement on souhaite avoir deux fois le nombre de cœurs du serveur pour des performances correctes.

Démarrage du cluster

La configuration précédente terminée, il est maintenant possible de démarrer le cluster. Un nœud doit être utilisé pour bootstraper le cluster avec la commande galera_new_cluster.

root@db01:~# galera_new_cluster

Cette commande initialise le Primary component du cluster et démarre Mariadb. Le primary Component est l’ensemble des nœuds qui forment le cluster, qui peuvent communiquer ensemble et assurer le commit d’une transaction. Chacun des nœuds démarrés par la suite se connecteront à ce nœud pour démarrer la réplication. En terminologie Galera, il s’agit du State Snapshot Transfert (SST).
Le journal de log définit plus tôt doit nous confirmer à ce propos que le bootstrap est lancé et que le statut du serveur passe en Joined.

2023-03-05 22:34:39 0 [Note] WSREP: Server status change initializing -> initialized
2023-03-05 22:34:39 0 [Note] WSREP: wsrep_notify_cmd is not defined, skipping notification.
2023-03-05 22:34:39 1 [Note] WSREP: Bootstrapping a new cluster, setting initial position to 00000000-0000-0000-0000-000000000000:-1
2023-03-05 22:34:39 4 [Note] WSREP: Cluster table is empty, not recovering transactions
2023-03-05 22:34:39 1 [Note] WSREP: Server status change initialized -> joined

Les autres nœuds du cluster peuvent ensuite être démarrés normalement. Ils vont se connecter au Primary Component, lancer un state transfert pour synchroniser la copie locale de la base de données afin d’être synchronisé au cluster.

root@db02:~# systemctl start mariadb

Contrôlons de nouveau nos logs, et l’on peut constaté que pas mal de lignes ont défilé. Ce que l’on doit retenir c’est que les nouveaux nœuds ont initialisé un state transfert depuis l’un des serveurs déjà synchronisés et que l’état doit être passé en « complete ».

2023-03-05 22:37:37 0 [Note] WSREP: Member 1.0 (db03) requested state transfer from '*any*'. Selected 0.0 (db02)(SYNCED) as donor.
2023-03-05 22:37:39 0 [Note] WSREP: (ea0f8bad-ad8c, 'tcp://0.0.0.0:4567') turning message relay requesting off
2023-03-05 22:37:39 0 [Note] WSREP: 0.0 (db02): State transfer to 1.0 (db03) complete.
2023-03-05 22:37:39 0 [Note] WSREP: Member 0.0 (db02) synced with group.
2023-03-05 22:37:42 0 [Note] WSREP: 1.0 (db03): State transfer from 0.0 (db02) complete.
2023-03-05 22:37:42 0 [Note] WSREP: Member 1.0 (db03) synced with group.

Chaque nœud peut ensuite être démarré ou redémarré indépendamment avec systemctl. Cependant, si chaque nœud a été arrêté proprement, le cluster n’est plus formé et il est nécessaire à nouveau de bootstrap le cluster avec galera_new_cluster.

Vous l’aurez deviné, en cas de maintenance, il conviendra de démarrer en premier le dernier nœud qui a été arrêté afin d’avoir des données cohérentes. Le problème va se poser si l’on ignore l’ordre d’arrêt ou que le cluster s’est mal arrêté. Il pourra dans ce cas être nécessaire d’indiquer que le nœud sur lequel on souhaite intialiser le bootstrap du cluster est en mesure de le prendre en charge, cela se fait dans le fichier /var/lib/mysql/grastate.dat avec la variable safe_to_bootstrap à forcer à 1. Cette valeur est à zéro après le bootstrap pour éviter une initialisation accidentelle d’un cluster déjà bootstrapé. De préférence, il s’agit d’une opération à utiliser en derniers recours.

root@db01:~# cat /var/lib/mysql/grastate.dat
# GALERA saved state
version: 2.1
uuid:    ea14ca85-bba5-11ed-bf58-0b029f897fa2
seqno:   -1
safe_to_bootstrap: 0

Tester la réplication

En théorie, notre cluster est en place. Pour le confirmer vérifions avec des données. Commençons par créer une base de données nommée galeratest qui ne comporte qu’une seule table :

root@db01:~# mysql -u root -e "CREATE DATABASE galeratest;"
root@db01:~# mysql -u root galeratest -e "CREATE TABLE test(ID int NOT NULL AUTO_INCREMENT, data varchar(255) NOT NULL, PRIMARY KEY (ID) );"

Peuplons maintenant cette table avec un millier d’enregistrements :

root@db01:~# for i in {1..1000}; do   mysql -u root galeratest -e "INSERT INTO test (\`data\`) VALUES ('test$i');"; done

Et enfin, vérifions sur un autre serveur que nous retrouvons bien nos enregistrements :

root@db02:~# mysql -u root galeratest -e "SELECT COUNT(ID) FROM test;"
+-----------+
| COUNT(ID) |
+-----------+
|      1000 |
+-----------+

C’est parfait, nous avons bien nos 1000 lignes dans la table, les données sont donc bien répliquées.
Superviser l’état du cluster

En environnement de production, il convient de vérifier que chaque nœud est connecté aux autres membres cluster et qu’il est bien répliqué. Ces opérations doivent être vérifiées à minima manuellement et ce régulièrement et idéalement automatiquement, que ce soit via des scripts ou une intégration de ceux-ci avec une solution de supervision type Nagios.

Galera permet de récupérer localement sur chaque nœud l’état du cluster avec un certain nombre de variables de statut. Les différentes variables wsrep du provider Galera sont accessibles au travers de SHOW STATUS, de manière similaire aux variables de statut de MariaDB.

A l’issue du déploiement précédent, wsrep_ready permet déjà de visualiser si le nœud est en mesure d’accepter les requêtes. Si la réponse est « OFF » le serveur renverra des erreurs aux clients.

MariaDB [mysql]> show status like 'wsrep_ready';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready   | ON    |
+---------------+-------+

Ensuite, wsrep_connected doit renvoyer ON. Si cette valeur renvoie OFF, alors le nœud n’est pas connecté au cluster. Cela peut être l’origine d’une erreur de configuration ou bien d’une anomalie réseau.

MariaDB [mysql]> show status like 'wsrep_connected';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| wsrep_connected | ON    |
+-----------------+-------+

Enfin, wsrep_cluster_size doit renvoyer le nombre de nœuds présents dans le cluster. En état nominal il s’agit logiquement du nombre de nœuds total du cluster. Toutefois cette valeur permet également de gérer les niveaux d’alertes pour lequel le nombre minimum de nœuds pour rendre le service. En théorie, un nœud suffit à rendre le service, toutes considérations de performances mises à part :

MariaDB [(none)]> show status like 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+

Ensuite, il faut vérifier que chaque nœud est connecté au primary component et donc qu’il est dans un état sain et dans un état où il peut recevoir des mises à jour des autres nœuds.

MariaDB [(none)]> show status like 'wsrep_cluster_status';
+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| wsrep_cluster_status | Primary |
+----------------------+---------+

Pour aller plus loin dans la visualisation de l’état du nœud au sein du cluster, la variable wsrep_local_state_comment donne davantage d’indications sur l’état du nœud. Cette variable possède quatre valeurs :
• Joining : le nœud est en train de rejoindre le cluster
• Donor/Desynced : le nœud est la source de réplication d’un autre nœud en train de rejoindre le cluster
• Joined : le nœud a rejoint le cluster
• Synced : le nœud est synchronisé avec le cluster

MariaDB [(none)]> show status like 'wsrep_local_state_comment';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| wsrep_local_state_comment | Synced |
+---------------------------+--------+

Enfin, au-delà de l’état du cluster, il convient de superviser les performances de réplication. La variable wsrep_local_recv_queue_avg donne la longueur moyenne de la file d’attente de réplication. Si elle est supérieure à 0 cela signifie que le node a un peu de latence dans l’application des write-sets. Au delà de 0,5 il faut vérifier qu’il n’y a pas de goulot d’étranglement. S’agissant d’une valeur moyenne, il convient d’observer dans ce cas là les valeurs minimales et maximales, wsrep_local_recv_queue_min et wsrep_local_recv_queue_max afin d’avoir l’amplitude réelle.

MariaDB [(none)]> show status like 'wsrep_local_recv_queue_avg';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| wsrep_local_recv_queue_avg | 0.142857 |
+----------------------------+----------+

Ces variables sont les principales à superviser. En pratique, il en existe une soixantaine visibles avec un « show status like ‘wsrep_%; ». La plupart ne seront d’aucune utilité mais celles présentées restent celles qu’il faut connaître impérativement.

Load balancing avec HAProxy

Notre cluster Galera est monté, les clients vont ensuite devoir s’y connecter. Si on configure les accès sur le nom d’hôte ou l’adresse IP d’un des nœuds, alors en cas d’indisponibilité de celui-ci les autres nœuds seront fonctionnels mais inutilisés. Une méthode consiste à utiliser du round robin DNS. C’est à dire que pour un nom d’hôte, on va déclarer trois enregistrements type A pointant vers chacuns des adresses IP des nœuds du cluster. Cependant cette solution n’est pas idéale et peut renvoyer vers un nœud non fonctionnel.

Une meilleure solution consiste à utiliser un load balancer qui va exposer le service MariaDB mais qui aura en backend les différents nœuds qui composent le cluster Galera. Le load balancer permet en outre de tester la disponibilité des backends et ne présente que les nœuds fonctionnels. HAProxy est le load balancer libre le plus populaire et le plus aboutit pour gérer ces situations. Commençons pas l’installation sur une VM dédiée.

root@lb:~# apt -y install haproxy
root@lb:~# systemctl enable haproxy

En suite, nous aurons besoin d’un utilisateur non privilégié qui permettra à HAProxy de s’authentifier pour vérifier qu’une connexion peut être établie.

MariaDB [mysql]> CREATE USER 'haproxy'@'192.168.69.70';

Enfin nous allons configurer HAProxy dans le fichier /etc/haproxy/haproxy.cfg et ajouter ces lignes à la fin du fichier.

listen galera
    bind 192.168.69.70:3306
    balance leastconn
    mode tcp
    option tcpka
    option mysql-check user haproxy
    option tcplog
    server db1 192.168.69.81:3306 check weight 1
    server db2 192.168.69.82:3306 check weight 1
    server db3 192.168.69.83:3306 check weight 1

Le service Galera est exposé sur le port MariaDB classique, 3306/TCP via l’IP du load balancer 192.168.69.70. Balance leastconn est l’algorithme de répartition de charge, dans ce cas il s’agit d’envoyer les connexions vers le serveur qui en a le moins, nous pourrions tout autant utiliser du round robin ou du source IP. Le check mysql-check est utilisé avec l’utilisateur haproxy créé précédemment. Haproxy enverra un paquet pour s’authentifier et un second pour mettre fin proprement à la connexion. Un simple check tcp engendrerait dans les logs une fin prématurée de la connexion. Enfin, on définit chaque nœud vers lequel on renvoie les connexions. Check sert à indiquer qu’on teste la disponibilité du backend et weight 1 que les connexions seront distribuées de manière équitable entre les backends.

Un redémarrage du service plus tard et on peut contrôler l’état de nos backends avec hatop. Si au moins un backend apparaît comme UP l’accès au travers de la VIP est possible.

root@lb:~# systemctl restart haproxy
root@lb:~# hatop -s /run/haproxy/admin.sock

Idéalement et dans un contexte de production, il faudrait également mettre en haute disponibilité le load balancer via une paire de load balancer HAProxy partageant une VIP en VRRP avec Keepalived par exemple. Ceci afin de ne pas créer de nouveau point unique de panne. Mais cela dépasse le cadre de cet article.

Conclusion

Galera est un moyen simple pour monter une solution de Haute Disponibilité pour vos bases de données MariaDB avec peu de contraintes d’exploitation. Il n’y a donc plus de raisons de réveiller les admins la nuit pour dépanner un serveur MariaDB en mono serveur dès lors que vous administrez des applications critiques. Pour aller plus loin, il s’agit d’un sujet qui se prête particulièrement bien à des déploiements orchestrés par Ansible ou Puppet.

Références
[BASEDOC] Base documentaire des Éditions Diamond : https://connect.ed-diamond.com/
[1] Documentation officielle de Galera : https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/
[2] Aller plus loin avec MariaDB, LP 130 par Masquelin Mickaël
[3] À la découverte d’HAProxy, LP HS 55 par Assmann Baptiste (bedis)

❌