Наша группа по оптимизации производительности нашла маленькое изменение, которое оказало большое влияние на скорость сборки по всем конвейерам. Мы обнаружили, что установка параметра refspec во время git fetch ускоряет шаг клонирования в 100 раз.

Группа Engineering Productivity отвечает за поддержку инженеров, которые создают и развёртывают программное обеспечение в Pinterest. Наша команда поддерживает ряд инфраструктурных сервисов и часто работает над крупными проектами — перенос всего программного обеспечения на Bazel, создание платформы непрерывной доставки под названием Hermez. Они же поддерживают монорепозитории, куда ежедневно присылают по несколько сотен коммитов, и это ещё не все их задачи.

Мы направляем большие усилия на то, чтобы разработка и доставка программного обеспечения в Pinterest происходили быстро и безболезненно. Недавно жизнь ещё раз показала, какое большое влияние может оказать даже самая мелкая деталь. Мы нашли такую маленькую деталь в Git, которая значительно сократила время сборки в наших конвейерах непрерывной интеграции. Чтобы понять, как это маленькое изменение оказало такое большое влияние, нужно поделиться некоторой информацией о наших монорепозиториях и конвейерах.

Монорепозитории и конвейеры


У нас в Pinterest шесть основных репозиториев: Pinboard, Optimus, Cosmos, Magnus, iOS и Android. Всё это монорепозитории с большим наборов сервисов, специфичных для языка. Pinboard — самый крупный монорепозиторий, который поддерживается с момента основания компании. В нём более 350 тыс. коммитов и размер 20 ГБ при полном клонировании.

Клонирование монорепозитория с большим объёмом кода и длительной историей занимает много времени, а в наших конвейерах непрерывной интеграции приходится делать это очень часто в течение дня. Для одного только Pinboard в рабочие дни мы делаем больше 60 тыс. git pull. Большинство скриптов конфигурации конвейера Jenkins (написанных на Groovy) начинаются с этапа Checkout, где мы клонируем репозиторий, который на более поздних этапах будет построен и протестирован. Вот как выглядит типичная стадия Checkout:



Если использовать Git CLI напрямую:



```
Даже при неполном/поверхностном (shallow) клонировании, не извлекая никаких тегов и только для последних 50 коммитов, операция всё равно выполнялась не так быстро, как могла бы. Всё потому, что мы не устанавливали параметр refspec. Обратите внимание, что отсутствие этого параметра означает команду на извлечение всех refspec'ов: +refs/heads/*:refs/remotes/origin/*. В случае с Pinboard происходит обработка более 2500 ветвей.

Просто добавив опцию refspec и указав, какие ссылки нас интересуют (в нашем случае только из мастера), можно ограничить область обработки нужной ветвью и сэкономить много времени. Вот как это выглядит в нашем конвейере:



Простое изменение одной строки сократило время клонирования в 100 раз и в результате значительно сократило время сборки. Время клонирования крупнейшего репозитория Pinboard сократилось с 40 минут до 30 секунд. Это показывает, что иногда даже самые маленькие усилия имеют очень большое значение.