Cómo quemamos accidentalmente $ 72,000 en dos horas en Google Cloud Platform y casi nos declaramos en bancarrota





La historia de cómo nos encontramos al borde de la bancarrota, sin siquiera tener tiempo para lanzar el primer producto, cómo logramos sobrevivir y qué lecciones aprendimos.



En marzo de 2020, cuando COVID llegó al mundo, nuestra startup Milkie Way también se vio muy afectada y estuvo a punto de cerrar. Quemamos $ 72,000 mientras investigábamos y probamos internamente Cloud Run con Firebase durante varias horas.



Comencé a desarrollar el servicio Announce en noviembre de 2019. El objetivo principal era lanzar la primera versión funcional mínima del producto, por lo que el código funcionaba en una pila simple. Usamos JS, Python e implementamos nuestro producto en Google App Engine.



Con un equipo muy pequeño, nos centramos en la codificación, el desarrollo de la interfaz de usuario y la preparación de productos. Casi no dediqué tiempo a administrar la nube, solo dediqué lo suficiente para poner el sistema en funcionamiento y proporcionar un proceso de desarrollo básico (CI / CD).





Anuncio de escritorio



La primera versión no fue muy conveniente, pero solo queríamos lanzar una versión para experimentos y luego trabajar en la normal. Debido a COVID, pensamos que este es un buen momento para lanzar, ya que las agencias gubernamentales de todo el mundo pueden usar Announce para publicar alertas.



¿No es genial generar algunos datos en la plataforma cuando los usuarios aún no han subido su contenido? Este pensamiento llevó a otro proyecto, Announce-AI, para la generación de contenido. Los datos son ricos en varios eventos, como alertas de terremotos y posiblemente noticias locales relevantes.



Algunos detalles técnicos



Usamos Cloud Functions para comenzar a desarrollar Announce-AI. Dado que nuestro robot de raspado todavía estaba en su infancia, decidimos aprovechar estas funciones ligeras. Pero hubo problemas con el escalado porque las funciones en la nube tienen un tiempo de espera de aproximadamente 9 minutos.



¡Y de repente nos enteramos del sistema Cloud Run, que luego tenía un gran límite de uso gratuito! Sin entenderlo completamente, le pedí al equipo que implementara la función de "prueba" Announce-AI en Cloud Run y ​​evaluara su desempeño. El objetivo era jugar con Cloud Run para ganar experiencia.





Ejecución de la nube de Google



Como tenemos un sitio muy pequeño, usamos una base de datos Firebase por simplicidad, ya que Cloud Run no tiene almacenamiento y la implementación de SQL Server u otra base de datos es demasiado excesiva para la prueba.



Creé un nuevo proyecto de desarrollo GCP ANC-AI, configuré mi presupuesto de facturación en la nube en $ 7, guardé mi proyecto de Firebase con un plan gratuito (Spark). La peor opción que hemos imaginado es superar el límite diario de Firebase.



Después de algunas modificaciones, preparamos el código, hicimos algunas solicitudes manuales y luego lo dejamos en ejecución.



Comienza la pesadilla



El día de las pruebas, todo salió bien y volvimos al desarrollo de Announce. Al día siguiente, después del trabajo, a última hora de la tarde, fui a dormir una siesta. Cuando me desperté, vi varios correos electrónicos de Google Cloud, todos a intervalos de varios minutos.



Primer correo electrónico: actualización automática de nuestro proyecto de Firebase





Segundo correo electrónico: por encima del presupuesto





Afortunadamente, mi tarjeta tiene un límite de $ 100. Debido a esto, los pagos no se realizaron y Google suspendió el servicio de nuestras cuentas.



Tercera letra: tarjeta rechazada





Salté de la cama, ingresé a la facturación de Google Cloud y vi una factura de aproximadamente $ 5,000. Presa del pánico, comenzó a hacer clic en las teclas, sin comprender lo que estaba sucediendo. En el fondo, comencé a reflexionar sobre cómo pudo haber sucedido esto y cómo pagar la factura de $ 5000, en cuyo caso.



El problema era que la puntuación seguía creciendo cada minuto.



En cinco minutos mostró $ 15.000, en 20 minutos - $ 25.000 No entendí cuándo dejarían de aumentar los números. ¿Quizás crecerán indefinidamente?



Dos horas después, la cifra se detuvo en poco menos de $ 72 000.



Para entonces, el equipo y yo estábamos en una teleconferencia, estaba completamente sorprendido y no tenía ni idea de qué hacer a continuación. Apagamos la facturación, cerramos todos los servicios.



