Como sobrevivimos ao aumento da carga de traballo x10 de xeito remoto e que conclusións sacamos

Ola Habr! Os últimos meses vivimos nunha situación moi interesante, e gustaríame compartir a nosa historia de escalado de infraestruturas. Durante este tempo, SberMarket cuadriplicou os pedidos e lanzou o servizo en 4 novas cidades. O crecemento explosivo da demanda de entrega de comestibles obrigounos a escalar a nosa infraestrutura. Le sobre as conclusións máis interesantes e útiles baixo o corte.

Como sobrevivimos ao aumento da carga de traballo x10 de xeito remoto e que conclusións sacamos

Chámome Dima Bobylev, son o director técnico de SberMarket. Como esta é a primeira publicación no noso blog, vou dicir algunhas palabras sobre min e sobre a empresa. O pasado outono, participei no concurso para mozos líderes de Runet. Para o concurso I escribiu unha pequena historia sobre como vemos en SberMarket a cultura interna e o enfoque do desenvolvemento do servizo. E aínda que non conseguín gañar o concurso, formulei por min mesmo os principios básicos para o desenvolvemento do ecosistema informático.

Ao xestionar un equipo, é importante comprender e atopar un equilibrio entre o que necesita a empresa e as necesidades de cada desenvolvedor individual. Agora SberMarket está a crecer 13 veces ao ano, e isto afecta ao produto, o que require un aumento constante no volume e no ritmo de desenvolvemento. A pesar diso, dedicamos tempo suficiente aos desenvolvedores para a análise preliminar e a codificación de alta calidade. O enfoque formado axuda non só á creación dun produto de traballo, senón tamén ao seu posterior escalado e desenvolvemento. Como resultado deste crecemento, SberMarket xa se converteu nun líder entre os servizos de entrega de comestibles: entregamos uns 18 pedidos ao día, aínda que había uns 3500 a principios de febreiro.

Como sobrevivimos ao aumento da carga de traballo x10 de xeito remoto e que conclusións sacamos
Un día, un cliente pediulle a un mensaxeiro de SberMarket que lle entregase os alimentos sen contacto, xusto no balcón.

Pero pasemos aos detalles específicos. Durante os últimos meses, estivemos a escalar activamente a infraestrutura da nosa empresa. Esta necesidade foi explicada por factores externos e internos. Simultaneamente coa expansión da base de clientes, o número de tendas conectadas pasou de 90 a principios de ano a máis de 200 a mediados de maio. Por suposto, preparámonos, reservamos a infraestrutura principal e contamos coa posibilidade de escalado vertical e horizontal de todas as máquinas virtuais aloxadas na nube de Yandex. Non obstante, a práctica demostrou: "Todo o que pode saír mal vai saír mal". E hoxe quero compartir as situacións máis curiosas que sucederon nestas semanas. Espero que a nosa experiencia vos sexa útil.

Escravo en plena preparación para o combate

Mesmo antes do inicio da pandemia, enfrontámonos a un aumento no número de solicitudes aos nosos servidores backend. A tendencia de pedir comida con entrega a domicilio comezou a cobrar forza e, coa introdución das primeiras medidas de autoillamento en relación co COVID-19, a carga medrou drasticamente ante os nosos ollos ao longo do día. Era necesario descargar rapidamente os servidores mestres da base de datos principal e transferir algunhas das solicitudes de lectura aos servidores de réplica (escravos).

Estabamos preparando este paso con antelación e xa estaban funcionando 2 servidores escravos para tal manobra. Traballaron principalmente en tarefas por lotes para xerar fontes de información para o intercambio de datos cos socios. Estes procesos crearon unha carga extra e, con razón, foron retirados dos corchetes un par de meses antes. 

Dado que a replicación tivo lugar no Slave, adherimos ao concepto de que as aplicacións só poden funcionar con elas en modo de só lectura. O Plan de recuperación ante desastres asumiu que, en caso de desastre, podíamos simplemente montar o escravo en lugar do mestre e cambiar todas as solicitudes de escritura e lectura ao escravo. Non obstante, tamén queriamos utilizar réplicas para as necesidades do departamento de análise, polo que os servidores non estaban completamente configurados para o estado de só lectura, e cada host tiña o seu propio conxunto de usuarios e algúns tiñan permisos de escritura para gardar os resultados do cálculo intermedio.

Ata un certo nivel de carga, tiñamos suficiente master para escribir e ler ao procesar as solicitudes http. A mediados de marzo, xusto cando Sbermarket decidiu cambiar completamente ao traballo remoto, comezamos a multiplicar o crecemento de RPS. Cada vez son máis os nosos clientes que se autoillaban ou traballaron desde casa, o que se reflectiu nos indicadores de carga.

