Тестування розподілених систем, — інтерв'ю з Андрієм Сатариным, Яндекс


Тестування розподілених систем істотно відрізняється від тестування централізованих. Деякі тестувальники можуть похвалитися серйозними знаннями та досвідом у цій галузі.

Я поспілкувався зі спікером конференції Heisenbug 2016 Moscow Андрієм Сатариным (twitter.com/asatarin). Андрій брав участь у проектах по тестуванню в Mail.ru у Лабораторії Касперського, Deutsche Bank, а зараз тестує розподілені системи в Яндексі. Стаття буде корисна не тільки людям, які займаються тестуванням, але і розробникам. Якщо ви жодного разу не торкалися питання тестування розподілених систем, ласкаво просимо під капот.

Андрій Сатарин:

… вони вбивають ноди прямо в робочий час і розробники спостерігають за...


Способи та особливості тестування розподілених систем
– Які методики і стратегії тестування розподілених систем існують? Чим вони відрізняються?

– Крім усім відомих класичних підходів (модульне тестування, системне тестування, інтеграційне тестування) для розподілених систем є підходи, які покликані виявляти складні дефекти.

Дуже популярний підхід впровадження збою (fault injection). Коли система працює, ми за допомогою спеціальних програм і механізмів додаємо збої: збої дисків або цілих машин, може бути, мережеві збої, збої внутрішніх компонентів тестованої системи. Оскільки переважна більшість розподілених систем повинні володіти стійкістю до подібного роду збоїв, принаймні, в якихось обмежених масштабах, то система не повинна припиняти свою роботу або проявляти якихось аномалій у роботі. По суті це тестування на відмовостійкість, оскільки це одне з найважливіших функціональних вимог до розподілених систем. Чим більше машин працює, тим вище ймовірність індивідуальної проблеми на якійсь з них. Наприклад, якщо задіяна тисяча машин, то, умовно кажучи, диски будуть вилітати раз в тиждень. Система зобов'язана переживати такі ситуації жодним чином їх не помічаючи.

Є більш академічні підходи, наприклад, формальна верифікація (formal verification). У розподілених системах є внутрішні алгоритми та протоколи, які дозволяють їй працювати. Вони самі по собі досить складні, але гарантують деякі інваріанти, які повинні досягатися завжди, незалежно від будь-яких збоїв в системі, переупорядковування пакетів в мережі і чого-небудь ще. Суть підходу полягає в тому, що на основі опису алгоритму на спеціальному мовою перевіряється його коректність. Це дає впевненість у тому, що той алгоритм, який використовується, за умови, що він коректно реалізований, буде працювати.

У 2015 році вийшла академічна стаття від Microsoft Research «Proving Practical Distributed Systems Correct», де вони описали модель системи розподіленого сховища, після чого за допомогою спеціальних інструментів перевірили цю модель на коректність, а потім згенерували код, який відразу ж заробив.

– Які особливості необхідно враховувати при тестуванні розподілених систем?

– Особливість в тому, що важливо розуміти, які саме інваріанти гарантує досліджувана система. Наприклад, зараз популярні nosql бази даних, які можуть бути більш високопродуктивними, але вони не підтримують транзакції. Тобто їх рівень консистентности нижче, ніж у класичних (MySql, PostgreSQL, Oracle). І, коли відбувається тестування такої розподіленої системи, типу nosql бази даних, важливо, щоб було розуміння, які саме інваріанти вона підтримує. Від цього залежать аномалії, які будуть спостерігатися в тестах. У складних тестах, наприклад, коли є кілька конкурентних письменників і читачів, можна побачити багато різних станів. Іншими словами, потрібно розуміти, які ефекти можна спостерігати в системі, а які — ні.

Нефункціональні вимоги відіграють найбільш суттєву роль
– Які типові помилки роблять самі люди при тестуванні розподілених систем?

– Найпоширеніша помилка — це перевірка не всіх гарантій, які система повинна надавати, в цьому випадку система стає недотестирована. Друга помилка, яка може дорого коштувати, це не тестування на відмову якоїсь частини системи. З досвіду, якщо в розподіленій системі якась підсистема не тестувалася на fault injection, то багів там трохи більше, ніж дуже багато.

– Які метрики і характеристики розподіленої системи важливо тестувати і чому?

