Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Здравейте, казвам се Евгений. Работя в инфраструктурата за търсене на Yandex.Market. Искам да разкажа на общността на Habr за вътрешната кухня на Market - и имам много да разкажа. На първо място, как работи търсенето на пазара, процеси и архитектура. Как да се справим с извънредни ситуации: какво се случва, ако един сървър падне? Ами ако има 100 такива сървъра?

Ще научите също как внедряваме нова функционалност на куп сървъри наведнъж. И как тестваме сложни услуги директно в производството, без да причиняваме неудобство на потребителите. Като цяло как работи търсенето на пазара, така че всички да си прекарат добре.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Малко за нас: какъв проблем решаваме

Когато въвеждате текст, търсите продукт по параметри или сравнявате цени в различни магазини, всички заявки се изпращат до услугата за търсене. Търсенето е най-голямата услуга на пазара.

Ние обработваме всички заявки за търсене: от сайтовете market.yandex.ru, beru.ru, услугата Supercheck, Yandex.Advisor, мобилни приложения. Ние също така включваме оферти за продукти в резултатите от търсенето на yandex.ru.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Под услуга за търсене разбирам не само самото търсене, но и база данни с всички оферти на пазара. Мащабът е следният: повече от милиард заявки за търсене се обработват на ден. И всичко трябва да работи бързо, без прекъсвания и винаги да дава желания резултат.

Какво е какво: Пазарна архитектура

Ще опиша накратко настоящата архитектура на пазара. Може грубо да се опише с диаграмата по-долу:
Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди
Да кажем, че партньорски магазин идва при нас. Казва, че искам да продам играчка: тази зла котка с пищялка. И още една ядосана котка без пищялка. И просто котка. След това магазинът трябва да подготви оферти, за които пазарът търси. Магазинът генерира специален xml с оферти и съобщава пътя до този xml чрез партньорския интерфейс. След това индексаторът периодично изтегля този xml, проверява за грешки и записва цялата информация в огромна база данни.

Има много такива запазени xml файлове. От тази база данни се създава индекс за търсене. Индексът се съхранява във вътрешен формат. След като създаде индекса, услугата Layout го качва на сървърите за търсене.

В резултат на това в базата данни се появява ядосана котка с пищялка и индексът на котката се появява на сървъра.

Ще ви кажа как търсим котка в частта за архитектурата на търсенето.

Архитектура за търсене на пазара

Живеем в свят на микроуслуги: всяка входяща заявка market.yandex.ru причинява много подзаявки и десетки услуги участват в тяхната обработка. Диаграмата показва само няколко:

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди
Опростена схема за обработка на заявки

Всяка услуга има прекрасно нещо - собствен балансьор с уникално име:

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Балансьорът ни дава по-голяма гъвкавост при управлението на услугата: можете например да изключите сървърите, което често се изисква за актуализации. Балансьорът вижда, че сървърът е недостъпен и автоматично пренасочва заявките към други сървъри или центрове за данни. При добавяне или премахване на сървър натоварването автоматично се преразпределя между сървърите.

Уникалното име на балансьора не зависи от центъра за данни. Когато услуга A отправи заявка към B, тогава по подразбиране балансьорът B пренасочва заявката към текущия център за данни. Ако услугата е недостъпна или не съществува в текущия център за данни, тогава заявката се пренасочва към други центрове за данни.

Едно FQDN за всички центрове за данни позволява на услуга A напълно да се абстрахира от местоположенията. Заявката му към услуга B винаги ще бъде обработена. Изключение прави случаят, когато услугата се намира във всички центрове за данни.

Но не всичко е толкова розово с този балансьор: имаме допълнителен междинен компонент. Балансиращият може да е нестабилен и този проблем се решава чрез излишни сървъри. Има и допълнително забавяне между услуги A и B. Но на практика то е по-малко от 1 ms и за повечето услуги това не е критично.

Справяне с неочакваното: Балансиране и устойчивост на услугата за търсене

Представете си, че има срив: трябва да намерите котка с пищялка, но сървърът се срива. Или 100 сървъра. Как да се измъкна? Наистина ли ще оставим потребителя без котка?

Ситуацията е страшна, но сме готови за нея. Ще ви разкажа по ред.

Инфраструктурата за търсене е разположена в няколко центъра за данни:

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

При проектирането включваме възможност за изключване на един център за данни. Животът е пълен с изненади - например багер може да пререже подземен кабел (да, това се случи). Капацитетът в останалите центрове за данни трябва да е достатъчен, за да издържи пиково натоварване.

Нека разгледаме единичен център за данни. Всеки център за данни има една и съща схема на работа на балансьора:

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди
Един балансьор е поне три физически сървъра. Това резервиране е направено за надеждност. Балансьорите работят на HAProx.

