Якщо Medium робить цей контент доступним лише за плату, ви також можете переглянути його тут (LinkedIn).
Я був технічним керівником інфраструктури для інтеграційного тестування в усій компанії як в Amazon, так і в Google протягом багатьох років, і спосіб, як ці дві компанії мислять про CI/CD, суттєво відрізняється.
Я працював у Amazon понад 11 років (2009–2020). Я був головним інженером в організації засобів розробника, яка володіла всією інфраструктурою та засобами CI/CD для компанії. Ми були відповідальні за весь програмний засіб, який використовували десятки тисяч співробітників Amazon кожен день для написання коду, рецензування коду, збирання коду, тестування коду та впровадження коду.
У 2020 році мені було цікаво спробувати щось абсолютно інше, і я приєднався до Google, де працював 4 роки як технічний керівник інфраструктури для інтеграційного тестування, важливої складової частини інструментарію CI/CD Google. Хоча ці предметні області схожі, я не міг уявити собі дві більш відмінні технологічні стопки.
Зараз я знову в Amazon, після того як набув досвіду того, як абсолютно інша компанія, Google, дивиться на це. Було цікаво розглядати речі з різним поглядом.
Спочатку визначення
Спочатку деякі визначення, щоб ми всі були на одній стороні:
- "CI/CD" означає постійну інтеграцію (CI) та постійне впровадження (CD). Основна ідея - як зміна коду потрапляє з локальної робочої області розробника на виробництво.
- "Pre-Submit" відноситься до досвіду розробника перед тим, як він подасть шматок коду. В мене було особливий інтерес до того, яку перевірку можна провести для шматка коду перед тим, як він перевірений в системі контролю версій. Це може включати види тестування змін у вашій локальній робочій області або як частину процесу рецензування коду.
- "Post-Submit" відноситься до досвіду розробника після того, як він подав шматок коду.
Як ми об'єднуємо зміни, як ми розгортаємо їх на реалістичних тестових середовищах і валідуємо їх там, і як ми доводимо їх до виробництва.
- "Тестування" в даному випадку відноситься до інтеграційного тестування, або тестування зі всією системою, а не до модульного тестування. Модульне тестування легко запустити будь-де, але для інтеграційного тестування кандидатний код потрібно розгорнути на систему під тестування, і встановити залежності, що додає експоненційний рівень складності до інфраструктури.
Однажди я зрозумів, що Google добре працює до відправки змін, а не дуже добре після відправки, тоді як Amazon відмінно працює після відправки, але не дуже добре до неї.
Введення Monorepo та Microrepos
Довгий час мене ця різниця здивувала, але я думаю, що тепер я розумію кореневу причину. Google використовує монорепозиторій, де більшість своїх 120 тисяч інженерів ділять одне сховище без гілок. Amazon використовує десятки тисяч мікрорепозиторіїв (які ми називаємо «наборами версій» - технічно не зовсім мікрорепозиторії, але для цієї дискусії можна розглядати їх як мікрорепозиторії). Приблизно для кожної служби створюється свій мікрорепозиторій (існують всілякі винятки, але ми їх пропустимо, знову ж таки, для цілей цієї дискусії).
Мій добрий друг Alex Xu, співзасновник ByteByteGo, написав цікаву статтю, яка глибоко вдавлася у філософію монорепозиторію проти мікрорепозиторіїв, тому я не буду повністю повторювати її тут, але розгляну докладніше у контексті перед- та після-відправлення тестування.
Примітка: Ця стаття не є повним обговоренням "монорепозиторій проти мікрорепозиторіїв". Вона має на меті сфокусуватися на перед- або після- відправленні тестування в контексті CI/CD, що значно впливає на це.
Google, Перед-відправлення
Коли у вас понад сто тисяч розробників використовують одне сховище без гілок, радіус пошкодження від недоброї перевірки є величезним.
Є ненульова ймовірність того, що ваш коміт може заблокувати тисячі або десятки тисяч інженерів. Перебуваючи в Google, я іноді був блокований випадковим комітом від випадкової людини з випадкової частини компанії і, на жаль, я не зміг зрозуміти чому. Google вклав значні зусилля щоб мати можливість виконувати інтеграційні тести з кінця в кінець з локального середовища розробки або під час код-рев’ю в ефемерних, герметичних тестових середовищах. Фактично, була не одна інфраструктура, а чотири конкуруючі, дублюючі інфраструктури, які органічно і незалежно зростали протягом останніх двадцяти років. Я брав участь в спробі їх східчення, яка, я впевнений, триватиме ще довго після того, як мене не буде. Це було значущим зусиллям, в якому було задіяно понад сотню інженерів. Загалом, можливість виконувати коректні інтеграційні тести перед відправкою була дуже чарівною для мого амазонського перилового мозку.
Google, Після Відправки
Незважаючи на чарівність перед-відправком, зворотний бік медалі виявився досить слабким. Після мого першого коміту з нетерпінням запитав інженера у своїй команді: "Коли я побачу ці зміни на Продакшні?" Він відповів дуже невимушено: "О, у вівторок". Я залишився шокований. Для мого амазонського перилового мозку це було безбожництво. Amazon наполягає на тому, що кожна зміна коду повинна потрапити на Продакшн за години (про це далі). Звісно, це можливо утопічним, і зміни коду, які впливають на декілька сервісів, наприклад, мають багато додаткової складності і потребують більше часу, але більшість змін коду дійсно потрапляють на Продакшн за години. Для мене ідея виконання деплоїв тільки в певні дні, в певний час, виглядала дуже застарілою. Проблема, з якою стикається Google (зі своїм монорепо), полягає в тому, що одна зміна коду може вплинути на сотні тисяч деплоїв.
Batching code changes helps, but then a single deployment can include dozens or hundreds of independent changes, which means that if a deployment fails, you now have to identify the culprit. Again Google being Google, we had dozens of culprit finders for this purpose, always duplicative and competing (you’re beginning to see a pattern here…).
Amazon, Перед Поданням
Філософія клеючись до мікро-репозиторіїв надає Amazon дуже чудовий вбудований механізм зменшення зони вразливості. Поганий код може зламати окремий мікро-репозиторій, але після подання тестів зазвичай він виявляється і блокується, щоб не потрапити на інші мікро-репозиторії й не зламати їх. Поганий код може подратувати ваших найближчих колег, але не може одразу ж зламати десятки тисяч незнайомців (хоча, в кінцевому підсумку, він може, якщо після-подання тестів вашого мікро-репозиторію не виявить його).
Маючи вбудований механізм зменшення зони вразливості, не було критичною необхідністю вкладати великі кошти у перед-подання тестів, як це було для Google. Це було б приємним, але не обов'язковим.
Не те, що ми не хочемо вкладати в удосконалення інфраструктури перед-подання тестів, але з обмеженими кадрами ми отримували більше за свої гроші, переконуючись, що наша інфраструктура після-подання є найкращою в своєму класі (оскільки проблеми неухвалення обов'язково виникали б на після-поданні, незалежно від того, наскільки дивовижні були перед-подання тестів). Щоб усвідомити масштаб, Amazon був заощадливим і наші інвестиції були приблизно в десяту частину того, що витратила Google. Тому, як багато я б хотів забезпечити фінансування та створити ефемерні тестові середовища для забезпечення перед-подання тестів, мені довелося бути безжалісно прагматичним щодо того, куди я підтримував, щоб моя організація вкладала свої кадрові ресурси.
Звичайно: Перенесення Тестування до Лівої Сторони - дивовижна річ. Зловити проблеми на локальному рівні розробки, або на перегляді коду у найгіршому випадку, набагато бажаніше, ніж зловити їх після подання. Чим пізніше у життєвому циклі розробки програмного забезпечення ви виявите помилку, тим дорожче її виправлення.
And in retrospect, had I made the case for investing in ephemeral, hermetic test environments at Amazon a decade ago, it would have more than paid for the investment in saved developer toil. Hindsight is 20/20.
Amazon, Post-Submit
Якщо говорити про досвід після відправки на Amazon, тут компанія виявляється відмінною. Мікрорепозиторій є набагато більш закритим середовищем, ніж монорепозиторій, тому ми можемо гарантувати, що кожна зміна коду пройде належне тестування та дістанеться до продукції протягом кількох годин для певного сервісу. Справа ускладнюється, коли ви маєте зміни, які впливають на кілька сервісів та потребують синхронізації декількох мікрорепозиторіїв (монорепозиторій гарно вирішує цю проблему!), але насправді велика більшість змін коду досить локальна для одного сервісу. Філософія Amazon щодо мікрорепозиторіїв дуже добре працює для незалежних мікросервісів, і Amazon вклався в цю концепцію ще задовго до 2002-го маніфесту Безоса щодо API, і побудував цілу концепцію команд з двома піццами навколо цього. Коли ви відкриваєте свій браузер на http://amazon.com, це не просто монолітний додаток у одному репозиторії. Ваша дія призводить до викликів літерально в сотні або тисячі сервісів, які розташовані в такій самій кількості мікрорепозиторіях, кожен з яких вилучає незалежні фрагменти даних, щоб ви могли зробити своє замовлення на Amazon.
Заключні думки
Дискусія про монорепозиторій проти мікрорепозиторіїв є приблизно такою ж результативною, як "коти проти собак, який кращий улюбленець?" або "чи є хот-дог сендвічем?"
Я працював в обох середовищах. Ось що я помітив: якщо ви починали займатися мікрорепозиторіями, вам ймовірно не сподобається монорепозиторій, і навпаки. Інженери з Meta або Google, які приходять на Amazon, вважають мікрорепозиторії не зручними та хочуть переконати нас перейти на монорепозиторій.
markdown
Я, з іншого боку, сприйняв(ла) монорепозиторій майже вісцерально під час перебування в Google. Це дуже особисте уподобання. Я не думаю, що я міг(ла) би запропонувати переконливий, заснований на даних аргумент, що один підходить об'єктивно краще за інший.
У кінцевому підсумку, завжди є складність у CI/CD для великих систем. Google і компанії, які вірили в монорепозиторій, обрали управляти складністю в одному місці. Amazon і компанії, які вірили в мікрорепозиторії, обрали працювати з абсолютно іншою складністю в іншому місці. Це приблизно однаковий рівень складності, просто в різних місцях.
Для того, щоб монорепозиторій працював, Google не лише повинен був інвестувати в ефемерні середовища для забезпечення тестування перед відправленням, вони також повинні були інвестувати в розумний вибір тестів і роботи над виправленням тестів. Як визначити, які тести виконувати для певної зміни коду? Залежності будуються в Blaze (система збірки Google), тому в теорії ви можете просто обчислити графік збірки і виконати всі тести всіх, хто мав залежність від пакунка, який ви змінюєте. Але коли сотні тисяч інженерів працювали у одному репозиторії десятиліттями, ці графіки залежностей можуть бути величезні, і ви просто не можете постійно запускати мільйони тестів "просто на випадок". Тому Google побудував велику кількість інфраструктури навколо розумного вибору тестів (щоб скоротити кількість тестів для виконання) і, будучи Google, існувало десятки дублюючих, конкуруючих зусиль для зменшення непостійності тестів. Це мало значення, оскільки непостійність тестів зростає експоненціально. Якщо у вас є N тестів у вашому наборі тестів, і кожен має ймовірність успіху P%, ймовірність того, що ваш весь набір тестів працюватиме, дорівнює P^N. Навіть щось на кшталт трьох тестів із індивідуальною ймовірністю успіху 99% означає, що об'єднані вони мають ймовірність успіху лише 97% (99%³). Тому зменшення кількості тестів для виконання і зменшення їх непостійності було вельми важливим для забезпечення функціонування монорепозиторію на масштабі Google і підтримання його здоров'я.
Загалом, інвестиції у інфраструктуру були величезними, скажімо 300 інженерів за вартістю $400k/рік кожен (лише використовуючи загальнодоступні цифри з levels.fyi, середня зарплата для SWE рівня L4 становить $278k/рік, але слід мати на увазі, що вартість праці інженера для компанії набагато вища за їх зарплату) - це легко перевищує 100 мільйонів доларів на рік. Робота з монорепозитарієм вимагає великих витрат.
Для того, щоб мікрорепозитарії працювали, Amazon повинен був інвестувати в інфраструктуру для управління тим, як зміни коду безпечно та своєчасно подаються від мікрорепозитарію до мікрорепозитарію, що також вимагало значної команди. У світі монорепозитарію зміна одразу стає доступною для всіх; у світі мікрорепозитаріїв, якщо ви використовуєте бібліотеку або загальний компонент, вам потрібно вивід або введення між мікрорепозитаріями. Якщо ви цікавитесь, мій друг та колишній Вищий Принципалний Інженер у Amazon Клер Лігуорі написала деякі статті про філософію CI/CD у Amazon.
Моя стаття фокусується на аспекті Тестування у CI/CD, але варто відзначити, що монорепозитарій спрощує такі речі, як патчі безпеки та ініціативи між компаніями. І розв'язання версій залежностей може бути викликом у мікрорепозитаріях: що, якщо ваш мікрорепозитарій використовує FooBar-1.2, а одна з ваших залежностей використовує FooBar-1.3? Але з міркувань лаконічності я хотів сконцентруватися у своїй статті на історії інтеграційних тестів до та після надсилання для обох компаній.
Щодо Перед-Надсилання чи Після-Надсилання: в кінцевому підсумку, це не повинно бути АБО, це повинно бути І. Ми повинні мати чудову інфраструктуру перед надсиланням, а також чудову інфраструктуру після надсилання. Це просто потребує усвідомленої інвестиції, але коли у вас є десятки тисяч розробників, інвестування в скорочення навантаження на розробника має величезний вплив, тому це виправдовується.
Перекладено з: How Amazon and Google view CI/CD in an entirely different way