Como en todos los proyectos de GCP nos liquidamos con una tarjeta, todas nuestras cuentas y proyectos fueron suspendidos.



La pesadilla continua



Esto sucedió la noche del viernes 27 de marzo, tres días antes de que planeáramos lanzar la primera versión. Ahora el desarrollo se ha detenido porque Google ha suspendido todos nuestros proyectos vinculados a un mapa. Mi moral estaba por debajo del suelo y el futuro de la empresa parecía incierto.





Todos nuestros proyectos en la nube están en espera, el desarrollo se detiene.



Tan pronto como mi mente se resignó a la nueva realidad, a la medianoche decidí averiguar qué había sucedido normalmente. Empecé a escribir un documento con una investigación detallada del incidente ... y lo llamé "Capítulo 11" [este es un capítulo de la ley de quiebras - aprox. por.].



Dos colegas que participaron en el experimento también se quedaron despiertos toda la noche, investigando y tratando de entender qué sucedió.



A la mañana siguiente, sábado 28 de marzo, llamé y escribí cartas a una docena de bufetes de abogados para concertar una cita o hablar con un abogado. Todos estaban fuera, pero pude obtener una respuesta de uno de ellos por correo electrónico. Dado que los detalles del incidente son tan complejos, incluso para los ingenieros, explicar esto a un abogado en un inglés sencillo no fue fácil en sí mismo.



Para nosotros, como startup, no había forma de recuperar $ 72 000.



Para entonces, ya había estudiado a fondo los capítulos 7 y 11 de la ley de quiebras y me había preparado mentalmente para lo que podría suceder a continuación.



Un poco de respiro: lagunas de GCP



El sábado, después de enviar correos electrónicos a los abogados, comencé a leer y revisar cada página de la documentación de GCP. Cometimos errores, pero no tenía sentido que Google nos permitiera gastar $ 72,000 drásticamente si no hubiéramos hecho ningún pago antes.





GCP y Firebase



1. Actualización automática de una cuenta de Firebase a una cuenta de pago



No esperábamos esto, y esto no se advirtió en ninguna parte al registrarse en Firebase. Nuestra facturación de GCP se conectó a la ejecución de Cloud Run, pero Firebase se incluyó en un plan gratuito (Spark). Sin motivo aparente, GCP se actualizó a un plan pago y nos cobró la cantidad requerida.



Resulta que a este proceso lo llaman "integración profunda de Firebase y GCP".



2. No hay "límites" de facturación. Los presupuestos se retrasan al menos un día



La facturación de GCP se retrasa efectivamente al menos 24 horas. En la mayoría de los documentos, Google sugiere usar presupuestos y la función de apagado automático en la nube. Pero para cuando se activa la función de apagado o se envía una notificación al usuario, el daño ya está hecho.



Se tarda aproximadamente un día en sincronizar la facturación, por lo que notamos la factura al día siguiente.



3. ¡Google debería haberse llevado $ 100, no 72 mil!



Dado que hasta ahora no se han realizado pagos desde nuestra cuenta, GCP primero tuvo que cobrar una tarifa de $ 100 de acuerdo con la información de pago, y si no pagaba, detendría el servicio. Pero eso no sucedió. Descubrí la razón más tarde, ¡pero esto tampoco es culpa del usuario!



La primera factura para nosotros fue de $ 5000. El siguiente es de $ 72K.





El límite de facturación para nuestra cuenta es de $ 100



4. ¡No confíe en su panel de Firebase!



No solo la facturación, sino también la actualización del panel de Firebase tomó más de 24 horas.



Según la documentación de Firebase Console, los números en el panel pueden diferir "levemente" de los informes de facturación.



En nuestro caso, difirieron en 86.585.365,85%, o 86 millones de puntos porcentuales. Incluso cuando llegó la factura, Firebase Console seguía mostrando 42,000 lecturas y escrituras por mes (por debajo del límite diario).



Nuevo día, nuevo desafío



Después de seis años y medio en Google y escribir docenas de documentos de proyectos, informes de investigación y más, comencé a escribir un documento para Google, describiendo el incidente y agregando lagunas de Google al informe. El equipo de Google volverá a trabajar en dos días.



Corrección: algunos lectores han sugerido que estaba usando mis contactos internos de Google. De hecho, no me comuniqué con nadie y elegí el camino que seguiría cualquier desarrollador o empresa normal. Como cualquier otro desarrollador pequeño, pasé incontables horas charlando, consultando, redactando correos electrónicos largos e informando errores. En uno de los siguientes artículos sobre informes de incidentes, mostraré los documentos que envié a Google.