Избрахме HAProx поради неговата висока производителност, ниски изисквания за ресурси и широка функционалност. Нашият софтуер за търсене работи във всеки сървър.

Вероятността един сървър да се повреди е ниска. Но ако имате много сървъри, вероятността поне един да падне се увеличава.

Ето какво се случва в действителност: сървърите се сриват. Поради това е необходимо постоянно да се следи състоянието на всички сървъри. Ако сървърът спре да отговаря, той автоматично се изключва от трафика. За тази цел HAProxy има вградена проверка на здравето. Отива до всички сървъри веднъж в секунда с HTTP заявка „/ping“.

Друга функция на HAProxy: проверката на агента ви позволява да зареждате всички сървъри равномерно. За целта HAProxy се свързва с всички сървъри и те връщат теглото си в зависимост от текущото натоварване от 1 до 100. Теглото се изчислява въз основа на броя на заявките в опашката за обработка и натоварването на процесора.

Сега относно намирането на котката. Резултатите от търсенето са заявки като: /search?text=angry+cat. За да бъде търсенето бързо, целият индекс на котките трябва да се побере в RAM. Дори четенето от SSD не е достатъчно бързо.

Някога базата данни с оферти беше малка и RAM паметта на един сървър беше достатъчна за нея. Тъй като базата от предложения нарастваше, всичко вече не се побираше в тази RAM и данните бяха разделени на две части: сегмент 1 и сегмент 2.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди
Но това винаги се случва: всяко решение, дори и добро, поражда други проблеми.

Балансьорът все още отиде на всеки сървър. Но на машината, където дойде заявката, имаше само половината от индекса. Останалото беше на други сървъри. Следователно сървърът трябваше да отиде на някоя съседна машина. След получаване на данни от двата сървъра резултатите бяха комбинирани и прекласирани.

Тъй като балансьорът разпределя заявките равномерно, всички сървъри са били ангажирани с повторно класиране, а не само с изпращане на данни.

Проблемът е възникнал, ако съседен сървър е недостъпен. Решението беше да се посочат няколко сървъра с различни приоритети като „съседен“ сървър. Първо, заявката беше изпратена до сървърите в текущия шкаф. Ако нямаше отговор, заявката беше изпратена до всички сървъри в този център за данни. И накрая, заявката отиде до други центрове за данни.
С нарастването на броя на предложенията данните бяха разделени на четири части. Но това не беше границата.

В момента се използва конфигурация от осем шарда. Освен това, за да спести още повече памет, индексът беше разделен на част за търсене (която се използва за търсене) и част с фрагмент (която не участва в търсенето).

Един сървър съдържа информация само за един шард. Следователно, за да търсите в пълния индекс, трябва да търсите в осем сървъра, съдържащи различни сегменти.

Сървърите са групирани в клъстери. Всеки клъстер съдържа осем търсачки и един сървър за фрагменти.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди
Сървърът за фрагменти изпълнява база данни ключ-стойност със статични данни. Те са необходими за издаване на документи, например описание на котка с пищялка. Данните се прехвърлят специално на отделен сървър, за да не натоварват паметта на сървърите за търсене.

Тъй като идентификаторите на документи са уникални само в рамките на един индекс, може да възникне ситуация, при която във фрагментите няма документи. Е, или че за един ID ще има различно съдържание. Следователно, за да работи търсенето и да се върнат резултатите, имаше нужда от последователност в целия клъстер. По-долу ще ви кажа как следим последователността.

Самото търсене е структурирано по следния начин: заявка за търсене може да дойде до всеки от осемте сървъра. Да кажем, че е дошъл на сървър 1. Този сървър обработва всички аргументи и разбира какво и как да търси. В зависимост от входящата заявка, сървърът може да отправи допълнителни заявки към външни услуги за необходимата информация. Една заявка може да бъде последвана от до десет заявки към външни услуги.

След събиране на необходимата информация започва търсене в базата с оферти. За да направите това, се правят подзапитвания към всичките осем сървъра в клъстера.

След получаване на отговорите резултатите се комбинират. В крайна сметка може да са необходими още няколко подзаявки към сървъра за фрагменти, за да се генерират резултатите.

Заявките за търсене в клъстера изглеждат така: /shard1?text=angry+cat. В допълнение, подзаявките на формуляра се правят постоянно между всички сървъри в рамките на клъстера веднъж в секунда: /състояние.

разследване /състояние открива ситуация, при която сървърът не е достъпен.

Той също така контролира, че версията на търсачката и версията на индекса са еднакви на всички сървъри, в противен случай ще има непоследователни данни в клъстера.

