Comment nous avons accidentellement brûlé 72000 $ en deux heures sur Google Cloud Platform et avons failli faire faillite





L'histoire de la façon dont nous nous sommes retrouvés au bord de la faillite, n'ayant même pas le temps de lancer le premier produit, comment nous avons réussi à survivre et quelles leçons nous en avons tirées.



En mars 2020, lorsque COVID a frappé le monde, notre startup Milkie Way a également été durement touchée et a failli être fermée. Nous avons dépensé 72 000 $ en recherchant et en testant en interne Cloud Run avec Firebase pendant plusieurs heures.



J'ai commencé à développer le service Announce en novembre 2019. L'objectif principal était de publier la première version fonctionnelle minimale du produit, de sorte que le code fonctionnait sur une pile simple. Nous avons utilisé JS, Python et déployé notre produit sur Google App Engine.



Avec une très petite équipe, nous nous sommes concentrés sur le codage, le développement de l'interface utilisateur et la préparation des produits. Je n'ai presque pas passé de temps à gérer le cloud - j'ai passé juste assez pour mettre le système en marche et fournir un processus de développement de base (CI / CD).





Annonce de bureau



La première version n'était pas très pratique, mais nous voulions juste sortir une version pour les expériences, puis travailler sur la version normale. En raison de COVID, nous avons pensé que c'était le bon moment pour se lancer, car les agences gouvernementales du monde entier peuvent utiliser Announce pour publier des alertes.



N'est-il pas formidable de générer des données sur la plate-forme lorsque les utilisateurs n'ont pas encore téléchargé leur contenu? Cette réflexion a conduit à un autre projet, Announce-AI pour la génération de contenu. Les données riches sont divers événements tels que les alertes de tremblement de terre et les nouvelles locales éventuellement pertinentes.



Quelques détails techniques



Nous avons utilisé Cloud Functions pour commencer à développer Announce-AI. Comme notre robot de raclage en était encore à ses débuts, nous avons décidé de prendre ces fonctionnalités légères. Mais il y a eu des problèmes de mise à l'échelle car les fonctions cloud ont un délai d'expiration d'environ 9 minutes



Et tout à coup, nous avons découvert le système Cloud Run, qui avait alors une grande limite gratuite! Sans le comprendre complètement, j'ai demandé à l'équipe de déployer la fonction "test" Announce-AI dans Cloud Run et d'évaluer ses performances. L'objectif était de jouer avec Cloud Run pour acquérir de l'expérience.





Google cloud run



Comme nous avons un très petit site, nous avons utilisé une base de données Firebase pour plus de simplicité, puisque Cloud Run ne dispose d'aucun stockage et que le déploiement de SQL Server ou d'une autre base de données est trop excessif pour le test.



J'ai créé un nouveau projet GCP ANC-AI Dev, configuré mon budget de facturation cloud à 7 $, enregistré mon projet Firebase avec un plan gratuit (Spark). Le pire des cas que nous ayons imaginé est de dépasser la limite quotidienne de Firebase.



Après quelques modifications, nous avons préparé le code, effectué quelques requêtes manuelles, puis l'avons laissé en marche.



Le cauchemar commence



Le jour des tests, tout s'est bien passé et nous sommes revenus sur le développement d'Announce. Le lendemain après le travail, en fin d'après-midi, je suis allé faire une sieste. Quand je me suis réveillé, j'ai vu plusieurs e-mails de Google Cloud, tous à des intervalles de plusieurs minutes.



Première lettre: mise à jour automatique de notre projet Firebase





Deuxième lettre: budget dépassé





Heureusement, ma carte avait une limite de 100 $. Pour cette raison, les paiements n'ont pas été effectués et Google a suspendu le service de nos comptes.



Troisième lettre: carte refusée





J'ai sauté du lit, suis entré dans la facturation Google Cloud et j'ai vu une facture d'environ 5 000 $. Paniqué, il se mit à cliquer sur les touches, ne comprenant pas ce qui se passait. En arrière-plan, j'ai commencé à me demander comment cela aurait pu se produire et comment payer la facture de 5000 $, auquel cas.



Le problème était que le score augmentait à chaque minute.



En cinq minutes, il a montré 15 000 $, en 20 minutes - 25 000 $. Je ne savais pas quand les chiffres cesseraient d'augmenter. Peut-être vont-ils grandir indéfiniment?



Deux heures plus tard, le chiffre s'est arrêté à un peu moins de 72 000 $.



À ce moment-là, l'équipe et moi étions en téléconférence, j'étais complètement choquée et je n'avais absolument aucune idée de ce que je devais faire ensuite. Nous avons désactivé la facturation, fermé tous les services.



Étant donné que dans tous les projets GCP que nous avons réglés avec une seule carte, tous nos comptes et projets ont été suspendus.



