Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Ola, chámome Evgeniy. Traballo na infraestrutura de busca Yandex.Market. Quero contarlle á comunidade Habr a cociña interior do Mercado, e teño moito que contar. En primeiro lugar, como funciona, procesos e arquitectura da busca de mercados. Como afrontamos as situacións de emerxencia: que pasa se un servidor cae? E se hai 100 servidores deste tipo?

Tamén aprenderás como implementamos novas funcionalidades nun grupo de servidores á vez. E como probamos servizos complexos directamente en produción, sen causar ningún inconveniente aos usuarios. En xeral, como funciona a Busca de mercados para que todos o pasen ben.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Un pouco de nós: que problema resolvemos

Cando introduce texto, busca un produto por parámetros ou compara prezos en diferentes tendas, todas as solicitudes envíanse ao servizo de busca. A busca é o maior servizo do mercado.

Procesamos todas as solicitudes de busca: desde os sitios market.yandex.ru, beru.ru, o servizo Supercheck, Yandex.Advisor, aplicacións móbiles. Tamén incluímos ofertas de produtos nos resultados de busca en yandex.ru.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Por servizo de busca refírome non só á procura en si, senón tamén a unha base de datos con todas as ofertas do Mercado. A escala é esta: trátanse máis de mil millóns de solicitudes de busca ao día. E todo debe funcionar rapidamente, sen interrupcións e sempre producir o resultado desexado.

Que é o que: Arquitectura de mercado

Describirei brevemente a arquitectura actual do Mercado. Pódese describir grosso modo no seguinte diagrama:
Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla
Digamos que vén a nós unha tenda asociada. Di que quero vender un xoguete: este gato malvado cun chirriador. E outro gato enfadado sen chirriar. E só un gato. A continuación, a tenda debe preparar ofertas para as que o Mercado busca. A tenda xera un xml especial con ofertas e comunica o camiño a este xml a través da interface de afiliados. A continuación, o indexador descarga periodicamente este xml, comproba se hai erros e garda toda a información nunha enorme base de datos.

Hai moitos xml gardados deste tipo. A partir desta base de datos créase un índice de busca. O índice gárdase en formato interno. Despois de crear o índice, o servizo Layout cárgao nos servidores de busca.

Como resultado, aparece un gato enfadado cun chirriador na base de datos e o índice do gato aparece no servidor.

Vouvos contar como buscamos un gato na parte sobre a arquitectura de busca.

Arquitectura de busca de mercado

Vivimos nun mundo de microservizos: cada solicitude entrante mercado.yandex.ru provoca moitas subconsultas e decenas de servizos están implicados no seu procesamento. O diagrama mostra só algúns:

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla
Esquema simplificado de tramitación de solicitudes

Cada servizo ten unha cousa marabillosa: o seu propio equilibrador cun nome único:

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

O equilibrador ofrécenos unha maior flexibilidade na xestión do servizo: podes, por exemplo, apagar os servidores, o que adoita ser necesario para as actualizacións. O equilibrador ve que o servidor non está dispoñible e redirixe automaticamente as solicitudes a outros servidores ou centros de datos. Ao engadir ou eliminar un servidor, a carga redistribuíuse automaticamente entre os servidores.

O nome único do equilibrador non depende do centro de datos. Cando o servizo A fai unha solicitude a B, o equilibrador B redirixe a solicitude por defecto ao centro de datos actual. Se o servizo non está dispoñible ou non existe no centro de datos actual, entón a solicitude redirixirase a outros centros de datos.

Un único FQDN para todos os centros de datos permite que o servizo A abstraia completamente das localizacións. A súa solicitude ao servizo B será sempre tramitada. A excepción é o caso cando o servizo está situado en todos os centros de datos.

Pero non todo é tan bo con este equilibrador: temos un compoñente intermedio adicional. O equilibrador pode ser inestable e este problema é resolto por servidores redundantes. Tamén hai un atraso adicional entre os servizos A e B. Pero na práctica é inferior a 1 ms e para a maioría dos servizos isto non é crítico.