A actuación do "mestre" xa non era suficiente, polo que comezamos a transferir algunhas das solicitudes de lectura máis pesadas á réplica. Para dirixir de forma transparente as solicitudes de escritura ao mestre e ler as solicitudes ao escravo, usamos a xoia de rubí "Polbo". Creamos un usuario especial con _readonly postfix sen permisos de escritura. Pero debido a un erro na configuración dun dos hosts, parte das solicitudes de escritura dirixíronse ao servidor escravo en nome dun usuario que tiña os dereitos adecuados.

O problema non se manifestou inmediatamente, porque. o aumento da carga aumentou o atraso dos escravos. A incoherencia dos datos foi descuberta pola mañá, cando, tras as importacións nocturnas, os escravos non "poñeron" o amo. Atribuímolo a unha alta carga no propio servizo e ás importacións asociadas ao lanzamento de novas tendas. Pero era inaceptable dar datos cunha demora de moitas horas, e cambiamos os procesos ao segundo escravo analítico, porque tiñaоRecursos máis grandes e non se cargaba con solicitudes de lectura (que é como nos explicamos a falta de atraso de replicación).

Cando descubrimos as razóns da "difusión" do escravo principal, o analítico xa fallara polo mesmo motivo. A pesar da presenza de dous servidores adicionais, aos que planeabamos transferir a carga en caso de falla principal, debido a un erro desafortunado, resultou que non había un nun momento crítico.

Pero como non só volcamos a base de datos (a restauración naquel momento era dunhas 5 horas), senón tamén unha instantánea do servidor mestre, conseguimos lanzar a réplica en 2 horas. É certo que despois diso, esperábase que tirasemos o rexistro de replicación durante moito tempo (porque o proceso está en modo de fío único, pero esa é unha historia completamente diferente).

Conclusión: Despois de tal incidente, quedou claro que a práctica de restrinxir as escrituras para os usuarios debería abandonarse e que todo o servidor debería declararse só de lectura. Con este enfoque, podes estar seguro de que as réplicas estarán dispoñibles nun momento crítico.

Optimizar incluso unha consulta pesada pode recuperar a base de datos

Aínda que actualizamos constantemente o catálogo no sitio, as solicitudes que fixemos aos servidores Slave permitiron un lixeiro atraso con respecto ao Master. O tempo durante o que descubrimos e eliminamos o problema dos escravos "desviados de súpeto" foi máis que a "barrera psicolóxica" (durante este tempo, os prezos podían actualizarse e os clientes verían datos obsoletos), e vímonos obrigados a cambiar. todas as consultas ao servidor de base de datos principal. Como resultado, o sitio foi lento... pero polo menos funcionou. E mentres o Slave se recuperaba, non nos quedaba máis que optimización. 

Mentres os servidores Slave se estaban recuperando, os minutos avanzaban lentamente, o Mestre permaneceu sobrecargado e esforzámonos en optimizar as tarefas activas segundo a Regra de Pareto: escollemos as consultas TOP que dan a maior parte da carga e comezamos a axustar. Isto fíxose sobre a marcha.

Un efecto interesante foi que MySQL, cargado ata os globos oculares, responde incluso a unha lixeira mellora nos procesos. A optimización dun par de consultas que deron só o 5% da carga total xa mostrou unha notable descarga da CPU. Como resultado, puidemos proporcionar unha reserva aceptable de recursos para que o Mestre traballe coa base de datos e obtivese o tempo necesario para restaurar as réplicas. 

Conclusión: Incluso unha pequena optimización permítelle "sobrevivir" á sobrecarga durante varias horas. Isto foi o suficiente para restaurar servidores con réplicas. Por certo, discutiremos o lado técnico da optimización de consultas nunha das seguintes publicacións. Así que subscríbete ao noso blog se che pode ser útil.

Organizar o seguimento da saúde dos servizos asociados

Procesamos pedidos dos clientes e, polo tanto, os nosos servizos interactúan constantemente con API de terceiros: estas son pasarelas para enviar SMS, plataformas de pago, sistemas de enrutamento, un xeocodificador, o Servizo Federal de Impostos e moitos outros sistemas. E cando a carga comezou a crecer rapidamente, comezamos a atoparnos coas limitacións da API dos servizos dos nosos socios, nas que nin sequera pensabamos antes.

A superación inesperada das cotas de servizos dos socios pode provocar o teu propio tempo de inactividade. Moitas API bloquean clientes que superan os límites e, nalgúns casos, un exceso de solicitudes pode sobrecargar a produción do socio. 

