Analyse post-incident de l’incident Kagi de la semaine dernière
(status.kagi.com)Résolution du problème d’instabilité du service Kagi.com
- En cours d’investigation - Un problème est survenu après un déploiement et l’équipe travaille à sa résolution. (12 janvier, 16:45 UTC)
- Surveillance - L’équipe a annulé un changement de configuration soupçonné d’être à l’origine du problème et surveille en continu le retour à la normale du service. (12 janvier, 18:30 UTC)
- Mise à jour - Afin de rétablir complètement la stabilité, le trafic sera brièvement interrompu et les utilisateurs seront redirigés vers cette page. Des détails supplémentaires seront fournis à mesure que la situation évolue pendant la restauration contrôlée de la charge sur le service. (12 janvier, 20:26 UTC)
- Surveillance - Le trafic a été rétabli et l’équipe continue de surveiller le retour complet à la normale du service. (12 janvier, 21:14 UTC)
- Résolu - Tous les services fonctionnent normalement. L’équipe remercie les utilisateurs d’avoir patienté pendant la résolution du problème.
Analyse post-incident
- Zac, responsable technique chez Kagi, a partagé une analyse post-incident détaillée de l’interruption de service de la semaine dernière.
- En réponse à cet incident, l’ingénieur senior Seth et l’ingénieur DevOps Luan ont travaillé ensemble.
- Des acteurs ont abusé du service et exploité des goulots d’étranglement de l’infrastructure ; des mesures d’atténuation immédiates ont été prises et des améliorations sont en cours dans plusieurs domaines du code et de la communication.
Déroulement de l’incident
- Le 12 janvier vers 17 h 30, un problème d’infrastructure a été détecté via la surveillance interne et les signalements des utilisateurs.
- La nature du problème provoquait des chargements lents ou des expirations de page pour des utilisateurs dans différentes régions.
- La résolution a pris un temps considérable, et l’équipe a expliqué le contexte, l’évolution de la situation et le plan à venir.
Processus de résolution technique
- Au départ, le problème est survenu par coïncidence au moment d’une augmentation des ressources RAM sur une VM.
- La surveillance signalait une latence élevée et un problème de pool de connexions à la base de données dans l’application.
- Le pool de connexions était arrivé à saturation, ce qui signifiait que le nombre total de connexions dépassait la limite maximale configurée.
- Pendant l’évaluation de l’état interne de la base de données et des performances des requêtes, quelques instances ont été remplacées pour tester l’effet sur la réduction de la congestion.
- Comme le remplacement d’une partie des instances semblait aider, le trafic utilisateur a été temporairement suspendu afin de réinitialiser complètement tous les pools de connexions en une seule fois.
- L’examen de l’état de la base de données a clairement montré que la cause racine était une forte contention sur les lignes de la table des utilisateurs.
- Cette contention a fortement augmenté la latence d’écriture, créant une contre-pression sur le pool de connexions de l’application, jusqu’à épuiser toutes les connexions disponibles.
- Jusqu’à présent, Kagi utilisait la base de données mono-cœur la moins chère disponible sur GCP, ce qui comportait le risque de rendre facilement la base de données inopérante.
- En identifiant les acteurs malveillants, l’équipe a découvert des comptes créés dans les 24 heures ainsi qu’un compte utilisateur unique ayant effectué plus de 60 000 recherches en peu de temps.
- La fonction de recherche a été retirée à ce compte, et un hotfix a été publié pour désactiver l’écriture spécifique à l’origine du problème.
- À minuit, le problème était entièrement résolu, et l’équipe a continué de surveiller de près tout signe de retour de ces acteurs.
Mesures à venir
- Kagi indique avoir beaucoup appris de cet incident et avoir déjà lancé des plans immédiats pour renforcer davantage le système et améliorer le processus de communication en cas d’incident.
- L’entreprise reconnaît d’abord que les mises à jour de la page de statut n’ont pas été assez rapides.
- Elle prévoit de migrer vers une plateforme de page de statut permettant d’exposer plus facilement la surveillance interne automatisée aux utilisateurs, afin qu’ils puissent voir en temps réel l’état de santé de la plateforme.
- L’équipe atténue directement les requêtes problématiques et mène des tests de charge pour déterminer si d’autres failles similaires existent.
- Une surveillance supplémentaire sera mise en place pour pointer plus rapidement vers le bon emplacement dans l’infrastructure et éviter de perdre du temps à suivre de faux signaux comme ce fut le cas cette fois.
- Les systèmes de détection de ce type d’abus sont également en cours de renforcement, et comme ils ont un impact direct non seulement sur les performances mais aussi sur les coûts, il est nécessaire de mettre en place des limitations automatisées pour les faire respecter.
- Les nouvelles limitations étaient déjà en vigueur au moment de cette publication, et leur impact sera surveillé tout en continuant à les ajuster si nécessaire.
- Kagi demande à toute personne pensant avoir été bloquée à tort dans son accès au service de contacter support@kagi.com.
L’avis de GN⁺
- Kagi a subi un problème de latence d’écriture causé par une contention sur les lignes de la table des utilisateurs, ce qui a créé une contre-pression sur le pool de connexions de l’application et provoqué l’interruption du service.
- Ce problème était la conséquence du risque lié à l’utilisation par Kagi de la base de données mono-cœur la moins chère sur GCP.
- À travers cet incident, l’équipe Kagi montre sa volonté d’améliorer la stabilité et la transparence du service en prenant des mesures pour renforcer le système, améliorer la communication avec les utilisateurs et mettre en place des limitations automatisées pour prévenir les abus. Ces efforts reflètent la volonté de Kagi de fournir un service plus fiable à ses utilisateurs.
1 commentaires
Avis sur Hacker News
Au départ, il s’est avéré que le fait que la mise à niveau de l’infrastructure pour ajouter de la RAM à la VM et la panne se soient produites exactement au même moment relevait d’une pure coïncidence, mais ce genre de « coïncidence » arrive vraiment souvent et finit par faire douter de son existence même pendant qu’on cherche la cause du problème
Quand on panique dans cet état, on finit par pousser un correctif d’urgence (hotfix) qui casse autre chose, et à partir de là, ça devient bien plus douloureux
La loi de Murphy est cruelle pour les administrateurs système et les développeurs
J’aime bien cette formule : « si on ne sait pas pourquoi/comment on l’a corrigé, alors on ne l’a peut-être pas vraiment corrigé »
« Heureusement », ça n’avait rien à voir avec ma requête, mais quand deux coïncidences de ce genre se superposent, c’est vraiment terrifiant
Après avoir vécu ce genre de situation suffisamment de fois, j’ai pris l’habitude de remettre en cause davantage d’hypothèses et de ne pas présenter comme données confirmées ce qui n’a pas encore été vérifié
Ça n’a pas complètement supprimé mes biais ni mes conclusions hâtives, mais ça m’a aidé, et garder l’esprit ouvert est assez difficile
Une compétence importante pour un ingénieur, c’est de pouvoir raisonner de manière critique sur les changements faits pendant la réponse à incident, les déboguer et les « tester en isolation ». C’est bien plus difficile qu’il n’y paraît et cela relève souvent plutôt d’un niveau senior
J’étais l’un des utilisateurs à avoir signalé ce problème sur Discord. J’aime bien Kagi, mais voir la page d’état indiquer que tout allait bien était assez décevant
Voir que la page d’état ne semblait pas prioritaire même pendant un incident qui affectait de vrais utilisateurs m’a rendu inquiet, et j’espère qu’elle sera mise à jour correctement à l’avenir
Par le passé, des services sur lesquels je comptais beaucoup, comme GitHub, mettaient leur page d’état à jour immédiatement, ce qui me rassurait en me confirmant que le problème venait bien du service et non de mon appareil
Cette fois-là, je devais trouver une épicerie ouverte à proximité avant qu’il ne neige ce jour-là, et j’ai finalement dû passer par Google, ce qui était un peu décevant
Cela dit, 99,9 % du temps passé avec Kagi a été meilleur qu’avec Google, donc je vais continuer à l’utiliser, et j’espère, comme indiqué dans l’analyse post-mortem, qu’ils déplaceront le code de la page d’état vers un autre service/une autre plateforme
Au final, publier quoi que ce soit sur la page d’état devient en soi une conversation, et cette conversation consomme du temps et de l’attention d’ingénieurs, ce qui retarde d’autant la résolution de l’incident
Il faut trouver un équilibre entre la communication et la restauration effective du service, et la bonne réponse n’est pas toujours évidente
Quand on a assez de monde, un Technical Incident Manager peut prendre en charge la communication et on peut aussi ajouter des ingénieurs côté communication, mais ce n’est pas toujours possible. Certains systèmes sont particuliers, mal documentés et insuffisamment instrumentés
Personnellement, je préfère publier immédiatement une annonce large et vague du type « nous enquêtons sur un problème potentiel » dès qu’on voit des signes de souci, puis compléter les détails ou retirer l’annonce plus tard. Mais les entreprises où j’ai travaillé n’aimaient pas cette approche
C’est là que j’ai vraiment été séduit par Kagi, et j’ai commencé à alterner pour certaines requêtes, mais avec les LLM, Perplexity et Google qui répondent de plus en plus souvent directement sur la page de recherche, il ne reste plus beaucoup de requêtes que je fais sur Kagi
Si Kagi fusionnait d’une manière ou d’une autre avec Perplexity, ce serait assez intéressant
Souvent, ils ne l’indiquent même jamais
Cette panne est étonnamment familière
J’ai eu à gérer exactement ce même type de panne plus de fois que je ne voudrais l’admettre, et comme l’équipe de Kagi, je suis tombé dans le terrier du lapin de l’état du pool de connexions à la base de données, en essayant les mêmes mesures d’atténuation, comme ajouter de nouvelles instances ou « réinitialiser » le trafic en pensant que cela réglerait le problème, pour finalement n’obtenir aucun résultat
Dans ce genre de panne, le fait que les métriques classiques de saturation de base de données, comme l’utilisation CPU, les IOPS, etc., bougent à peine n’aide pas non plus. On voit bien que la latence des requêtes est élevée, mais on se dit « il reste de la marge côté CPU et IOPS… », puis on rate, comme toujours, le fait qu’une contention sur les verrous est cachée derrière
D’après mon expérience, 98 % des anomalies du pool de connexions DB viennent en réalité d’anomalies de la DB elle-même. Je ne sais pas quelle base de données relationnelle utilise Kagi, mais je recommande vivement de tracer le temps d’attente I/O global de la DB (secondes/seconde), le temps global d’acquisition des verrous (secondes/seconde), ainsi que le temps d’exécution par requête normalisée (secondes/seconde)
Si on y ajoute un graphique d’utilisation CPU, on obtient un tableau de bord qui permet d’identifier rapidement la plupart des gros problèmes de performance
À part ça, il est un peu surprenant que les requêtes de recherche déclenchent des écritures dans une base de données relationnelle. J’aurais pensé qu’une base relationnelle ne servait qu’aux préférences utilisateur, à la gestion des connexions et ce genre de choses
Si Kagi fait son comptage d’usage, par exemple l’incrément de compteurs, dans une base de données relationnelle, c’est un mode d’échec très classique qui explose à mesure que l’échelle augmente
Il peut bien sûr y avoir des écritures indirectes liées à la recherche, comme lorsqu’on bloque des résultats, ainsi que l’historique de visite ou l’analytique
Mais il n’est toujours pas évident de voir ce qui pourrait provoquer une contention de verrous en écriture à chaque recherche
C’est le genre de chose que toutes les startups finissent par vivre un jour. Je l’ai vécu, et c’est vraiment douloureux
On manque parfois du temps ou des ressources pour bâtir les capacités qui empêcheraient ce type de problème, et il arrive aussi qu’on ne pense même pas qu’un incident précis puisse se produire avant de se le prendre en pleine figure
La transparence est importante, apprendre l’est aussi, mais parfois la compensation compte également. Kagi devrait envisager d’accorder des crédits de recherche pour la période pendant laquelle le service n’était pas utilisable
D’autant plus qu’ils ont eux-mêmes reconnu que la réponse en temps réel avait été insuffisante
Une panne sur un service payant, ce n’est pas la même chose qu’une panne sur un service où « l’utilisateur est le produit »
Cela montre beaucoup de choses sur le niveau d’observabilité des systèmes internes
Il est facile de dire qu’ils auraient dû s’en rendre compte plus tôt, mais avec les bons dashboards Datadog et les bonnes requêtes Splunk, cela serait apparu bien plus vite et bien plus clairement
J’espère qu’ils prendront cela comme une occasion d’apprendre et d’investir dans une meilleure supervision
Cet incident a été une expérience d’apprentissage à 100 %, mais je peux donner un peu plus de contexte sur l’observabilité
Kagi est une petite équipe, et en pratique nous ne sommes que 3 à pouvoir répondre à ce genre d’événement, répartis sur 3 fuseaux horaires. Pour moi et pour le développeur principal, c’est encore le début de notre carrière web, donc nous ne sommes pas des vétérans de la Silicon Valley qui ont déjà tout vu
Il est évident qu’il nous reste beaucoup à apprendre, mais comme nous avons construit Kagi à partir de rien, nous sommes fiers du chemin parcouru jusqu’ici et de la direction que nous prenons
Nous avons commencé à traiter l’observabilité plus sérieusement depuis environ 6 mois. Nous avons maintenant beaucoup de dashboards, ainsi que des alertes qui arrivent directement dans les canaux de chat de l’entreprise et appellent les personnes concernées
En tant que principal responsable de la base de données, Query Insights de GCP m’aide énormément. Pendant l’incident, les alertes de monitoring se sont bien déclenchées et Query Insights montrait aussi la requête « coupable », mais même avec tout le monitoring du monde, on peut manquer d’expérience pour interpréter la cause racine ou la mesure d’atténuation la plus efficace
Autrement dit, nous n’avons pas encore assez de recul pour éviter de nous faire gaslighter par ce que nous montrent nos propres systèmes si nous ne faisons pas attention. Avec le recul, je peux dire que GCP Query Insights avait raison à 100 % et que le problème ne venait pas de la couche applicative
Grâce à notre croissance, nous pouvons désormais agrandir l’équipe de façon significative. Nous avons déjà eu recours à du conseil SRE par le passé, et nous comptons continuer à nous améliorer avec davantage de soutien, à temps plein ou à temps partiel
Donc un seul utilisateur a lancé un scraper et a mis le service à terre pendant 7 heures ? Je sais qu’il est facile de dire de l’extérieur « il fallait l’anticiper », mais je trouve étrange que personne ne se soit demandé pendant les tests : « que se passe-t-il si le volume de recherches explose ? »
https://news.ycombinator.com/item?id=39019936
En résumé, nous avons très peu de personnel clé, une équipe jeune, et tout le monde cumule plusieurs rôles. Nous n’avons pas encore d’équipe SRE dédiée
À propos de « que se passe-t-il si le volume de recherches explose ? », si vous regardez https://kagi.com/stats, vous verrez qu’il y a déjà « beaucoup de recherches », et qu’on approche des 400 000 par jour. En temps normal, le système fonctionne avec une marge de capacité suffisante et certaines mesures d’auto-scaling sont déjà en place
Le problème venait de détails exploités par certains utilisateurs dans des cas pathologiques. Par manque d’expérience, nous ne savions pas vraiment si nous aurions pu prévoir et simuler à l’avance certains trafics naturels ou pathologiques
Simuler en charge 20 000 utilisateurs lançant des recherches simultanément semble être une expérience qui valait la peine d’être tentée au début, et nous avons fait des choses comparables. Mais au vu de cette panne, cela n’aurait sans doute pas suffi à détecter ce problème
Jusqu’ici, une dizaine de personnes ont lancé des scanners de sécurité sur le service en production, et le trafic généré à ces occasions était supérieur à celui de cette panne
Il est très difficile de trouver le bon équilibre dans ce type de développement quand il faut aussi livrer des fonctionnalités, et il est clair que nous aurions dû en faire davantage. Comme je l’ai dit ailleurs, nous comptons agrandir l’équipe prochainement pour éviter que ces efforts soient trop dispersés
Avec le recul, il y a beaucoup de choses à dire, mais j’espère que cela explique de façon plus transparente comment nous en sommes arrivés là
Surtout si c’est la première fois que quelqu’un les frappe de cette manière
À titre de comparaison, le système dont je m’occupe n’est pas à l’échelle FAANG, mais en taux de requêtes il est clairement plus gros que Kagi. Kagi apprendra vite, et même si ce genre de problème se reproduit entre-temps, je pense qu’un certain niveau de tolérance est acceptable. C’est aussi le signe qu’ils avancent dans la bonne direction
En tant qu’utilisateur payant de Kagi, cette indisponibilité m’a fait réaliser à quel point je tenais pour acquise la fiabilité de Google
En dehors d’une seule fois peut-être, Google n’a jamais été indisponible pour moi en 20 ans. Perdre l’accès à un moteur de recherche, c’est assez critique
J’aime vraiment Kagi, au point de payer pour, mais subir une panne dès mon deuxième mois d’utilisation m’a quand même laissé un malaise. J’aime les analyses post-mortem, mais j’espère ne pas avoir à en lire souvent
Malgré tout, j’espère que cette expérience aidera Kagi à devenir un service plus résilient et plus fiable
Un moteur de recherche n’est pas un service avec effet de verrouillage comme un fournisseur d’e-mail ou un FAI
J’avais clairement pris l’habitude de compter sur le fait que Kagi soit rapide et fonctionne bien partout
Ça me rappelle quand, chez un client, nous faisions tourner une preuve de concept pour un nouvel outil réseau. Environ 2 minutes après le lancement, tout le réseau du client est tombé
Nous étions dans une zone sandbox isolée, donc il n’y avait aucun moyen que notre produit puisse provoquer une panne du réseau entier, mais dans ma tête c’était quand même : « ce n’est pas possible, si… si… ?!? »
« Plus tard, nous avons pu entrer en contact avec le compte bloqué, qui a affirmé l’utiliser pour scraper automatiquement nos résultats, ce qui n’est pas autorisé par les conditions d’utilisation. »
Il faut appliquer une limite de QPS à toutes les requêtes RPC/API/HTTP possibles en entrée, en particulier aux requêtes publiques.
Nous avions une fonction de recherche avec autocomplétion, et pour prendre en charge les utilisateurs qui tapent vite, nous avions volontairement supprimé la limitation de débit sur cet endpoint.
Un jour, vers 6 h du matin, quelqu’un dans le Tennessee est arrivé au travail, a posé son portefeuille sur son clavier, et le portefeuille a maintenu une touche enfoncée, déclenchant l’API à chaque frappe.
Évidemment, au bout d’environ 15 minutes, la base de données est devenue très instable, et la latence de la base a tellement augmenté qu’un des serveurs web a crashé. Une panne en cascade a suivi, et tout le cluster de production est tombé.
Inutile de préciser que la limitation de débit a été rétablie ce jour-là.