Le cauchemar continue



Cela s'est produit vendredi soir, 27 mars - trois jours avant que nous ayons prévu de lancer la première version. Désormais, le développement s'est arrêté car Google a suspendu tous nos projets liés à une carte. Mon moral était au-dessous du plancher et l'avenir de l'entreprise semblait incertain.





Tous nos projets cloud sont en attente, le développement est arrêté.Dès



que mon esprit s'est résigné à la nouvelle réalité, à minuit j'ai décidé de comprendre ce qui s'était passé normalement. J'ai commencé à rédiger un document avec une enquête détaillée sur l'incident ... et je l'ai appelé "Chapitre 11" [c'est un chapitre de la loi sur la faillite - env. par.].



Deux collègues qui ont participé à l'expérience sont également restés éveillés toute la nuit, recherchant et essayant de comprendre ce qui s'était passé.



Le lendemain matin, samedi 28 mars, j'ai appelé et écrit des lettres à une douzaine de cabinets d'avocats pour prendre rendez-vous ou parler à un avocat. Ils étaient tous absents, mais j'ai pu obtenir une réponse de l'un d'eux par e-mail. Étant donné que les détails de l'incident sont si complexes, même pour les ingénieurs, l'expliquer à un avocat dans un anglais simple n'a pas été facile en soi.



Pour nous, en tant que start-up, il n'y avait aucun moyen de récupérer 72 000 $.



À ce moment-là, j'avais déjà étudié en profondeur les 7e et 11e chapitres du droit de la faillite et je me suis mentalement préparé à ce qui pourrait se passer ensuite.



Un peu de répit: les failles de GCP



Samedi, après avoir envoyé des e-mails aux avocats, j'ai commencé à lire et à parcourir chaque page de la documentation GCP. Nous avons fait des erreurs, mais il était inutile que Google nous laisse dépenser 72 000 $ de façon spectaculaire si nous n'avions pas effectué de paiement auparavant!





GCP et Firebase



1. Mise à niveau automatique d'un compte Firebase vers un compte payant



Nous ne nous attendions pas à cela, et cela n'a été averti nulle part lors de l'enregistrement sur Firebase. Notre facturation GCP était connectée à l'exécution de Cloud Run, mais Firebase relevait d'un plan gratuit (Spark). GCP vient de sortir de nulle part est passé à un forfait payant et nous a facturé le montant requis.



Il s'avère qu'ils appellent ce processus "intégration profonde de Firebase et GCP".



2. Il n'y a pas de «limites» de facturation. Les budgets sont en retard d'au moins un jour



La facturation GCP est effectivement retardée d'au moins 24 heures. Dans la plupart des documents, Google suggère d'utiliser les budgets et la fonction d'arrêt automatique du cloud. Mais au moment où la fonction d'arrêt est déclenchée ou qu'une notification est envoyée à l'utilisateur, le dommage est déjà fait.



Il faut environ une journée pour synchroniser la facturation, c'est pourquoi nous avons remarqué la facture le lendemain.



3. Google aurait dû prendre 100 $, pas 72 000!



Étant donné qu'aucun paiement n'a été effectué à partir de notre compte jusqu'à présent, GCP a d'abord dû prélever des frais de 100 USD conformément aux informations de facturation, et s'il ne payait pas, arrêter le service. Mais cela ne s'est pas produit. J'ai découvert la raison plus tard, mais ce n'est pas non plus la faute de l'utilisateur!



La première facture pour nous était d'environ 5000 $. Le montant suivant est de 72 000 USD.





Le seuil de facturation de notre compte est de 100 USD.



4. Ne vous fiez pas à votre tableau de bord Firebase!



Non seulement la facturation, mais également la mise à jour du tableau de bord Firebase ont pris plus de 24 heures.



Selon la documentation de la console Firebase, les chiffres du tableau de bord peuvent différer "légèrement" des rapports de facturation.



Dans notre cas, ils différaient de 86 585 365,85%, soit 86 millions de points de pourcentage. Même lorsque la facture est arrivée, la console Firebase affichait toujours 42 000 lectures et écritures par mois (en dessous de la limite quotidienne).



Nouveau jour, nouveau défi



Après six ans et demi chez Google et la rédaction de dizaines de documents de projet, de rapports d'enquête, etc., j'ai commencé à rédiger un document pour Google, décrivant l'incident et ajoutant des failles de Google au rapport. L'équipe Google sera de retour au travail dans deux jours.



Correction: certains lecteurs ont suggéré que j'utilisais mes contacts Google internes. En fait, je n'ai communiqué avec personne et j'ai choisi le chemin que tout développeur ou entreprise normal suivrait. Comme tout autre petit développeur, j'ai passé d'innombrables heures à discuter, à consulter, à rédiger de longs e-mails et à signaler des bogues. Dans l'un des articles suivants sur le rapport d'incident, je montrerai les documents que j'ai soumis à Google.





Last Day chez Google



De plus, il était nécessaire de comprendre nos erreurs et de développer une stratégie de développement produit. Tout le monde dans l'équipe n'était pas au courant de l'incident, mais il était assez clair que nous avions de gros problèmes.



Chez Google, j'ai rencontré des millions de dollars d'erreur humaine, mais la culture de Google sauve les employés (sauf que les ingénieurs doivent rédiger de longs rapports plus tard). Cette fois, il n'y avait pas de Google. Notre propre petit capital et notre travail acharné sont en jeu.



L'Himalaya inébranlable nous dit ...



C'était la première fois que je recevais un tel coup. Cela pourrait changer l'avenir de notre entreprise et ma vie. Cet incident m'a appris plusieurs leçons de commerce, dont la plus importante - prendre un coup.



À l'époque, j'avais une équipe de sept ingénieurs et stagiaires, et il a fallu environ dix jours à Google pour nous répondre à propos de cet incident. En attendant, il fallait reprendre le développement, trouver un moyen de contourner la suspension des comptes. Malgré tout, nous avons dû nous concentrer sur les fonctionnalités et notre produit.





Poème "Le Stalwart Himalaya nous dit"



Pour une raison quelconque, un poème de mon enfance tournait constamment dans ma tête. C'était mon livre préféré, et je m'en suis souvenu mot pour mot, même si la dernière fois que je l'ai lu il y a plus de 15 ans.



Qu'avons-nous fait réellement?



En tant que toute petite équipe, nous voulions éviter de dépenser en matériel le plus longtemps possible. Le problème Cloud Functions et Cloud Run était expiré.



Une instance récupérera continuellement les URL de la page. Mais après 9 minutes, il y aura un temps mort.



Ensuite, après avoir discuté du problème avec désinvolture, j'ai noté le code brut sur le tableau noir en quelques minutes. Maintenant, j'ai réalisé que ce code avait beaucoup de défauts architecturaux, mais ensuite nous visions des cycles rapides de correction de bogues pour apprendre et essayer de nouvelles choses rapidement.





Announce-AI concept à Cloud Run



Pour surmonter la limitation du délai d'expiration, j'ai suggéré d'utiliser des requêtes POST (avec une URL en tant que données) pour soumettre des travaux à une instance et - de lancer plusieurs instances en parallèle, plutôt que de les mettre en file d'attente pour une. Étant donné que chaque instance de Cloud Run ne supprimera qu'une seule page, il n'y aura jamais de délai d'expiration, toutes les pages seront traitées en parallèle (mise à l'échelle bien) et le processus est hautement optimisé car Cloud Run est consommé avec une précision de la milliseconde.





