«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

На сьогоднішній день сервіс «Бітрікс24» не має сотень гігабіт трафіку, немає величезного парку серверів (хоча й існуючих, звичайно, чимало). Але для багатьох клієнтів він є основним інструментом роботи в компанії, це справжній business-critical додаток. Тому падати — ну ніяк не можна. А якщо падіння все-таки трапилося, але «повстав» сервіс так швидко, що ніхто нічого і не помітив? І як вдається реалізувати при цьому failover без втрати якості роботи та кількості клієнтів? Олександр Демидов, директор напряму хмарних сервісів "Бітрікс24", розповів для нашого блогу про те, як за 7 років існування продукту еволюціонувала система резервування.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

«У вигляді SaaS ми запустили „Бітрікс24“ 7 років тому. Головна складність, напевно, була така: до запуску в паблік у вигляді SaaS цей продукт існував просто у форматі коробкового рішення. Клієнти купували його у нас, розміщували у себе на серверах, заводили корпоративний портал - загальне рішення для спілкування співробітників, зберігання файлів, ведення завдань, CRM, ось це все. І ми до 2012 року вирішили, що хочемо запустити це як SaaS, адмініструючи самостійно, забезпечуючи стійкість до відмов і надійність. Досвід ми набирали в процесі, тому що до того часу у нас його просто не було - ми були лише виробниками ПЗ, не сервіс-провайдерами.

Запускаючи сервіс, ми розуміли, що найголовніше — це забезпечити стійкість до відмов, надійність і постійну доступність сервісу, тому що якщо у вас простий звичайний сайт, магазин, наприклад, і він упав у вас і лежить година — страждаєте тільки ви самі, ви втрачаєте замовлення Ви втрачаєте клієнтів, але для самого вашого клієнта — для нього це не дуже критично. Він засмутився, звичайно, але пішов і купив на іншому сайті. А якщо ця програма, на яку зав'язана вся робота всередині компанії, комунікації, рішення, то найголовніше — це завоювати довіру користувачів, тобто не підводити їх і не падати. Тому що вся робота може стати, якщо щось усередині працювати не буде.

Бітрікс.24 як SaaS

Перший прототип ми зібрали за рік до публічного запуску у 2011 році. Зібрали приблизно за тиждень, подивилися, покрутили — він навіть був працюючим. Тобто можна було зайти у форму, ввести назву порталу, розгортався новий портал, заводилася база користувачів. Подивилися на нього, оцінили в принципі продукт, згорнули і цілий рік далі допрацьовували. Тому що ми мали велике завдання: ми не хотіли робити дві різні кодові бази, ми не хотіли підтримувати окремо коробковий продукт, окремо хмарні рішення, — ми хотіли робити все це в рамках одного коду.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

Типовий веб-додаток на той момент - це один сервер, на якому крутиться якийсь код php, база mysql, файли завантажуються, документи, картинки кладуться в папку upload - ну і все це працює. На жаль, запускати критично стійкий веб-сервіс на цьому неможливо. Там розподілений кеш не підтримується, реплікація бази даних не підтримується.

Ми сформулювали вимоги: це вміння розміщуватись у різних локейшнах, підтримувати реплікацію, в ідеалі розміщуватись у різних географічно розподілених дата-центрах. Розділити логіку продукту та, власне, зберігання даних. Динамічно вміти масштабуватися за навантаженням, статику взагалі винести. З цих міркувань склалися, власне, вимоги до продукту, який ми протягом року і допрацьовували. За цей час у платформі, яка вийшла єдиною — для коробкових рішень, для нашого власного сервісу, ми зробили підтримку тих речей, які нам були необхідні. Підтримка реплікації mysql на рівні самого продукту: тобто розробник, який пише код — не замислюється, як його запити розподілятимуться, він використовує наш api, а ми вміємо правильно розподіляти запити на запис і читання між майстрами та слейвами.

Ми зробили підтримку на рівні продукту різних хмарних об'єктних сховищ: google storage, amazon s3 — плюс, підтримка open stack swift. Тому це було зручно і для нас як для сервісу, і для розробників, які працюють із коробковим рішенням: якщо вони використовують просто наш api для роботи, вони не замислюються, де в результаті файл збережеться, локально на файловій системі або потрапить до об'єктного файлового сховища .

