Как укротихме терабайтите логове в ЦИАН

Как укротихме терабайтите логове в ЦИАН

Здравейте, казвам се Александър, работя като инженер в ЦИАН и се занимавам с системно администриране и автоматизация на инфраструктурни процеси. В коментарите под една от предишните статии ни помолиха да разкажем откъде получаваме 4 TB логове на ден и какво правим с тях. Да, имаме много логове и за тяхната обработка е създаден отделен инфраструктурен клъстер, който ни позволява бързо да решаваме проблеми. В тази статия ще разкажа как в течение на година адаптирахме клъстера за работа с непрекъснато нарастващ поток от данни.

С какво започнахме

Как укротихме терабайтите логове в ЦИАН

През последните няколко години натоварването на cian.ru нарастваше много бързо и към третото тримесечие на 2018 година посещаемостта на сайта достигна 11.2 милиона уникални потребители на месец. В този период в критични моменти губехме до 40% от логовете, което ни попречи да се справяме бързо с инцидентите и инвестирахме много време и усилия в решаването им. Освен това често не можехме да открием причината за проблема и той се повтаряше след известно време. Това беше ад, с който трябваше да се направи нещо.

По онова време за съхранение на логовете използвахме клъстер от 10 дата-нода с ElasticSearch версия 5.5.2 с типични настройки на индексите. Той беше внедрен преди повече от година като популярно и достъпно решение: тогава потокът от логове не беше толкова голям и нямаше смисъл да измисляме нестандартни конфигурации. 

Обработката на входящите логове се осигуряваше от Logstash на различни портове на пет координатора на ElasticSearch. Един индекс, независимо от размера, се състоеше от пет шарда. Беше организирана почасова и дневна ротация, в резултат на което всеки час в клъстера се появяваха около 100 нови шарда. Докато логовете не бяха много, клъстерът справяше и настройките му никой не оспорваше. 

Проблеми с бързия растеж

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

Точно мащабироването ни доведе до това, че клъстерът стана почти неуправляем. Когато логовете започнаха да постъпват със скорост от 20 хиляди съобщения в секунда, честа безполезна ротация увеличи броя на шардовете до 6 хиляди, а на един възел се падаха над 600 шардове. 

Това доведе до проблеми с разпределението на оперативната памет, а при падането на възел започваше наведнъж преместването на всички шардове, увеличавайки трафика и натоварвайки останалите възли, което правеше почти невъзможно записването на данни в клъстера. И през този период ние оставахме без логове. А при проблема с сървъра. ние губехме 1/10 от клъстера в принцип. Допълнително усложняваше голямото количество индекси с малък размер.

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

Поставихме си задачата — напълно да изключим загубата на логове и да съкратим времето за доставка им в клъстера ELK до максимум 15 минути по време на извънредни ситуации (на тази цифра впоследствие се опирахме като на вътрешен KPI).

Нов механизъм на ротация и hot-warm възли

Как укротихме терабайтите логове в ЦИАН

Преобразуването на клъстера започнахме с обновление на версията на ElasticSearch от 5.5.2 на 6.4.3. Клъстерът отново легна на версия 5 и решихме да го затворим и напълно обновим — логовете все пак ги нямаше. Така че този преход направихме само за няколко часа.

Най-значителното преобразуване в този етап беше внедряването на три възли с координатор като междинен буфер Apache Kafka. Носителят на съобщения ни избави от загубата на логове по време на проблеми с ElasticSearch. В същото време добавихме 2 възли в кластера и преминахме на архитектура hot-warm с три "горещи" възли, разположени в различни шкафове в дата центъра. На тях насочихме логовете, които не трябва да губим — nginx, както и логовете за грешки на приложенията. На останалите възли отиваха незначителни логове — debug, warning и т.н., а "важните" логове от "горещите" възли се прехвърляха след 24 часа.

За да не увеличаваме броя на малките индекси, преминахме от ротация по време на механизма rollover. В форумите имаше много информация, че ротацията по размер на индекса е много ненадеждна, затова решихме да използваме ротация по брой документи в индекса. Анализирахме всеки индекс и фиксирахме броя на документите, след който трябва да се извърши ротация. По този начин постигнахме оптимален размер на шардовете — не повече от 50 Гб. 

Оптимизация на кластера

Как укротихме терабайтите логове в ЦИАН

Въпреки това напълно не успяхме да се избавим от проблемите. За съжаление, все пак се появяваха малки индекси: те не достигаха зададения обем, не ротацияха и бяха изтривани с глобалното почистване на индекси на възраст над три дни, тъй като премахнахме ротацията по дата. Това водеше до загуба на данни, тъй като индексът напълно изчезваше от клъстера, и опитът за запис в несъществуващ индекс нарушаваше логиката на curator-a, който използвахме за управление. Alias за запис се преобразуваше в индекс и нарушаваше логиката на rollover-а, предизвиквайки неконтролирано растежа на някои индекси до 600 Гб. 

Например, за конфигурацията за ротация:

сurator-elk-rollover.yaml

---
actions:
  1:
    action: rollover
    options:
      name: "nginx_write"
      conditions:
        max_docs: 100000000
  2:
    action: rollover
    options:
      name: "python_error_write"
      conditions:
        max_docs: 10000000