Last Day at Google



Además, era necesario comprender nuestros errores y desarrollar una estrategia de desarrollo de productos. No todos en el equipo sabían del incidente, pero estaba bastante claro que estábamos en un gran problema.



En Google, enfrenté millones de dólares en errores humanos, pero la cultura de Google salva a los empleados (excepto a los ingenieros que tienen que escribir informes largos más tarde). Esta vez no hubo Google. Están en juego nuestro pequeño capital y nuestro arduo trabajo.



El firme Himalaya nos dice ...



Esta fue la primera vez que recibí un golpe así. Esto podría cambiar el futuro de nuestra empresa y mi vida. Este incidente me enseñó varias lecciones de negocios, incluida la más importante: recibir un golpe.



En ese momento, tenía un equipo de siete ingenieros y aprendices, y Google tardó unos diez días en respondernos sobre este incidente. Mientras tanto, teníamos que reanudar el desarrollo, encontrar una forma de evitar la suspensión de cuentas. A pesar de todo, tuvimos que centrarnos en las características y nuestro producto.





Poema "Los incondicionales del Himalaya nos dicen"



Por alguna razón, un poema de mi infancia giraba constantemente en mi cabeza. Era mi libro favorito, y lo recordaba palabra por palabra, aunque la última vez que lo leí hace más de 15 años.



¿Qué hemos hecho realmente?



Como equipo muy pequeño, queríamos evitar gastar en hardware durante el mayor tiempo posible. El problema de Cloud Functions y Cloud Run era el tiempo de espera.



Una instancia extraerá continuamente las URL de la página. Pero después de 9 minutos, habrá un tiempo de espera.



Luego, habiendo discutido casualmente el problema, anoté el código en bruto en la pizarra en un par de minutos. Ahora me di cuenta de que ese código tenía muchas fallas arquitectónicas, pero luego nuestro objetivo era ciclos rápidos de corrección de errores para aprender y probar cosas nuevas rápidamente.





Anuncia el concepto de IA en Cloud Run



Para superar la limitación de tiempo de espera, sugerí usar solicitudes POST (con una URL como datos) para enviar trabajos a una instancia y lanzar varias instancias en paralelo, en lugar de hacer cola para una. Dado que cada instancia en Cloud Run solo eliminará una página, nunca habrá un tiempo de espera, todas las páginas se procesarán en paralelo (buen escalado) y el proceso está altamente optimizado ya que Cloud Run se consume con precisión de milisegundos.





Cloud Run Scraper



Si observa de cerca, al proceso le faltan algunos detalles importantes.



  1. Se produce una recursividad exponencial continua: las instancias no saben cuándo detenerse porque no hay una declaración de interrupción.

  2. Las solicitudes POST pueden tener la misma URL. Si hay un enlace a la página anterior, entonces el servicio de Cloud Run se atascará en una recursividad infinita, pero lo peor de todo, esta recursividad se multiplica exponencialmente (¡la cantidad máxima de instancias se estableció en 1000!)


Como puede imaginar, esto ha dado lugar a una situación en la que 1000 instancias realizan solicitudes y escriben en Firebase DB cada pocos milisegundos. ¡Vimos que había alrededor de mil millones de solicitudes por minuto pasando por las lecturas de Firebase en un momento!





Resumen de transacciones de fin de mes de GCP



116 mil millones de lecturas y 33 millones de escrituras



La versión experimental de nuestra aplicación en Cloud Run realizó 116 mil millones de lecturas y 33 millones de escrituras en Firestore. Oh!



Costos de lectura de Firebase:



$ (0.06 / 100,000) * 116,000,000,000 = $ 69,600


16.000 horas de Cloud Run



Después de probar, de detener los registros, llegamos a la conclusión de que la solicitud murió, pero de hecho pasó a un proceso en segundo plano. Como no desinstalamos los servicios (estábamos usando Cloud Run por primera vez y realmente no lo entendíamos entonces), varios servicios continuaron funcionando lentamente.



En 24 horas, todos estos servicios en 1.000 instancias se ejecutaron durante un total de 16.022 horas.



Todos nuestros errores



Implementar el algoritmo erróneo en la nube



Ya se ha discutido anteriormente. Encontramos una nueva forma de usar solicitudes POST sin servidor que no encontré en ningún lugar de Internet, pero la implementamos sin especificar el algoritmo.



Implementar Cloud Run con parámetros predeterminados