У результаті ми одразу вирішили, що резервуватимемося на рівні цілого дата-центру. У 2012 році ми запускалися повністю в Amazon AWS, тому що ми вже мали досвід роботи з цією платформою — наш власний сайт там розміщувався. Нас приваблювало те, що в кожному регіоні в Amazon'e є кілька зон доступності — по суті, (в їхній термінології) кілька дата-центрів, які більш-менш один від одного незалежні і дозволяють нам резервуватися на рівні цілого дата-центру: якщо він раптом виходить з ладу, бази реплікуються master-master, сервери веб-застосунків зарезервовані, а статика винесена в об'єктне сховище s3. Навантаження балансується — на той момент амазонівським elb, але згодом ми прийшли до власних балансувальників, бо нам потрібна була складніша логіка.

Що хотіли – те й отримали…

Усі базові речі, які ми хотіли забезпечити — стійкість до відмов самих серверів, веб-додатків, баз даних — все працювало добре. Найпростіший сценарій: якщо у нас виходить з ладу якийсь із веб-додатків, то тут все просто - вони вимикаються з балансування.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

Машини, що вийшли з ладу, балансувальник (тоді це був амазоновський elb) сам позначав unhealthy, вимикав розподіл навантаження на них. Працював амазонівський автоскейлінг: коли навантаження зростало, додавалися нові машини до автоскейлінг-групи, навантаження розподілялося на нові машини — все було добре. З нашими балансувальниками логіка приблизна та сама: якщо щось трапляється з сервером додатків, ми прибираємо з нього запити, викидаємо ці машини, стартуємо нові і продовжуємо працювати. Схема за всі ці роки трошки змінювалася, але продовжує працювати: вона проста, зрозуміла, і жодних труднощів із цим немає.

Ми працюємо по всьому світу, піки навантаження у клієнтів абсолютно різні, і, по-хорошому, ми повинні мати можливість проводити ті чи інші сервісні роботи з будь-якими компонентами нашої системи у будь-який час – непомітно для клієнтів. Тому ми маємо змогу вимкнути з роботи базу даних, перерозподіливши навантаження на другий дата-центр.

Як це все працює? — Трафік ми перемикаємо на працюючий дата-центр — якщо це аварія на дата-центрі, то повністю, якщо це наші планові роботи з якоюсь однією базою, то ми частину трафіку, який обслуговує цих клієнтів, перемикаємо на другий дата-центр, зупиняється реплікація. Якщо потрібні нові машини для веб-додатків, оскільки виросло навантаження на другому дата-центрі, вони автоматично стартують. Роботи закінчуємо, реплікація відновлюється і ми повертаємо все навантаження назад. Якщо нам треба дзеркально провести якісь роботи у другому ДЦ, наприклад, встановити системні оновлення або змінити налаштування у другій базі даних, то, загалом, повторюємо все те саме просто в інший бік. А якщо це аварія, ми робимо все банально: в системі моніторингу використовуємо механізм event-handlers. Якщо у нас спрацьовує кілька перевірок і статус переходить у critical, то у нас запускається цей handler, обробник, який може виконати ту чи іншу логіку. У нас для кожної бази прописано який сервер є для неї failover'ом і куди потрібно переключити трафік у разі її недоступності. Ми — так історично склалося — використовуємо у тому чи іншому вигляді nagios чи будь-які його форки. У принципі, подібні механізми є практично в будь-якій системі моніторингу, щось складніше ми поки що не використовуємо, але, можливо, колись будемо. Зараз моніторинг спрацьовує на недоступність і може щось переключити.

Чи всі ми зарезервували?

У нас багато клієнтів із США, багато клієнтів із Європи, багато клієнтів, які ближчі до Сходу — Японія, Сінгапур і так далі. Зрозуміло, велика частка клієнтів у Росії. Тобто робота далеко не в одному регіоні. Користувачам хочеться швидкого відгуку, є вимоги щодо дотримання різних локальних законів, і всередині кожного регіону ми резервуємося на два дата-центри, плюс є якісь додаткові сервіси, які знову ж таки зручно розміщувати всередині одного регіону — для клієнтів, які в цьому регіон працює. Обробники REST, сервери авторизації, вони менш критичні для роботи клієнта в цілому, по них можна перемикатися з невеликою прийнятною затримкою, але не хочеться винаходити велосипеди, як їх моніторити і що з ними робити. Тому максимум ми намагаємося використовувати вже існуючі рішення, а не розвивати в себе якусь компетенцію щодо додаткових продуктів. І десь ми банально використовуємо перемикання на рівні dns, причому жвавість сервісу визначаємо тим самим dns. У Amazon є сервіс Route 53, але це не просто dns, в який можна записи внести і все, він набагато гнучкіший і зручний. Через нього можна побудувати гео-розподілені сервіси з геолокаціями, коли ви з його допомогою визначаєте, звідки прийшов клієнт, і даєте йому ті чи інші записи - з його допомогою можна побудувати архітектуру failover. Ті самі health-checks налаштовуються в самому Route 53, ви задаєте endpoint, які моніторяться, задаєте метрики, задаєте, за якими протоколами визначати «живість» сервісу - tcp, http, https; задає періодичність перевірок, що визначають, сервіс живий чи ні. І в самому dns прописуєте, що буде primary, що буде secondary, куди перемикатися, якщо спрацьовує health-check всередині route 53. Все це можна зробити якимись іншими інструментами, але чим це зручно - один раз налаштували і потім взагалі не думаємо про тому, як у нас робляться перевірки, як у нас триває перемикання: все працює саме.