Por exemplo, no momento do crecemento do número de entregas, os servizos de acompañamento non podían facer fronte ás tarefas da súa distribución e determinación de rutas. Como resultado, resultou que os pedidos estaban feitos, pero o servizo que creou a ruta non funcionaba. Debo dicir que os nosos loxísticos fixeron o case imposible nestas condicións, e a clara interacción do equipo axudou a compensar os fallos temporais do servizo. Pero non é realista procesar tal volume de aplicacións manualmente todo o tempo, e despois dun tempo atopariamos unha brecha inaceptable entre as ordes e a súa execución. 

Tomáronse unha serie de medidas organizativas e o traballo ben coordinado do equipo axudou a gañar tempo mentres acordamos novas condicións e agardamos a modernización dos servizos dalgúns socios. Hai outras API que ofrecen altas taxas de resistencia e impíos en caso de tráfico elevado. Por exemplo, ao principio, utilizamos unha API de mapeo coñecida para determinar o enderezo do punto de entrega. Pero a finais de mes recibiron unha factura redonda por case 2 millóns de rublos. Despois diso, decidimos substituílo rapidamente. Non vou dedicarme á publicidade, pero direi que os nosos gastos diminuíron significativamente.
Como sobrevivimos ao aumento da carga de traballo x10 de xeito remoto e que conclusións sacamos

Conclusión: É imperativo vixiar as condicións de traballo de todos os servizos asociados e telos presentes. Aínda que hoxe pareza que están “con gran marxe” para vostede, isto non significa que mañá non se convertan nun obstáculo para o crecemento. E, por suposto, é mellor acordar con antelación as condicións financeiras do aumento das solicitudes do servizo. 

Ás veces resulta queNecesita máis ouro"(c) non axuda

Estamos acostumados a "gags" na base de datos principal ou nos servidores de aplicacións, pero ao escalar, poden aparecer problemas onde non se esperaban.Para a busca de texto completo no sitio, utilizamos o motor Apache Solr. A medida que aumentaba a carga, observamos unha diminución do tempo de resposta e a carga da CPU do servidor alcanzou o 100%. O que podería ser máis sinxelo: darlle máis recursos ao contedor Solr.

En lugar do aumento esperado do rendemento, o servidor simplemente "morreu". Cargouse inmediatamente ao 100% e respondeu aínda máis lentamente. Inicialmente, tiñamos 2 núcleos e 2 GB de RAM. Decidimos facer o que normalmente axuda: demos ao servidor 8 núcleos e 32 GB. Todo empeorou moito (dirémosche exactamente como e por que nunha publicación aparte). 

En poucos días, descubrimos as complejidades deste problema e conseguimos un rendemento óptimo con 8 núcleos e 32 GB. Esta configuración permítenos seguir aumentando a carga hoxe, o que é moi importante, porque o crecemento non é só en termos de clientes, senón tamén no número de tendas conectadas: en 2 meses o seu número duplicouse. 

Conclusión: Os métodos estándar como "engadir máis ferro" non sempre funcionan. Polo tanto, ao escalar calquera servizo, cómpre ter unha boa comprensión de como utiliza os recursos e probalo con antelación, o seu traballo en novas condicións. 

O estado sen estado é a clave para a escala horizontal sinxela

En xeral, o noso equipo adhírese a un enfoque ben coñecido: os servizos non deben ter un estado interno (sen estado) e deben ser independentes do ambiente de execución. Isto permitiunos sobrevivir ao aumento da carga mediante un simple escalado horizontal. Pero tivemos unha excepción de servizo: un controlador para tarefas longas en segundo plano. Participou no envío de correo electrónico e sms, procesamento de eventos, xeración de feeds, importación de prezos e stocks e procesamento de imaxes. Aconteceu que dependía do almacenamento de ficheiros local e estaba nunha única copia. 

Cando o número de tarefas na cola do procesador aumentou (e isto ocorreu naturalmente cun aumento do número de pedidos), o rendemento do servidor que hospedaba o procesador e o almacenamento de ficheiros converteuse nun factor limitante. Como resultado, detívose a actualización da gama e os prezos, o envío de notificacións aos usuarios e moitas outras funcións críticas atrapadas na cola. O equipo de Ops migrou rapidamente o almacenamento de ficheiros ao almacenamento de rede tipo S3, e isto permitiunos crear varias máquinas poderosas para escalar o manejador de tarefas en segundo plano.

Conclusión: A regra sen estado debe ser observada para todos os compoñentes sen excepción, aínda que pareza "que definitivamente non descansaremos aquí". É mellor dedicar un pouco de tempo á organización correcta do traballo de todos os sistemas que reescribir o código con présa e corrixir un servizo sobrecargado.

7 Principios para o crecemento intensivo