Cloud Run Scraper



Si vous regardez de plus près, il manque quelques détails importants au processus.



  1. Une récursion exponentielle continue se produit: les instances ne savent pas quand s'arrêter car il n'y a pas d'instruction break.

  2. Les requêtes POST peuvent avoir la même URL. S'il existe un lien vers la page précédente, le service Cloud Run restera bloqué dans une récursivité infinie, mais pire que tout, cette récursivité est multipliée de manière exponentielle (le nombre maximum d'instances a été fixé à 1000!)


Comme vous pouvez l'imaginer, cela a abouti à une situation où 1000 instances font des requêtes et écrivent dans Firebase DB toutes les quelques millisecondes. Nous avons vu qu'il y avait environ 1 milliard de requêtes par minute passant par les lectures Firebase à un moment donné!





Récapitulatif des transactions de fin de mois GCP



116 milliards de lectures et 33 millions d'écritures



La version expérimentale de notre application sur Cloud Run a effectué 116 milliards de lectures et 33 millions d'écritures sur Firestore. Oh!



Coûts de lecture de Firebase:



(0,06 / 100 000) * 116 000 000 000 = 69 600 USD


16000 heures de Cloud Run



Après avoir testé, après avoir arrêté les journaux, nous avons conclu que la demande était morte, mais en fait elle était entrée dans un processus en arrière-plan. Comme nous n'avons pas désinstallé les services (nous utilisions Cloud Run pour la première fois et ne l'avions pas vraiment compris), plusieurs services ont continué à fonctionner lentement.



En 24 heures, tous ces services sur 1 000 instances ont été exécutés pendant un total de 16 022 heures.



Toutes nos erreurs



Déployer l'algorithme erroné dans le cloud



A déjà été discuté ci-dessus. Nous avons trouvé une nouvelle façon d'utiliser les requêtes POST sans serveur que je n'ai trouvé nulle part sur Internet, mais nous l'avons déployée sans spécifier l'algorithme.



Déployer Cloud Run avec les paramètres par défaut