Перше «але»: а як і чим резервувати сам route 53? Хіба мало, що з ним щось станеться? Ми, на щастя, жодного разу на ці граблі не наступали, але знову ж таки, попереду в мене буде розповідь, чому ми думали, що все-таки резервувати треба. Тут ми стелимо собі соломку заздалегідь. Декілька разів на добу ми робимо повне вивантаження всіх зон, які у нас в route 53 заведені. API Amazon'a дозволяє їх спокійно віддавати в JSON, і у нас піднято кілька резервних серверів, куди ми це конвертуємо, вивантажуємо у вигляді конфігів та маємо, грубо кажучи, бекапну конфігурацію. Якщо ми можемо швидко розгорнути її вручну, не втратимо дані налаштувань dns.

Друге «але»: що у цій картині ще не зарезервовано? Сам балансувальник! У нас розподіл клієнтів у регіонах зроблено дуже просто. У нас є домени bitrix24.ru, bitrix24.com, .de - зараз їх штук 13 різних, які працюють по різних зонах. Ми дійшли наступного: у кожному регіоні — свої балансувальники. Так зручніше розподіляти по регіонах, залежно від того, яке пікове навантаження по мережі. Якщо це збій на рівні якогось одного балансувальника, то він просто виводиться з експлуатації та забирається з dns. Якщо відбувається якась проблема з групою балансувальників, то вони резервуються на інших майданчиках, і перемикання між ними робиться за допомогою тієї ж route53, тому що за рахунок короткого ttl перемикання відбувається максимум протягом 2, 3, 5 хвилин.

Третє «але»: що ще не зарезервовано? S3 правильно. Ми, розміщуючи файли, які зберігаємо у користувачів в s3 – щиро вірили, що він бронебійний і нічого там резервувати не треба. Але історія свідчить, що відбувається по-іншому. Взагалі, Amazon описує S3 як фундаментальний сервіс, тому що сам Amazon використовує S3 для зберігання образів машин, конфігів, образів AMI, снепшотів… І якщо падає s3, як це одного разу сталося за ці 7 років, скільки ми bitrix24 експлуатуємо, він за собою віялом тягне купу всього - недоступність старту віртуалок, збій у роботі api і таке інше.

І впасти S3 може так сталося одного разу. Тому ми дійшли наступної схеми: ще кілька років тому серйозних об'єктних публічних сховищ у Росії не було, і ми розглядали варіант робити щось своє… На щастя, ми цього робити не почали, бо закопалися б у ту експертизу, якої ми не володіємо, і напевно накосячили б. Зараз s3-сумісні сховища є у Mail.ru, є у Яндекса, є ще ряд провайдерів. Ми врешті-решт дійшли думки, що хочемо мати, по-перше, резервування, по-друге, можливість роботи з локальними копіями. Для конкретно російського регіону ми використовуємо сервіс Mail.ru Hotbox, який по api сумісний з s3. Нам не знадобилося якихось серйозних доробок за кодом усередині додатка, і ми зробили наступний механізм: у s3 є тригери, які спрацьовують на створення/видалення об'єктів, у Amazon є такий сервіс, як Лямбда — це serverless запуску коду, який виконається якраз при спрацьовуванні тих чи інших тригерів.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