Въпреки факта, че един сървър за фрагменти обработва заявки от осем търсачки, неговият процесор е много слабо натоварен. Ето защо сега прехвърляме данните от фрагмента към отделна услуга.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

За прехвърляне на данни въведохме универсални ключове за документи. Сега е невъзможно за ситуация, при която съдържание от друг документ се връща с помощта на един ключ.

Но преходът към друга архитектура все още не е завършен. Сега искаме да се отървем от специалния сървър за фрагменти. И след това се отдалечете напълно от клъстерната структура. Това ще ни позволи да продължим да мащабираме лесно. Допълнителен бонус е значителна икономия на желязо.

А сега към страшните истории с щастлив край. Нека разгледаме няколко случая на недостъпност на сървъра.

Случи се нещо ужасно: един сървър е недостъпен

Да приемем, че един сървър е недостъпен. Тогава останалите сървъри в клъстера могат да продължат да отговарят, но резултатите от търсенето ще бъдат непълни.

Чрез проверка на състоянието /състояние съседните сървъри разбират, че единият е недостъпен. Следователно, за да се поддържа пълнота, всички сървъри в клъстера на заявка /пинг те започват да отговарят на балансьора, че също са недостъпни. Оказва се, че всички сървъри в клъстера са умрели (което не е вярно). Това е основният недостатък на нашата клъстерна схема - затова искаме да се измъкнем от нея.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Заявките, които са неуспешни с грешка, се изпращат отново от балансиращия на други сървъри.
Балансиращият също спира да изпраща потребителски трафик към мъртви сървъри, но продължава да проверява техния статус.

Когато сървърът стане достъпен, той започва да отговаря /пинг. Веднага щом започнат да пристигат нормални отговори на ping от мъртви сървъри, балансьорите започват да изпращат потребителски трафик там. Работата на клъстера е възстановена, ура.

Още по-лошо: много сървъри са недостъпни

Значителна част от сървърите в центъра за данни са прекъснати. Какво да правя, къде да бягам? Балансьорът отново идва на помощ. Всеки балансьор постоянно съхранява в паметта текущия брой активни сървъри. Той постоянно изчислява максималното количество трафик, което текущият център за данни може да обработи.

Когато много сървъри в един център за данни се повредят, балансиращият осъзнава, че този център за данни не може да обработи целия трафик.

След това излишният трафик започва да се разпределя на случаен принцип към други центрове за данни. Всичко работи, всички са доволни.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Как го правим: публикуване на издания

Сега нека поговорим за това как публикуваме промените, направени в услугата. Тук поехме по пътя на опростяване на процесите: пускането на нова версия е почти напълно автоматизирано.
Когато в проекта се натрупат определен брой промени, автоматично се създава ново издание и започва изграждането му.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

След това услугата се пуска за тестване, където се проверява стабилността на работата.

В същото време се стартира автоматично тестване на производителността. С това се занимава специална служба. Сега няма да говоря за него - описанието му заслужава отделна статия.

Ако публикуването в тестване е успешно, публикуването на изданието в предварително стабилно стартира автоматично. Prestable е специален клъстер, към който се насочва нормален потребителски трафик. Ако върне грешка, балансьорът прави повторна заявка към производството.

В prestable времето за реакция се измерва и сравнява с предишното издание в производството. Ако всичко е наред, човек се свързва: проверява графиките и резултатите от тестовете за натоварване и след това започва да се разпространява в производството.

Всичко най-добро е за потребителя: A/B тестване

Не винаги е очевидно дали промените в дадена услуга ще донесат реални ползи. За да измерят полезността на промените, хората измислиха A/B тестване. Ще ви разкажа малко за това как работи в търсенето на Yandex.Market.

Всичко започва с добавянето на нов CGI параметър, който позволява нова функционалност. Нека нашият параметър е: market_new_functionality=1. След това в кода активираме тази функционалност, ако флагът присъства:

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

Нова функционалност се въвежда в производствената среда.

За автоматизиране на A/B тестването има специална услуга, която предоставя подробна информация описани тук. В услугата се създава експеримент. Делът на трафика е зададен например 15%. Процентите се задават не за заявки, а за потребители. Посочва се и продължителността на експеримента, например седмица.

Могат да се провеждат няколко експеримента едновременно. В настройките можете да посочите дали е възможно пресичане с други експерименти.

В резултат на това услугата автоматично добавя аргумент market_new_functionality=1 до 15% от потребителите. Освен това автоматично изчислява избраните показатели. След като експериментът приключи, анализаторите преглеждат резултатите и правят заключения. Въз основа на констатациите се взема решение за пускане в производство или усъвършенстване.

Сръчната ръка на пазара: тестване в производството

