В мире непрерывной интеграции и доставки (CI/CD) скорость сборок играет ключевую роль для продуктивности команд разработки и быстрого запуска новых функций. Одним из важных инструментов для сокращения времени сборки является кэширование. Однако стандартный механизм кэширования в GitHub Actions (GHA) имеет свои ограничения и недостатки, которые могут мешать эффективной работе и увеличивать время ожидания результатов. В рамках недавних исследований и разработок команда Depot провела реверс-инжиниринг внутренней работы кэша GHA, что позволило создать значительно более быстрые и надежные раннеры с улучшенной системой кэширования. В этой статье мы подробно рассмотрим проблему кэширования в GitHub Actions, способы решения, которые предложила компания Depot, а также результаты и перспективы развития данной технологии.
Проблемы стандартного кэширования в GitHub Actions GitHub Actions – популярный инструмент для автоматизации сборок, тестирования и деплоя. Главной задачей кэширования в этом инструменте является повторное использование результатов предыдущих сборок, чтобы не выполнять одинаковые задачи повторно и не забивать ресурсы. Тем не менее, сама архитектура GitHub Actions создает определенные ограничения. Суть проблемы заключается в том, что GitHub использует эпhemeral-раннеры — временные виртуальные машины, создаваемые для выполнения конкретной задачи и уничтожаемые после её завершения. Это требует удаленного хранения кэша, поскольку локальный диск ураннера не сохраняется между запусками.
Как следствие, при каждом запуске сборки кэш должен передаваться по сети от сервера хранения кэшу до раннера, а после сборки — обратно. Такого рода удаленное кэширование оказывает значительное влияние на скорость, выбор инфраструктуры, надежность и стабильность процесса. GitHub хранилище кэша по умолчанию работает через Azure Blob Storage, сеть при этом ограничена примерно 1 Гбит/с (около 125 МБ/сек) – это значит, что передача больших объемов данных происходит с ограниченной пропускной способностью. Кроме того, максимальный размер кэша ограничен 10 ГБ на репозиторий, что быстро становится препятствием для проектов с большими объемами зависимостей или артефактов. Проблему усугубляет нестабильность API кэширования, а также ограниченный параллелизм передачи данных: GitHub при стандартных настройках использует только две параллельные потока, что снижает максимальную скорость загрузки и выгрузки кэша.
В результате при больших и сложных сборках кэширование не дает ожидаемого ускорения, а иногда даже увеличивает время сборки из-за ожидания передачи кэша по сети. Параллельно с этим существуют альтернативные решения и сторонние провайдеры, предлагающие свои сервисы ускоренного выполнения workflows. Но они зачастую требуют перехода на кастомизированные действия с собственными операциями кэширования, что влечет дополнительную загрузку для разработчиков, вынужденных поддерживать несколько версий одинаковых workflows и плагинов. Как Depot решил проблему кэширования в GitHub Actions Компания Depot подошла к решению вопроса с уникальным подходом. Их цель была не только ускорить работу кэша, но и сохранить совместимость с дефолтным экосистемным решением GitHub, чтобы пользователи могли пользоваться ускорением без необходимости менять существующие workflow и избавляться от стандартных кэширующих действий.
В основе решения Depot – переработка инфраструктуры и программного обеспечения избранной архитектуры. Была выбрана инфраструктура AWS: раннеры запущены на мощных EC2 инстансах, кэш хранится в Amazon S3 с целью использования преимуществ высокой скорости и масштабируемости сети внутри облака AWS. Такой выбор тоже объясняется тесной интеграцией многих проектов в инфраструктуру AWS, что позволяет сократить задержки и повысить скорость обмена данными. Ключевым техническим приемом стало внедрение промежуточного Go-прокси, который перехватывает все вызовы API GitHub Cache на стороне раннера и перенаправляет их из стандартного Azure Blob Storage на S3. За счет использования этой прокси, Depot смог реализовать кэш API полностью на своих серверах, эмулируя стандартный GitHub Cache API и позволяя раннерам взаимодействовать с ним без необходимости изменения workflow.
Еще одним важным шагом стала оптимизация параллелизма сети при загрузке и скачивании кэша. В то время как стандартные GitHub Actions используют всего 2 параллельных потока, Depot экспериментировал с количеством потоков, постепенно увеличивая их до 4 при загрузке и до 8 при скачивании. Эта оптимизация позволила существенно увеличить пропускную способность и сократить время передачи. Итогом такой архитектуры стало достижение скорости передачи кэша более 1 ГБ/сек — это порядка десятикратного улучшения по сравнению с оригинальным кэшированием GitHub Actions. Кроме того, Depot повысил лимит размера кэша, убрав ограничение в 10 ГБ, а время хранения кэша продлил с 7 до 30 дней.
Архитектура GitHub Actions раннеров Depot Depot не ограничился только оптимизацией кэширования – также был пересмотрен подход к запуску самих раннеров. Как и у стандартных GitHub Actions, раннеры у Depot являются эпhemeral, то есть выделяются на время выполнения одной сборки и уничтожаются после её завершения. Однако с помощью предварительно прогретого пула standby машин в EC2, запуск нового раннера происходит моментально, что минимизирует задержки. Раннеры размещены в тех же дата-центрах AWS, где расположены Docker билд-сервисы Depot, что позволяет оптимизировать взаимодействие между ними и добиться значительных преимуществ по скорости передачи данных и снижению задержек. Пользователи, объединяющие в своих workflow и Depot Docker builders, и Depot GitHub Actions runner, получают дополнительное ускорение за счет близости инфраструктуры и высокоскоростного частного сетевого трафика, минуя интернет.
Результаты и преимущества использования Depot GitHub Actions раннеров Благодаря новому подходу к кэшированию и инфраструктуре, Depot удалось достичь впечатляющих результатов: Пропускная способность кэша выросла в 10 раз – до 1 ГБ/сек при загрузке и выгрузке. Устранены ограничения на размер кэша, что позволяет хранить большие наборы артефактов и зависимостей. Время хранения кэша увеличено с одной недели до 30 дней, что особенно полезно для проектов с редкими сборками или заданиями, требующими длительного хранения промежуточных результатов. Поддерживается совместимость со стандартным actions/cache@v3, то есть пользователям не нужно менять существующую конфигурацию workflow. Архитектура раннеров повышает стабильность и быстрое выделение вычислительных ресурсов, сокращая время ожидания и обеспечивая более предсказуемую производительность.
Depot также предлагает на базе схожей инфраструктуры новые возможности, например, раннеры с поддержкой ARM архитектуры, расширенные дисковые пространства и другие виды оптимизаций под конкретные задачи сборки. Перспективы развития и выводы Опыт Depot показывает, что глубокое понимание внутренней логики и протоколов действий GitHub позволяет создавать решения, которые дают значительный прирост производительности при минимальном уровне затрат и без необходимости ломать привычные процессы. Реверс-инжиниринг кэша GitHub Actions открыл путь к инновационным методам ускорения CI/CD, позволяя разработчикам сокращать время на итерации и повышать эффективность работы. В будущем, с ростом числа многоплатформенных проектов, ожидается, что подобные решения будут интегрировать еще больше оптимизаций: более тесное взаимодействие между кэшированием и сборочными системами, работа с разными архитектурами (ARM, x86), а также использование интеллектуальных алгоритмов кэширования для адаптации под конкретные типы проектов. В конечном итоге, решение Depot служит отличным примером того, как сочетание современных облачных технологий, внимательного анализа протоколов и творческого подхода к построению инфраструктуры может помочь преодолеть ограничения стандартных инструментов и добиться значительного ускорения рабочих процессов разработчиков.
Для команд, использующих GitHub Actions и стремящихся к максимальной производительности, пользование Depot может стать простым и эффективным шагом к улучшению своих CI/CD pipeline без необходимости фундаментальных изменений в конфигурации. Если вы заинтересованы испытать возможности ускоренного кэширования и раннеров Depot, вам достаточно создать бесплатный аккаунт и изменить параметр runs-on в вашем workflow с ubuntu-22.04 на depot-ubuntu-22.04 — и вы сразу почувствуете разницу в скорости и стабильности ваших сборок.