– З нефункціональних вимог це, по-перше, відмовостійкість (fault tolerance), а по-друге, це продуктивність (perfomance). Для розподілених систем нефункціональні вимоги відіграють найбільш суттєву роль порівняно з функціональними вимогами. Fault tolerance на першому місці, тому що спочатку система повинна працювати, а якщо вона не працює, то інше вже не так важливо.

– Наскільки важлива продуктивність тестів? Потрібно враховувати можливі затримки мережі при розробці тестів для розподіленої системи?

– Це залежить від видів тестів, про яких йде мова. Якщо це модульні тести, то продуктивність важлива. У загальному випадку, звичайно, краще мати швидкі тести (як кажуть, краще бути здоровим і багатим). Це вірно для функціональних тестів. Для нефункціональних, які перевіряють, наприклад, консистентним або стійкість до збоїв, продуктивність тестів важлива для більш частого прояву дефектів. Наприклад, якщо дефект проявляється один раз на мільйон операцій, то чим частіше відбуваються ці операції, тим частіше проявляється і дефект. Якщо це займає годину, то це цілком прийнятно. Якщо це займає кілька днів, то пошук таких дефектів стає проблемою.

98% всіх дефектів можна відтворити лише на 3 ноди
– чи Потрібно створювати спеціальні кластера для тестування чи можна використовувати «бойові» кластера, які знаходяться в продакшені? Як визначити оптимальний розмір тестового кластера?

– Найчастіше застосовують саме тестові кластера. Якщо говорити про тестування на бойових серверах, то найвідоміший приклад — це компанія Netflix, яка активно пропагує свій підхід, званий «simian army», тобто «армія макак». Він полягає в тому, що вони в продакшені роблять fault injection. Вони вбивають ноди прямо в робочий час і розробники спостерігають за тим, щоб система ніяк при цьому не деградувала. Але тут треба розуміти, що така можливість з'являється тільки починаючи з якогось масштабу. Якщо система працює на 10-20 ноди, то тестування подібним чином означає, що буде деградація на 5-10%. В продакшені не всі готові на такі жертви. Крім того, може бути якийсь service level agreement (SLA) і таке тестування може бути дорого з-за його порушення. У будь-якому випадку, навіть якщо зустрічається практика тестування на продакшені, то існує перед цим величезна тестова інфраструктура, яка відловлює більшу частину дефектів. Перевага тестування в продакшені тільки в тому, що немає необхідності повторювати продуктивне оточення.

З приводу розміру тестового кластера. Якщо система розподілена, то він повинен бути більше одиниці — це обмеження знизу. На тему обмежень зверху є стаття «Simple Testing Can Prevent Most Critical Failures», в якій досліджується питання про те, які помилки є в розподілених системах. Згідно статті, дослідники прийшли до висновку, що 98% всіх дефектів можна відтворити лише на 3 ноди. Конкретно в нашій роботі ми використовуємо більше, зазвичай тестовий кластер складається з 8 нод, але це пов'язано з внутрішнім пристроєм нашої системи.

– Як боротися з повними або частковими відмовами розподіленої системи під час тестування?

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

– Які конкретно технології та інструменти використовуються для створення тестового оточення? Для автоматизації тестування?

– Тестове оточення залежить від технологій, які використовуються для розробки, і від технологій, які знайомі команді. Ми, наприклад, активно використовуємо Python, тому що він добре підходить для таких завдань і наші тестувальники його знають. Він простий в плані написання тестів, досить високорівневий, щоб на ньому можна було писати зрозуміло. На мій погляд, у нього трохи «біда» з concurrency, але ця проблема вирішувана. Сама система розробляється на C++, але його використовувати для високорівневих тестів досить важко, так як швидко і легко розробляти на ньому не вийде, а в тестах буває важлива швидкість розробки.

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

– У тебе є ще що-небудь, що ти б хотів додати по темі?

– Я б хотів додати, що на тему тестування розподілених систем є величезна кількість матеріалів як академічних, так і близьких до індустрії, безліч підходів і способів тестування. Пошук методів та їх вдосконалення не зупиняється ні на день. Ця тема постійно розвивається – і саме цим вона цікава.




Послухати більше доповідей на тему тестування можна буде 10 грудня в готелі «Radisson Слов'янська» на конференції Гейзенбаг. Реєстрація ще відкрита.

Теми доповідей:

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.