Често се случва да трябва да тествате работата на нова функционалност в производството, но не сте сигурни как ще се държи в „бойни“ условия при голямо натоварване.

Има решение: флаговете в CGI параметрите могат да се използват не само за A/B тестване, но и за тестване на нова функционалност.

Направихме инструмент, който ви позволява незабавно да промените конфигурацията на хиляди сървъри, без да излагате услугата на рискове. Нарича се Stop Tap. Първоначалната идея беше да можете бързо да деактивирате някои функции без оформление. След това инструментът се разшири и стана по-сложен.

Диаграмата на услугата е представена по-долу:

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Стойностите на флага се задават чрез API. Услугата за управление съхранява тези стойности в базата данни. Всички сървъри отиват в базата данни веднъж на всеки десет секунди, изпомпват стойности на флагове и прилагат тези стойности към всяка заявка.

В крана Stop можете да зададете два типа стойности:

1) Условни изрази. Прилага се, когато една от стойностите е вярна. Например:

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

Стойността "3" ще бъде приложена, когато заявката се обработва в местоположение DC1. И стойността е „4“, когато заявката се обработва на втория клъстер за сайта beru.ru.

2) Безусловни стойности. Прилага се по подразбиране, ако нито едно от условията не е изпълнено. Например:

стойност, стойност!

Ако дадена стойност завършва с удивителен знак, тя получава по-висок приоритет.

Анализаторът на CGI параметър анализира URL адреса. След това прилага стойностите от Stop Tap.

Прилагат се стойности със следните приоритети:

  1. С повишен приоритет от Stop Tap (удивителен знак).
  2. Стойност от заявка.
  3. Стойност по подразбиране от докосване Stop.
  4. Стойност по подразбиране в кода.

Има много флагове, които са посочени в условни стойности - те са достатъчни за всички известни сценарии:

  • Център за данни.
  • Околна среда: производство, тестване, сянка.
  • Място: пазар, beru.
  • Номер на клъстера.

С този инструмент можете да активирате нова функционалност на определена група сървъри (например само в един център за данни) и да тествате работата на тази функционалност без особен риск за цялата услуга. Дори ако сте направили сериозна грешка някъде, всичко е започнало да пада и целият център за данни е паднал, балансьорите ще пренасочат заявките към други центрове за данни. Крайните потребители няма да забележат нищо.

Ако забележите проблем, можете незабавно да върнете флага към предишната му стойност и промените ще бъдат отменени.

Тази услуга има и своите недостатъци: разработчиците я обичат много и често се опитват да прокарат всички промени в Stop Tap. Опитваме се да се борим със злоупотребата.

Подходът Stop Tap работи добре, когато вече имате стабилен код, готов за внедряване в производство. В същото време все още имате съмнения и искате да проверите кода в „бойни“ условия.

Stop Tap обаче не е подходящ за тестване по време на разработка. Има отделен клъстер за разработчици, наречен „сенчест клъстер“.

Тайно тестване: Shadow Cluster

Заявките от един от клъстерите се дублират към сенчестия клъстер. Но балансьорът напълно игнорира отговорите от този клъстер. Диаграмата на неговата работа е представена по-долу.

Как работи търсенето в Yandex.Market и какво се случва, ако един от сървърите се повреди

Получаваме тестов клъстер, който е в реални „бойни“ условия. Нормалният потребителски трафик отива там. Хардуерът и в двата клъстера е един и същ, така че производителността и грешките могат да се сравняват.

И тъй като балансьорът напълно игнорира отговорите, крайните потребители няма да видят отговорите от сенчестия клъстер. Следователно не е страшно да направите грешка.

Данни

И така, как изградихме търсенето на пазара?

За да направим всичко гладко, разделяме функционалността на отделни услуги. По този начин можем да мащабираме само онези компоненти, които са ни необходими, и да направим компонентите по-прости. Лесно е да присвоите отделен компонент на друг екип и да споделите отговорностите за работата по него. И значителните спестявания на желязо с този подход са очевиден плюс.

Сенчестият клъстер също ни помага: можем да разработваме услуги, да ги тестваме в процеса и да не безпокоим потребителя.

Е, тестване в производството, разбира се. Трябва да промените конфигурацията на хиляди сървъри? Лесно, използвайте Stop Tap. По този начин можете незабавно да пуснете готово комплексно решение и да се върнете към стабилна версия, ако възникнат проблеми.

Надявам се, че успях да покажа как правим пазара бърз и стабилен с непрекъснато нарастваща база от оферти. Как решаваме сървърни проблеми, справяме се с огромен брой заявки, подобряваме гъвкавостта на услугата и правим това, без да прекъсваме работните процеси.

Източник: www.habr.com

Добавяне на нов коментар