Lorsque nous avons créé le service Cloud Run, nous avons choisi les valeurs par défaut pour celui-ci. Le nombre maximal d'instances est de 1 000 et la concurrence est de 80 demandes. Nous ne savions pas que ces valeurs sont en fait le pire des cas pour le programme de test.



Si nous choisissons max-instances = 2, le coût serait 500 fois inférieur.



Si nous définissons la concurrence = 1, nous ne remarquerons même pas le score.



Utiliser Firebase sans bien comprendre



Vous ne comprenez quelque chose que par expérience. Firebase n'est pas un langage à apprendre, c'est une plateforme de conteneurs. Ses règles sont déterminées par une société Google spécifique.







De plus, lors de l'écriture de code dans Node.js, vous devez penser aux processus d'arrière-plan. Si le code entre dans des processus d'arrière-plan, il n'est pas facile pour le développeur de savoir que le service est en cours d'exécution. Comme nous l'avons appris plus tard, cela a également causé la plupart des délais d'expiration de nos fonctions Cloud.



Les bogues rapides et les correctifs rapides sont une mauvaise idée dans le cloud



Le nuage dans son ensemble est comme une épée à double tranchant. S'il est utilisé correctement, il peut être très utile, mais s'il n'est pas utilisé correctement, blâmez-vous.



Si vous comptez le nombre de pages dans la documentation GCP, vous pouvez publier plusieurs volumes épais. Il faut beaucoup de temps et une compréhension approfondie du fonctionnement des services cloud pour tout comprendre, y compris la facturation et l'utilisation des fonctions. Sans surprise, il embauche des salariés individuels à temps plein pour cela!



Firebase et Cloud Run sont vraiment puissants



À son apogée, Firebase gère environ un milliard de lectures par minute. C'est un outil extrêmement puissant. Nous jouons avec Firebase depuis deux ou trois mois maintenant - et nous découvrons toujours de nouveaux aspects, mais jusque-là je n'avais aucune idée de la puissance de ce système.



Il en va de même pour Cloud Run! Si vous définissez le nombre de processus parallèles sur 60, max_containers == 1000, alors avec des requêtes de 400 ms, Cloud Run peut traiter 9 millions de requêtes par minute!



60 * 1000 * 2,5 * 60 = 9 000 000 requêtes par minute


En comparaison, la recherche Google traite 3,8 millions de requêtes par minute.



Utiliser la surveillance



Bien que Google Cloud Monitoring n'arrête pas la facturation, il envoie des alertes en temps opportun (délai de 3 à 4 minutes). Il n'est pas facile de maîtriser la terminologie de Google Cloud au début, mais si vous prenez le temps, le tableau de bord, les alertes et les métriques vous faciliteront un peu la vie.



Ces statistiques ne sont disponibles que pendant 90 jours, elles n'ont pas été enregistrées avec nous.



Nous avons survécu





Fuh, emporté



Après avoir examiné notre long rapport d'incident décrivant la situation de notre côté, après diverses consultations, conversations et discussions internes, Google nous a pardonné la dépense!



Merci Google!



Nous avons saisi une bouée de sauvetage et avons profité de cette occasion pour terminer le développement du produit. Cette fois, avec une planification, une architecture et une mise en œuvre beaucoup plus sûres.



Google, mon entreprise technologique préférée, n'est pas seulement une entreprise formidable avec laquelle travailler. C'est aussi une excellente entreprise avec qui travailler. Google Tools est très convivial pour les développeurs, dispose d'une excellente documentation (pour la plupart) et est en constante évolution.


(Remarque: ceci est mon opinion personnelle en tant que développeur individuel. Notre société n'est en aucun cas sponsorisée ou affiliée à Google).



Et après?



Après cet incident, nous avons passé plusieurs mois à étudier le cloud et notre architecture. En quelques semaines, ma compréhension s'était tellement améliorée que je pouvais estimer le coût du scraping "tout Internet" avec Cloud Run avec un algorithme amélioré.



L'incident m'a obligé à analyser en profondeur l'architecture de notre produit, et nous avons abandonné celle de la première version pour construire une infrastructure évolutive.



Dans la deuxième version d'Announce, nous avons non seulement créé un MVP, nous avons également créé une plate-forme sur laquelle nous pouvions développer de nouveaux produits par itérations rapides et les tester en profondeur dans un environnement sécurisé.



Ce voyage a longtemps ... Annoncerlancé fin novembre, environ sept mois après la première version, mais il est hautement évolutif, tire le meilleur parti du cloud et est hautement optimisé.



Nous avons également lancé sur toutes les plateformes, pas seulement sur Internet.



De plus, nous avons réutilisé la plateforme pour créer notre deuxième produit, Point Address . Il présente également une évolutivité et une bonne architecture.



All Articles