Xestionar o inesperado: equilibrio e resistencia do servizo de busca

Imaxina que hai un colapso: tes que atopar un gato cun chirriador, pero o servidor falla. Ou 100 servidores. Como saír? De verdade imos deixar ao usuario sen gato?

A situación dá medo, pero estamos preparados para iso. Dígocho por orde.

A infraestrutura de busca está situada en varios centros de datos:

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Ao deseñar, incluímos a posibilidade de pechar un centro de datos. A vida está chea de sorpresas: por exemplo, unha escavadora pode cortar un cable subterráneo (si, iso pasou). A capacidade dos centros de datos restantes debería ser suficiente para soportar a carga máxima.

Consideremos un único centro de datos. Cada centro de datos ten o mesmo esquema de operación do equilibrador:

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla
Un equilibrador é polo menos tres servidores físicos. Esta redundancia está feita para a fiabilidade. Os equilibradores funcionan con HAProx.

Escollemos HAProx polo seu alto rendemento, baixos requisitos de recursos e ampla funcionalidade. O noso software de busca execútase dentro de cada servidor.

A probabilidade de que un servidor falle é baixa. Pero se tes moitos servidores, aumenta a probabilidade de que polo menos un caia.

Isto é o que ocorre na realidade: os servidores fallan. Polo tanto, é necesario supervisar constantemente o estado de todos os servidores. Se o servidor deixa de responder, desconectarase automaticamente do tráfico. Para este fin, HAProxy ten un control de saúde integrado. Vai a todos os servidores unha vez por segundo cunha solicitude HTTP "/ping".

Outra característica de HAProxy: agent-check permítelle cargar todos os servidores de forma uniforme. Para iso, HAProxy conéctase a todos os servidores, e devolven o seu peso dependendo da carga actual de 1 a 100. O peso calcúlase en función do número de solicitudes na cola para procesar e da carga do procesador.

Agora sobre atopar o gato. A busca resulta en solicitudes como: /search?text=angry+cat. Para que a busca sexa rápida, todo o índice do gato debe caber na memoria RAM. Incluso a lectura do SSD non é o suficientemente rápida.

Érase unha vez, a base de datos de ofertas era pequena e a memoria RAM dun servidor era suficiente para iso. A medida que creceu a base de ofertas, xa non cabe todo nesta memoria RAM e os datos dividíronse en dúas partes: fragmento 1 e fragmento 2.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla
Pero isto pasa sempre: calquera solución, aínda que sexa boa, dá lugar a outros problemas.

O equilibrador aínda foi a calquera servidor. Pero na máquina onde chegou a solicitude, só había a metade do índice. O resto foi noutros servidores. Polo tanto, o servidor tivo que ir a algunha máquina veciña. Despois de recibir datos de ambos os servidores, os resultados combináronse e clasificáronse de novo.

Dado que o equilibrador distribúe as solicitudes de forma uniforme, todos os servidores dedicáronse a volver a clasificar e non só a enviar datos.

O problema ocorreu se un servidor veciño non estaba dispoñible. A solución foi especificar varios servidores con diferentes prioridades como servidor "veciño". En primeiro lugar, a solicitude enviouse aos servidores do rack actual. Se non houbo resposta, a solicitude enviouse a todos os servidores deste centro de datos. E por último, a solicitude foi a outros centros de datos.
A medida que creceu o número de propostas, os datos foron divididos en catro partes. Pero este non era o límite.

Actualmente, úsase unha configuración de oito fragmentos. Ademais, para aforrar aínda máis memoria, o índice dividiuse nunha parte de busca (que se utiliza para buscar) e unha parte de fragmentos (que non participa na busca).

Un servidor contén información só para un fragmento. Polo tanto, para buscar no índice completo, cómpre buscar en oito servidores que conteñan fragmentos diferentes.