A pesar da dispoñibilidade de capacidade adicional, no proceso de crecemento, pisamos algúns anciños. Durante este tempo, o número de pedidos aumentou máis de 4 veces. Agora xa entregamos máis de 17 pedidos por día en 000 cidades e planeamos ampliar aínda máis a xeografía: no primeiro semestre de 62, espérase que o servizo se lance en toda Rusia. Para facer fronte á crecente carga de traballo, tendo en conta os baches xa cheos, derivamos por nós mesmos 2020 principios básicos para traballar nun ambiente de crecemento constante:

  1. Xestión de incidencias. Creamos un taboleiro en Jira, onde cada incidencia queda reflectida en forma de ticket. Isto axudarache a priorizar e completar as tarefas relacionadas cos incidentes. De feito, en esencia, non é terrible cometer erros - é terrible cometer erros dúas veces na mesma ocasión. Para aqueles casos nos que os incidentes se repiten antes de que se poida corrixir a causa, débense preparar instrucións de actuación, porque durante unha carga pesada é importante reaccionar á velocidade do raio.
  2. Seguimento necesario para todos os elementos de infraestrutura sen excepción. Foi grazas a el que puidemos predecir o crecemento da carga e escoller correctamente os "cocos de botella" para priorizar a eliminación. O máis probable é que, baixo unha carga elevada, todo o que nin sequera pensaches se rompa ou empece a diminuír. Por iso, o mellor é crear novas alertas inmediatamente despois da aparición das primeiras incidencias para vixialas e anticipalas.
  3. Alertas correctas só é necesario cun aumento brusco da carga. En primeiro lugar, deben informar exactamente o que está roto. En segundo lugar, non debería haber moitas alertas, porque a abundancia de alertas non críticas leva a ignorar todas as alertas en xeral.
  4. As solicitudes deben ser sen estado. Asegurámonos de que non debería haber excepcións a esta regra. Necesitas unha total independencia do ambiente de execución. Para iso, pode almacenar os datos compartidos nunha base de datos ou, por exemplo, directamente en S3. Mellor aínda, siga as regras. https://12factor.net. Durante un forte aumento do tempo, simplemente non hai forma de optimizar o código e terás que facer fronte á carga aumentando directamente os recursos informáticos e a escala horizontal.
  5. Cotas e prestación de servizos externos. Cun rápido crecemento, o problema pode xurdir non só na súa infraestrutura, senón tamén nun servizo externo. O máis molesto é cando isto ocorre non por un fallo, senón por chegar a cotas ou límites. Polo tanto, os servizos externos deberían escalar igual que vostede mesmo. 
  6. Procesos e filas separados. Isto axuda moito cando se produce un enchufe nunha das pasarelas. Non teriamos atopado atrasos na transmisión de datos se as colas completas para o envío de SMS non interferisen no intercambio de notificacións entre os sistemas de información. E sería máis doado aumentar o número de traballadores se traballasen por separado.
  7. realidades financeiras. Cando hai un crecemento explosivo nos fluxos de datos, non hai tempo para pensar en tarifas e subscricións. Pero hai que lembralos, especialmente se es unha empresa pequena. O propietario de calquera API, así como o teu provedor de hospedaxe, pode establecer unha factura grande. Entón, lea atentamente os contratos.

Conclusión

Non sen perdas, pero sobrevivimos a esta etapa, e hoxe intentamos unirnos a todos os principios atopados, e cada máquina ten a capacidade de aumentar facilmente o rendemento x4 para facer fronte a algunhas sorpresas. 

Nas seguintes publicacións, compartiremos a nosa experiencia de investigar a caída do rendemento en Apache Solr, así como falaremos sobre a optimización de consultas e como a interacción co Servizo Federal de Impostos axuda á empresa a aforrar diñeiro. Subscríbete ao noso blog para non perderte nada e cóntanos nos comentarios se tiveches problemas similares durante o crecemento do tráfico.

Como sobrevivimos ao aumento da carga de traballo x10 de xeito remoto e que conclusións sacamos

Só os usuarios rexistrados poden participar na enquisa. Rexístrate, por favor.

Algunha vez tivo unha desaceleración ou caída do servizo debido a un forte aumento da carga debido a:

  • 55,6%Incapacidade para engadir rapidamente recursos informáticos10

  • 16,7%Límites da infraestrutura do provedor de hospedaxe3

  • 33,3%Límites de API6 de terceiros

  • 27,8%As violacións dos principios dos apátridas as súas aplicacións5

  • 88,9%Código non óptimo de servizos propios16

Votaron 18 usuarios. 6 usuarios abstivéronse.

Fonte: www.habr.com

Engadir un comentario