При отсъствие на rollover alias се появяваше грешка:

ERROR     alias "nginx_write" not found.
ERROR     Failed to complete action: rollover.  <type 'exceptions.ValueError'>: Unable to perform index rollover with alias "nginx_write".

Решението на този проблем оставихме за следващата итерация и се заехме с друг въпрос: преминахме на pull логика на работа с Logstash, който обработва входящите логове (изтриване на излишна информация и обогатяване). Поставихме го в docker, който стартираме чрез docker-compose, там също разположихме logstash-exporter, който предоставя метрики в Prometheus за бързо наблюдение на потока от логове. Така си позволихме плавно да променяме броя на инстанциите на logstash, отговорни за обработката на всеки вид логове.

Докато усъвършенствахме клъстера, посещаемостта на cian.ru нарасна до 12,8 млн уникални потребители на месец. В резултат се получи, че нашите преобразувания малко не успяваха да следват промените в продукцията, и се сблъскахме с факта, че "топлите" възли не се справяха с натоварването и забавяха цялостната доставка на логовете. "Горещите" данни получавахме без прекъсвания, но при доставката на останалите трябваше да намесваме и да правим ръчен rollover, за да разпределим индексите равномерно. 

В същото време мащабирането и промяната на настройките на инстанциите на logstash в клъстера се усложняваше от факта, че това беше локален docker-compose, и всичките действия се извършваха ръчно (за добавяне на нови крайни точки беше необходимо ръчно да преминем по всичките сървъри и навсякъде да направим docker-compose up -d).

Преразпределение на логовете

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

Как укротихме терабайтите логове в ЦИАН

Следващата итерация започнахме с обновление на хардуера. От пет координатора преминахме на три, заменихме дата-възлите и спечелихме по отношение на разходите и обема на хранилището. За възлите използваме две конфигурации: 

  • За "горещите" възли: E3-1270 v6 / 960Gb SSD / 32 Gb x 3 x 2 (3 за Hot1 и 3 за Hot2).
  • За "топлите" възли: E3-1230 v6 / 4Tb SSD / 32 Gb x 4.

На тази итерация изнесохме индекса с access-логовете на микросервисите, който заема толкова място, колкото логовете от фронтовите nginx, във втората група от три "горещи" възли. Данните на "горещите" възли вече съхраняваме за 20 часа, а след това ги прехвърляме на "топлите" за останалите логове. 

Проблемата с изчезването на малките индекси беше решена чрез преустановяване на техния ротационен ред. Сега индексите ще се ротиране на всеки 23 часа, дори и при малко данни. Това малко увеличи броя на шардовете (станаха около 800), но от гледна точка на производителността на клъстера, това е приемливо. 

В резултат на това, в клъстера се получиха шест "горещи" и само четири "топли" нода. Това предизвиква малко забавяне на заявките за по-дълги интервали от време, но увеличаването на броя на нодите в бъдеще ще реши този проблем.

Тази итерация поправи и проблема с липсата на полуавтоматично мащабиране. За целта разгръща инфраструктурен кластер с Nomad — аналогичен на този, който вече имаме в продукция. В момента броят на Logstash не се променя автоматично в зависимост от натоварването, но ще стигнем и до това.

Как укротихме терабайтите логове в ЦИАН

Планове за бъдещето

Реализираната конфигурация отлично мащабира и в момента съхраняваме 13,3 Тб данни — всички логове за 4 дни, което е необходимо за спешно разглеждане на аларми. Част от логовете трансформираме във метрики, които съхраняваме в Graphite. За да улесним работата на инженерите, разполагаме с метрики за инфраструктурния клъстер и скриптове за полуавтоматично поправяне на типични проблеми. След увеличаването на броя на дата нодовете, което е планирано за следващата година, ще преминем от съхранение на данни за 4 дни до 7 дни. Това ще бъде достатъчно за оперативната работа, тъй като винаги се опитваме да разследваме инцидентите възможно най-бързо, а за дългосрочни разследвания имаме данни от телеметрия. 

През октомври 2019 година посещаемостта на cian.ru вече достигна 15,3 милиона уникални потребители на месец. Това беше сериозно изпитание за архитектурното решение за доставка на логове. 

Сега се подготвяме за обновление на ElasticSearch до версия 7. Всъщност, за това ще трябва да обновим mapping-а на много индекси в ElasticSearch, тъй като те преминаха от версия 5.5 и бяха обявени за остарели в версия 6 (в версия 7 те просто не съществуват). А това означава, че по време на обновлението неизбежно ще възникне някакъв форс-мажор, който временно ще ни остави без логове. От версия 7 най-много очакваме Kibana с подобрен интерфейс и нови филтри. 

Основната ни цел е постигната: спряхме да губим логове и намалихме времето за престой на инфраструктурния клъстер от 2-3 сривове седмично до няколко часа сервизни работи на месец. Цялата тази работа в продукцията е почти незабележима. Въпреки това, сега можем точно да определим какво се случва с нашата услуга, можем бързо да реагираме в спокойно време и не се притесняваме, че логовете ще бъдат загубени. В общи линии, доволни сме, щастливи сме и се подготвяме за нови подвизи, за които ще разкажем по-късно.

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

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster