Команда инженерной продуктивности (The Engineering Productivity) в Pinterest одним маленьким изменением смогли привнести огромный вклад в ускорение пайплайнов сборки. Мы обнаружили, что установив правильное значение опции refspec при вызове git fetch сокращает время клонирования репозитория на 99%.
Команда инженерной продуктивности (The Engineering Productivity) в Pinterest отвечает за поддержку инженеров, которые разрабатывают и релизят весь софт внутри компании. Наша команда поддерживает большое количество инфраструктурных сервисов и часто работает над крупномасштабными проектами — миграция всех проектов на Bazel, разработка CD платформы под названием Hermez и поддержка моно-репозиториев, в которые коммитят пару сотен раз в день.
Все наши крупномасштабные проекты нацелены на достижение одной цели — сделать процесс разработки и релизов внутри Pinterest максимально быстрым и безболезненным. Недавно мы в очередной раз вспомнили, что всего одна маленькая деталь может иметь колоссальное влияние на цель. Мы обнаружили одну неприметную опцию git-команды, которая значительно сократило время сборки наших CI пайплайнов. Для того, чтобы понять, как одно маленькое изменение могло иметь настолько большое влияние, нам необходимо дать немного информации о наших моно-репозиториях и пайплайнах.
Моно-репозитории и пайплайны.
У нас есть шесть основных репозиториев в Pinterest: Pinboard, Optimus, Cosmos, Magnus, iOS и Android. Каждый из них является моно-репозиторием и содержит большое количество сервисов, специфичных для какого-то языка. Pinboard — самый старый репозиторий (его возраст равен возрасту компании) и самый большой. Он содержит более 350 тысяч коммитов и весит более 20 GB.
Клонирование репозиториев, которые содержат много кода и коммитов — это времязатратный процесс, и нам необходимо делать это постоянно в CI пайплайнах. Для одного только Pinboard мы делаем более 60 тысяч git pull в течение недели. Большинство наших Jenkins пайплайнов (написанных на Groovy) начинаются со стадии Checkout, в рамках которой мы клонируем репозиторий, после чего запускаем сборку и тесты. Вот, как обычно выглядит стадия Checkout:
stage("Checkout") {
checkout([
$class: 'GitSCM',
branches: [[name: 'master']],
extensions: [
[
$class: 'CloneOption',
depth: 50,
noTags: true,
shallow: true
]
],
userRemoteConfigs: [
[
url: <repo URL>
]
],
])
}
Если бы мы делали это вручную в терминале, команда выглядела бы следующим образом:
$ git clone <repo URL>
$ git fetch --no-tags --depth=50 <repo URL> +refs/heads/*:refs/remotes/origin/*
Даже несмотря на то, что мы говорим Git сделать неглубокое клонирование (shallow clone), не получать теги и скачивать только последние 50 коммитов, мы все еще не можем запустить эту операцию настолько быстро, как могли бы. Это происходит, потому что мы не устанавливаем refspec опцию. Заметьте, что, не устанавливая эту опцию в пайплайне, мы говорим Git, что хотим получить все существующие refspecs: +refs/heads/*:refs/remotes/origin/*. В случае Pinboard эта операция получала бы более 2500 веток.
Таким образом, добавив только refspec опцию и указав, какие refspecs нас интересуют (в нашем случае master), мы можем ограничить refs только теми ветками, которые нас интересуют, благодаря чему мы сэкономим кучу времени. Вот как это выглядит в нашем коде:
stage("Checkout") {
checkout([
$class: 'GitSCM',
branches: [[name: 'master']],
extensions: [
[
$class: 'CloneOption',
depth: 50,
noTags: true,
shallow: true
]
],
userRemoteConfigs: [
[
url: <repo URL>,
refspec: '+refs/heads/master:refs/remotes/origin/master'
]
],
])
}
Всего одна простая строчка сократила время клонирования наших репозиториев на 99% и ускорила сборку CI пайплайнов. Время клонирования самого большого репозитория (Pinboard) сократилось с 40 минут до 30 секунд. Это доказывает, что иногда наши небольшие усилия могут иметь большое значение.
Выводы
Как и большинство команд инженерной продуктивности, мы работаем над крупными проектами, которые оказывают большое влияние на нашу повседневную работу. Однако иногда именно исправления в одной строчке могут иметь огромное значение. Наша работа заключается в том, чтобы понять это.