Ми зробили дуже просто: якщо у нас спрацьовує тригер, ми виконуємо код, який скопіює об'єкт у сховище Mail.ru. Щоб повноцінно запустити роботу з локальними копіями даних, нам потрібна ще зворотна синхронізація, щоб клієнти, які знаходяться в російському сегменті, могли працювати зі сховищем, яке ближче до них. Mail ось-ось доробить тригери у себе в сховищі - можна буде вже на рівні інфраструктури виконувати зворотну синхронізацію, поки ми це робимо на рівні нашого власного коду. Якщо ми бачимо, що клієнт розмістив якийсь файл, то ми на рівні коду вміщуємо подію в чергу, обробляємо її і робимо зворотну реплікацію. Чим вона погана: якщо у нас відбувається якась робота з нашими об'єктами поза нашим продуктом, тобто якимись зовнішніми засобами, ми це не врахуємо. Тому ми чекаємо до кінця, коли з'являться тригери на рівні сховища, щоб незалежно від того, звідки ми виконали код, об'єкт, який до нас потрапив, копіювався в інший бік.

На рівні коду у нас для кожного клієнта прописуються обидва сховища: одне вважається основним, інше – бекапним. Якщо все добре, ми працюємо з тим сховищем, яке до нас ближче: тобто наші клієнти, які в Amazon, вони працюють із S3, а ті, хто працює в Росії, вони працюють з Hotbox. Якщо спрацьовує прапорець, то маємо підключитися failover, і ми клієнтів переключаємо на інше сховище. Ми цей прапорець можемо ставити незалежно регіонами і можемо їх туди-сюди перемикати. На практиці ще цим не користувалися, але цей механізм передбачили і думаємо, що колись нам це саме перемикання знадобиться і знадобиться. Одного разу це вже сталося.

Ой, а у вас Amazon втік.

Цього квітня — річниця початку блокувань Телеграм у Росії. Найстрашніший провайдер, який під це потрапив, - Amazon. І, на жаль, найбільше постраждали російські компанії, які працювали на весь світ.

Якщо компанія глобальна і Росія для неї зовсім маленький сегмент, 3-5% — ну, так чи інакше, можна ними пожертвувати.

Якщо це суто російська компанія — я впевнений, що потрібно розміщуватися локально — просто самим користувачам буде зручно, комфортно, ризиків буде менше.

А якщо це компанія, яка працює глобально, і має приблизно порівну клієнтів з Росії, і десь по світу? Зв'язок сегментів важлива, і працювати один з одним вони так чи інакше повинні.

Ще наприкінці березня 2018-го Роскомнагляд направив найбільшим операторам листа про те, що вони планують заблокувати кілька мільйонів ip Amazon, для того щоб заблокувати… месенджер Zello. Дякуємо цим самим провайдерам - вони лист успішно всім злили, і виникло розуміння, що зв'язність з Amazon може розвалитися. Це була п'ятниця, ми в паніці прибігли до колег із servers.ru, зі словами: «Друзі, нам потрібно кілька серверів, які стоятимуть не в Росії, не в Amazon, а, наприклад, десь в Амстердамі», для того щоб мати можливість хоча б якимось чином поставити там власні vpn і proxy для якихось endpoint'ів, на які ми ніяк не можемо впливати, наприклад, endpont'и того ж s3 — не можна спробувати підняти новий сервіс і отримати інший ip, нам все одно треба туди достукатися. За кілька днів ми ці сервери налаштували, підняли, і загалом, на момент початку блокувань підготувалися. Цікаво, що РКН, подивившись на галас та підняту паніку, сказав: «Ні, ми зараз блокувати нічого не будемо». (Але це рівно до того моменту, коли почали блокувати телеграм.) Налаштувавши можливості обходу і зрозумівши, що блокування не запровадили, ми, тим не менш, не почали цю справу розбирати. Так, про всяк випадок.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

І ось 2019 року ми таки живемо в умовах блокувань. Я ось учора вночі дивився: близько мільйона IP продовжують блокуватися. Щоправда, Amazon майже в повному складі розблокували, у піку доходило до 20 мільйонів адрес... Загалом, реальність така, що зв'язності, хорошої зв'язності її може не бути. Несподівано. Її може не бути з технічних причин — пожежі, екскаватори, таке інше. Або, як ми бачили, не зовсім технічне. Тому хтось великий і великий, з власними AS-ками, мабуть, може цим керувати іншими шляхами — direct connect та інші речі вже на рівні l2. Але в простому варіанті, як ми або ще дрібніші, можна про всяк випадок мати резервування на рівні серверів, піднятих деінде, налаштованих заздалегідь vpn, proxy, з можливістю швидко на них перемикати конфігурацію в тих сегментах, які у вас критичні за зв'язністю . Це нам стало в нагоді неодноразово, коли почалися блокування Amazon, ми через них пускали в найгіршому випадку якраз трафік S3, але поступово все це розрулилося.

А як резервувати… цілого провайдера?

Зараз сценарію на випадок виходу з ладу Amazon у нас немає. Ми маємо схожий сценарій для Росії. Ми в Росії розміщувалися в одного провайдера, у якого ми вибирали, щоби було кілька майданчиків. І рік тому ми зіткнулися з проблемою: навіть незважаючи на те, що це два дата-центри, вже на рівні конфігурації мережі провайдера можуть бути проблеми, які торкнуться обидва дата-центру. І ми можемо одержати недоступність на обох майданчиках. Звісно, ​​так і сталося. Ми врешті-решт переглянули архітектуру всередині. Вона не дуже змінилася, але для Росії у нас зараз два майданчики, які не в одного провайдера, а в двох різних. Якщо в одного щось вийде з ладу, ми можемо перейти на іншого.

Гіпотетично ми для Amazon розглядаємо можливість резервувати на рівні іншого провайдера; можливо, Google, можливо, ще хтось ... Але поки ми спостерігали на практиці, що якщо у Amazon аварії на рівні однієї availability-зони трапляються, то аварії на рівні цілого регіону досить рідкісне явище. Тому ми теоретично маємо уявлення про те, що ми, можливо, зробимо резервування «Amazon — не Amazon», але на практиці такого поки що немає.

Пари слів про автоматизацію

Чи завжди потрібна автоматика? Тут доречно згадати ефект Даннінг-Крюгера. По осі «х» наші знання та досвід, якого ми набираємось, а по осі «у» — впевненість у наших діях. Ми спочатку не знаємо нічого і зовсім не впевнені. Потім ми знаємо трошки і стаємо мега-впевненими - це так званий "пік дурості", добре ілюструється картинкою "недоумство і відвага". Далі ми вже трохи навчилися і готові йти в бій. Потім ми наступаємо на якісь мега-серйозні граблі, потрапляємо в долину розпачу, коли щось знаємо, а насправді ми багато чого не знаємо. Потім, у міру набору досвіду, стаємо вже впевненішими.

«Бітрікс24»: «Швидко підняте не вважається таким, що впало»

Наша логіка про різні перемикання автоматично на ті чи інші аварії вона дуже добре описується цим графіком. Ми стартували — ми нічого не вміли, практично всі роботи робилися вручну. Потім ми зрозуміли, що можна на все навісити автоматику і типу спати спокійно. І раптом ми наступаємо на мега-граблі: у нас спрацьовує false positive, і ми перемикаємо туди-сюди трафік, коли по-хорошому не варто було цього робити. Отже, ламається реплікація чи ще щось — ось та сама долина розпачу. А далі приходимо до розуміння, що до всього треба ставитись з розумом. Тобто є сенс покластися на автоматику, передбачивши можливість помилкового спрацьовування. Але! якщо наслідки можуть бути руйнівними, то краще віддати це на відкуп черговій зміні, черговим інженерам, які переконаються, простежать, що справді аварія, і необхідні дії виконають вручну.

Висновок

За 7 років ми пройшли шлях від того, що коли щось падало — була паніка-паніка, до розуміння, що проблем не існує, є лише завдання, їх необхідно — і можна вирішувати. Коли ви будуєте якийсь сервіс, подивіться на нього зверху, оцініть всі ризики, які можуть статися. Якщо ви відразу бачите їх - то заздалегідь передбачайте резервування та можливість побудови відмовостійкої інфраструктури, тому що будь-яка точка, яка може вийти з ладу та призвести до непрацездатності сервісу - вона обов'язково це зробить. І навіть якщо вам здається, що якісь елементи інфраструктури точно не вийдуть з ладу — на кшталт того ж s3, все одно майте на увазі, що вони можуть. І хоча б у теорії майте уявлення про те, що ви з ними робитимете, якщо щось таки трапиться. Майте план відпрацювання ризиків. Коли ви замислюєтеся про те, щоб робити все автоматикою чи вручну, — оцініть ризики: що буде, якщо автоматика почне все перемикати — чи це не призведе до ще гіршої картини порівняно з аварією? Можливо, десь потрібно використовувати розумний компроміс між використанням автоматики та реакцією чергового інженера, який оцінить реальну картину та зрозуміє, чи треба з ходу щось переключити чи «так, але не зараз».

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

Цей текст є доповненою та розширеною версією доповіді Олександра Демидова на конференції Uptime day 4.

Джерело: habr.com

Додати коментар або відгук