Os servidores agrúpanse en clústeres. Cada clúster contén oito motores de busca e un servidor de fragmentos.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla
O servidor de fragmentos executa unha base de datos de clave-valor con datos estáticos. Son necesarios para emitir documentos, por exemplo, a descrición dun gato cun chirriador. Os datos transfírense especialmente a un servidor separado para non cargar a memoria dos servidores de busca.

Dado que os ID de documentos son únicos dentro dun índice, podería darse unha situación na que non haxa documentos nos fragmentos. Ben, ou que para un ID haberá contido diferente. Polo tanto, para que a busca funcionase e os resultados fosen devoltos, existía unha necesidade de coherencia en todo o clúster. Vouche dicir a continuación como supervisamos a coherencia.

A busca en si estrutúrase do seguinte xeito: unha solicitude de busca pode chegar a calquera dos oito servidores. Digamos que chegou ao servidor 1. Este servidor procesa todos os argumentos e comprende que e como buscar. Dependendo da solicitude entrante, o servidor pode facer solicitudes adicionais a servizos externos para obter a información necesaria. Unha solicitude pode ir seguida de ata dez solicitudes a servizos externos.

Despois de recoller a información necesaria, comeza unha busca na base de datos de ofertas. Para iso, realízanse subconsultas aos oito servidores do clúster.

Unha vez recibidas as respostas, combínanse os resultados. Ao final, poden ser necesarias varias subconsultas ao servidor de fragmentos para xerar os resultados.

As consultas de busca dentro do clúster parecen: /shard1?text=angry+cat. Ademais, as subconsultas do formulario realízanse constantemente entre todos os servidores do clúster unha vez por segundo: /estado.

Solicitude /estado detecta unha situación na que o servidor non está dispoñible.

Tamén controla que a versión do motor de busca e a versión do índice sexan iguais en todos os servidores, se non, haberá datos inconsistentes dentro do clúster.

A pesar de que un servidor de fragmentos procesa solicitudes de oito buscadores, o seu procesador está moi cargado. Polo tanto, agora estamos a transferir os datos do fragmento a un servizo separado.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Para transferir datos, introducimos claves universais para documentos. Agora é imposible para unha situación na que o contido doutro documento é devolto usando unha chave.

Pero a transición a outra arquitectura aínda non está completa. Agora queremos desfacernos do servidor de fragmentos dedicado. E despois afástase por completo da estrutura do cluster. Isto permitiranos seguir escalando facilmente. Unha bonificación adicional é un importante aforro de ferro.

E agora a historias de medo con final feliz. Consideremos varios casos de indisponibilidade do servidor.

Ocorreu algo terrible: un servidor non está dispoñible

Digamos que un servidor non está dispoñible. Entón, os servidores restantes do clúster poden seguir respondendo, pero os resultados da busca estarán incompletos.

A través da comprobación de estado /estado os servidores veciños entenden que un non está dispoñible. Polo tanto, para manter a integridade, todos os servidores do clúster por solicitude /ping comezan a responder ao equilibrador que tampouco están dispoñibles. Resulta que todos os servidores do clúster morreron (o que non é certo). Este é o principal inconveniente do noso esquema de clúster; por iso queremos fuxir del.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

As solicitudes que fallan cun erro son enviadas de novo polo equilibrador a outros servidores.
O equilibrador tamén deixa de enviar tráfico de usuarios aos servidores mortos, pero segue comprobando o seu estado.

Cando o servidor está dispoñible, comeza a responder /ping. En canto comezan a chegar as respostas normais aos pings dos servidores mortos, os equilibradores comezan a enviar tráfico de usuarios alí. O funcionamento do clúster restableceuse.

Aínda peor: moitos servidores non están dispoñibles

Unha parte importante dos servidores do centro de datos están cortados. Que facer, onde correr? O equilibrador volve ao rescate. Cada equilibrador almacena constantemente na memoria o número actual de servidores activos. Calcula constantemente a cantidade máxima de tráfico que pode procesar o centro de datos actual.