Cuando creamos el servicio Cloud Run, elegimos los valores predeterminados para él. El número máximo de instancias es 1000 y la simultaneidad es 80 solicitudes. No sabíamos que estos valores son en realidad el peor de los casos para el programa de prueba.



Si elegimos instancias máximas = 2, los costos serían 500 veces menores.



Si establecemos la concurrencia = 1, ni siquiera notaríamos la puntuación.



Usar Firebase sin comprenderlo completamente



Solo entiendes algo por experiencia. Firebase no es un idioma para aprender, es una plataforma de contenedores. Sus reglas las determina una empresa de Google específica.







Además, al escribir código Node.js, debe pensar en los procesos en segundo plano. Si el código pasa a procesos en segundo plano, no es fácil para el desarrollador saber que el servicio se está ejecutando. Como supimos más tarde, esto también provocó la mayoría de los tiempos de espera para nuestras funciones en la nube.



Los errores rápidos y las soluciones rápidas son una mala idea en la nube



La nube en su conjunto es como una espada de doble filo. Si se usa correctamente, puede ser muy útil, pero si se usa incorrectamente, échese la culpa.



Si cuenta la cantidad de páginas en la documentación de GCP, puede publicar varios volúmenes gruesos. Se necesita mucho tiempo y una comprensión profunda de cómo funcionan los servicios en la nube para comprender todo, incluida la facturación y el uso de funciones. Como era de esperar, ¡contrata empleados individuales a tiempo completo para esto!



Firebase y Cloud Run son realmente poderosos



En su punto máximo, Firebase maneja alrededor de mil millones de lecturas por minuto. Esta es una herramienta extremadamente poderosa. Hemos estado jugando con Firebase durante dos o tres meses y seguimos descubriendo nuevos aspectos, pero hasta entonces no tenía idea de lo poderoso que es este sistema.



¡Lo mismo ocurre con Cloud Run! Si establece la cantidad de procesos paralelos en 60, max_containers == 1000, entonces, con solicitudes de 400 ms, Cloud Run puede procesar 9 millones de solicitudes por minuto.



60 * 1000 * 2.5 * 60 = 9,000,000 solicitudes por minuto


En comparación, la búsqueda de Google procesa 3,8 millones de consultas por minuto.



Monitoreo de uso



Aunque Google Cloud Monitoring no detendrá la facturación, envía alertas oportunas (demora de 3 a 4 minutos). No es fácil dominar la terminología de Google Cloud al principio, pero si se toma el tiempo, el panel, las alertas y las métricas le facilitarán un poco la vida.



Estas métricas están disponibles solo durante 90 días, no se han guardado con nosotros.



Sobrevivimos





Fuh, se dejó llevar



Después de examinar nuestro largo informe de incidentes que describe la situación por nuestra parte, después de varias consultas, conversaciones y discusiones internas, ¡Google nos perdonó el gasto!



¡Gracias Google!



Agarramos un salvavidas y aprovechamos esta oportunidad para completar el desarrollo del producto. Esta vez con mucha mejor planificación, arquitectura e implementación mucho más segura.



Google, mi empresa de tecnología favorita, no es solo una gran empresa con la que trabajar. También es una gran empresa para trabajar. Google Tools es muy amigable para los desarrolladores, tiene una excelente documentación (en su mayor parte) y está en constante evolución.


(Nota: esta es mi opinión personal como desarrollador individual. Nuestra empresa no está patrocinada ni afiliada a Google de ninguna manera).



¿Que sigue?



Después de este incidente, pasamos varios meses estudiando la nube y nuestra arquitectura. En unas pocas semanas, mi comprensión había mejorado tanto que podía estimar el costo de raspar "toda la Internet" con Cloud Run con un algoritmo mejorado.



El incidente me obligó a analizar en profundidad la arquitectura de nuestro producto y abandonamos la de la primera versión para construir una infraestructura escalable.



En la segunda versión de Announce, no solo creamos un MVP, creamos una plataforma en la que pudimos desarrollar nuevos productos en iteraciones rápidas y probarlos a fondo en un entorno seguro.



Este viaje tomó mucho tiempo ... Anunciarse lanzó a fines de noviembre, unos siete meses después de la primera versión, pero es muy escalable, toma lo mejor de la nube y está altamente optimizado.



También lanzamos en todas las plataformas, no solo en Internet.



Además, reutilizamos la plataforma para crear nuestro segundo producto, Point Address . También presenta escalabilidad y buena arquitectura.



All Articles