Cando moitos servidores dun centro de datos caen, o equilibrador dáse conta de que este centro de datos non pode procesar todo o tráfico.

A continuación, o exceso de tráfico comeza a ser distribuído aleatoriamente a outros centros de datos. Todo funciona, todos son felices.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Como o facemos: publicación de lanzamentos

Agora imos falar de como publicamos os cambios realizados no servizo. Aquí tomamos o camiño da simplificación dos procesos: o lanzamento dunha nova versión está case completamente automatizado.
Cando se acumulan un certo número de cambios no proxecto, créase automaticamente unha nova versión e comeza a súa compilación.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

A continuación, o servizo lánzase a proba, onde se comproba a estabilidade do funcionamento.

Ao mesmo tempo, lánzase a proba automática de rendemento. Isto é xestionado por un servizo especial. Non vou falar sobre iso agora - a súa descrición é digna dun artigo separado.

Se a publicación en probas ten éxito, a publicación da versión en prestable iníciase automaticamente. Prestable é un clúster especial onde se dirixe o tráfico normal de usuarios. Se devolve un erro, o equilibrador fai unha nova solicitude á produción.

En prestable, os tempos de resposta mídense e compáranse coa versión anterior en produción. Se todo está ben, entón unha persoa conéctase: comproba os gráficos e os resultados das probas de carga e despois comeza a lanzarse á produción.

Todo o mellor vai para o usuario: probas A/B

Non sempre é obvio se os cambios nun servizo traerán beneficios reais. Para medir a utilidade dos cambios, a xente inventou probas A/B. Vouche contar un pouco sobre como funciona en Yandex.Market search.

Todo comeza coa adición dun novo parámetro CGI que permite novas funcionalidades. Sexa o noso parámetro: market_new_functionality=1. Despois, no código activamos esta funcionalidade se a bandeira está presente:

If (cgi.experiments.market_new_functionality) {
// enable new functionality
}

A nova funcionalidade está a ser implementada na produción.

Para automatizar as probas A/B, hai un servizo dedicado que ofrece información detallada descrito aquí. Créase un experimento no servizo. A cota de tráfico establécese, por exemplo, nun 15%. As porcentaxes non se establecen para consultas, senón para usuarios. Tamén se indica a duración do experimento, por exemplo, unha semana.

Pódense realizar varios experimentos á vez. Na configuración podes especificar se é posible a intersección con outros experimentos.

Como resultado, o servizo engade automaticamente un argumento market_new_functionality=1 ao 15% dos usuarios. Tamén calcula automaticamente as métricas seleccionadas. Despois de completar o experimento, os analistas miran os resultados e sacan conclusións. En función dos descubrimentos, tómase a decisión de implementar a produción ou o perfeccionamento.

Man hábil do mercado: probas en produción

Moitas veces ocorre que cómpre probar o funcionamento dunha nova funcionalidade en produción, pero non está seguro de como se comportará en condicións de "combate" baixo carga pesada.

Hai unha solución: as bandeiras dos parámetros CGI pódense usar non só para probas A/B, senón tamén para probar novas funcionalidades.

Creamos unha ferramenta que che permite cambiar instantáneamente a configuración en miles de servidores sen expor o servizo a riscos. Chámase Stop Tap. A idea orixinal era poder desactivar rapidamente algunhas funcións sen un deseño. Entón a ferramenta expandiuse e fíxose máis complexa.

O diagrama de fluxo do servizo preséntase a continuación:

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Os valores das marcas establécense a través da API. O servizo de xestión almacena estes valores na base de datos. Todos os servidores van á base de datos unha vez cada dez segundos, extraen os valores de marca e aplican estes valores a cada solicitude.

No toque Deter pode establecer dous tipos de valores:

1) Expresións condicionais. Aplícase cando un dos valores sexa verdadeiro. Por exemplo:

{
	"condition":"IS_DC1",
	"value":"3",
}, 
{
	"condition": "CLUSTER==2 and IS_BERU", 
	"value": "4!" 
}

O valor "3" aplicarase cando se procese a solicitude na localización DC1. E o valor é "4" cando a solicitude se procesa no segundo clúster para o sitio beru.ru.

2) Valores incondicionais. Aplícase por defecto se non se cumpre ningunha das condicións. Por exemplo:

valor, valor!

Se un valor remata cun signo de exclamación, dáselle maior prioridade.

O analizador de parámetros CGI analiza o URL. A continuación, aplícase os valores desde Stop Tap.

Aplícanse os valores coas seguintes prioridades:

  1. Con maior prioridade desde Stop Tap (signo de admiración).
  2. O valor da solicitude.
  3. Valor predeterminado de Deter toque.
  4. Valor predeterminado no código.

Hai moitas bandeiras que se indican en valores condicionais - son suficientes para todos os escenarios que coñecemos:

  • Centro de datos.
  • Ambiente: produción, probas, sombra.
  • Lugar: mercado, beru.
  • Número de clúster.

Con esta ferramenta, pode habilitar novas funcionalidades nun determinado grupo de servidores (por exemplo, nun só centro de datos) e probar o funcionamento desta funcionalidade sen ningún risco particular para todo o servizo. Aínda que cometeches un erro grave nalgún lugar, todo comezou a caer e todo o centro de datos caeu, os equilibradores redirixirán as solicitudes a outros centros de datos. Os usuarios finais non notarán nada.

Se observas un problema, podes devolver inmediatamente a bandeira ao seu valor anterior e os cambios volveranse a modificar.

Este servizo tamén ten as súas desvantaxes: os desenvolvedores encántanlle moito e moitas veces intentan empurrar todos os cambios no Stop Tap. Estamos tentando combater o mal uso.

O enfoque Stop Tap funciona ben cando xa tes código estable listo para ser lanzado á produción. Ao mesmo tempo, aínda tes dúbidas e queres comprobar o código en condicións de "combate".

Non obstante, Stop Tap non é axeitado para probar durante o desenvolvemento. Hai un clúster separado para desenvolvedores chamado "clúster de sombra".

Proba secreta: Shadow Cluster

As solicitudes dun dos clústeres duplícanse no clúster de sombra. Pero o equilibrador ignora por completo as respostas deste clúster. O diagrama do seu funcionamento preséntase a continuación.

Como funciona a busca de Yandex.Market e que ocorre se un dos servidores falla

Obtemos un clúster de proba que está en condicións reais de "combate". O tráfico normal de usuarios vai alí. O hardware en ambos os grupos é o mesmo, polo que se poden comparar o rendemento e os erros.

E dado que o equilibrador ignora por completo as respostas, os usuarios finais non verán as respostas do clúster de sombra. Polo tanto, non dá medo cometer un erro.

Descubrimentos

Entón, como creamos a busca do mercado?

Para que todo saia ben, separamos a funcionalidade en servizos separados. Deste xeito, podemos escalar só aqueles compoñentes que necesitamos e simplificalos. É doado asignar un compoñente separado a outro equipo e compartir as responsabilidades de traballar nel. E un aforro significativo en ferro con este enfoque é unha vantaxe obvia.

O clúster de sombra tamén nos axuda: podemos desenvolver servizos, probalos no proceso e non molestar ao usuario.

Ben, probando en produción, claro. Necesitas cambiar a configuración en miles de servidores? Doado, usa Stop Tap. Deste xeito, pode lanzar inmediatamente unha solución complexa preparada e volver a unha versión estable se xurden problemas.

Espero poder mostrar como facemos o mercado rápido e estable cunha base de ofertas cada vez maior. Como resolvemos problemas do servidor, tratamos un gran número de solicitudes, melloramos a flexibilidade do servizo e facemos isto sen interromper os procesos de traballo.

Fonte: www.habr.com

Engadir un comentario