Вы также можете поучаствовать в формате буткемпа в Core Infrastructure, где за 3 месяца попробуете себя в разных командах Core Infrastructure. Познакомитесь с разными задачами, погрузитесь в инженерные процессы и получите реальный опыт разработки инфраструктурных решений.

Mirror.yandex.ru — старый сервис в новой реальности
Борис Литвиненко, ведущий разработчик из Yandex Infrastructure, рассказывает, как сервис mirror.yandex.ru, созданный в 2007 году, менялся со временем и как теперь нейросети помогают делать его удобнее и быстрее.
В этой статье — о том, с какими вызовами столкнулся наш старый добрый mirror.yandex.ru, которому уже 19 лет, как мы поменяли под капотом почти всё и как ИИ помогает решать задачи, стоящие перед командой сервиса сегодня.
Что такое mirror.yandex.ru
Это зеркало репозиториев дистрибутивов ОС на базе Linux и других проектов. Здесь можно найти копии самых разных данных из открытых источников — от Ubuntu до Helm Charts.
История сервиса началась в 2007 году, когда несколько энтузиастов Яндекса решили сделать зеркало для внутренних нужд, чтобы не зависеть от интернета. Это был один сервер с дисковой полкой. Из протоколов были HTTP, rsync и FTP.
Mirror.yandex.ru сегодня
Я присоединился к этому проекту в 2018 году, на тот момент серверов было уже около десяти. Тогда архитектура показалось мне сложной, поэтому я начал с упрощения. Десять серверов заменил тремя более мощными, убрал концепцию мастера, потому что она часто нас подводила. Мы перешли на диски большего размера, они реже ломались. Железо и сеть стали мощнее, что позволило нам качать независимые копии параллельно.
Сервис стал проще, однако появились и минусы. Например, данные качались независимо и поэтому могли разъезжаться между хостами. Но нас защищало то, что серверы располагались в разных дата-центрах.
С тех пор произошло ещё немало изменений, часть из них:
- Поменяли концепцию железа — мы больше не жили на железе напрямую, а создали виртуалки и LXD-контейнеры на тех же хостах, где были дисковые полки. Nginx и качалку сделали в отдельных контейнерах, чтобы они не мешали друг другу.
- Закрыли FTP — он устарел, и в отказоустойчивой архитектуре с ним возникали сложности.
- Перешли на Ansible.
- Переехали CronJobs-частью на Kubernetes®.
Но в целом концепция осталась той же: каждый сервер в трёх дата-центрах качает данные независимо. Перед серверами есть L3-балансировщик, который по BGP Anycast берёт трафик и доставляет до сервера, а тот напрямую отдаёт ответ пользователю. При этом данные отдаёт Nginx: он берёт их частично с дисковой полки, частично из S3. Важно, что нам удалось сохранить листинг, а это одна из самых больших проблем в подобных ситуациях.
Общая схема выглядит так:

В таблице ниже — параметры, показывающие эволюцию сервиса:

Цифры mirror.yandex.ru сегодня:

- Свыше 200 терабайт данных на зеркале
- Более 150 репозиториев — от пары ГБ до 12 ТБ
- 6 серверов
- 3 зоны доступности
- 5–50 гигабит трафика
- Несколько тысяч RPS
С какими вызовами столкнулся сервис
В новых условиях нам предстояло разобраться со следующими сложностями в работе mirror.yandex.ru:
-
Интернет-блокировки и нехватка места на полках
Блокировки вызвали большой спрос на дополнительные зеркала, и место стало кончаться (в нашем случае копии данных лежат на каждом сервере). -
Снова понадобился мастер
Если выносить данные в S3, то требуется их туда качать, а значит, нужен мастер. Нет смысла качать на каждом хосте данные из интернета в тот же S3 шестью серверами. -
Листинг запрещают
Запрет листинга есть во многих репозиториях, потому что он дорогой. Если листить нормально нельзя, возникают сложности: например, даже по HTTP Wget невозможно рекурсивно выкачать данные. А если переносить всё в S3, как тогда делать листинг на нашей стороне? Проблема двусторонняя. -
Rsync/FTP отмирает. Как качать?
Rsync-апстримы остаются только на старых репозиториях, на новых зачастую есть только HTTP. При этом и на нашей стороне рано или поздно появится необходимость качать по схеме rsync → S3, но как это сделать — тоже вопрос. Кроме того, нужно уметь раздавать по rsync-протоколу из S3. -
DDoS
С приходом нейросетей у DDoS стало больше результативности. Особую сложность представляет SSL-флуд, когда процессор сжигается на хендшейках. -
Очень старые DEB-тулзы
Тулзы, которыми качаются репозитории, очень древние и в основном написаны на Perl, они парсят и качают файлы напрямую. Круто, что им не нужен листинг, однако они не работают с S3, и это тоже одна из проблем. -
Обслуживание железа
Всю эту новую систему сложно автоматизировать. Требуется и техническое обслуживание: постоянная замена дисков, синхронизация и другой сервис.
Как мы внедряли изменения
В 2025 году в моей команде появился стажер Вова, и мы стали активнее решать все эти проблемы, частью которых я занимался и раньше. Например, Ansible тогда частично уже был. В него переехали конфиги, но я не перевёл все машины на схему с виртуализацией и контейнерами. На части машин всё запускалось прямо на хосте, их надо было переналить, что мы и делали. Для Kubernetes® можно было сделать LXD-виртуалку и прокинуть виртуальную функцию сетевухи, чтобы всё работало быстро.
mdadm + ext4 vs ZFS
Поскольку мы стали использовать S3, снова понадобился мастер, но откуда его взять? Проще всего поставить Kubernetes®: есть уже распределённые CronJobs, и не нужно ничего делать самим.
Мы используем mdadm + ext4, однако решили попробовать ZFS. Каких-то критичных проблем с mdadm не было, но если вылетал один диск, нужно было снимать анонс этого сервера, иначе синхронизации не дождаться.
Ещё одна сложность — журналируемые файловые системы. При отключении питания был риск повреждения файловой системы, в том числе риск не восстановить её.
Сравним плюсы mdadm + ext4 и ZFS:

Для ZFS нам пришлось писать новый хук, который менял диски и создавал заявку инженерам в дата-центр. Мы даже получили немного больше места на дисках. Но если добавить диски разного размера в RAID10 из mdadm, то возьмётся самый маленький, и этот же объём места будет использоваться с остальных дисков. В ZFS эта проблема решилась: там можно объединить в пары диски одинакового — большего — размера.
А вот если говорить о производительности, то она никак не увеличилась (по моим тестам).
Что делать с rsync
Rsync умирает из-за прихода S3, поэтому мы решили менять его на rclone — это rsync для облаков. Фактически это качалка, которая не умеет ничего хитрого, но зато работает с разными S3 и с HTTP-листингом, может качать из HTTP в S3 и на local HDD, что очень удобно для синхронизации.
S3 vs local HDD
Нужно было выбрать хранилище. Если место кончается, можно ставить новые полки в сервер, но наш сервис деньги не зарабатывает: полки надо было где-то добывать. Поэтому мы пришли к S3 — добыть квоту намного проще.
С S3 также всплывает проблема rsync: рано или поздно придётся качать апстримы из rsync в S3, раздавать по rsync-протоколу из S3 и при этом не терять листинг в HTTP. Понятно, что листинг станет намного дороже.

Как сейчас выглядит реальное распределение по репозиториям в mirror.yandex.ru?

Rsync всё ещё занимает процентов 80% всех репозиториев. Но rclone уже захватывает пальму первенства.
Как решить проблемы с S3
Мы решили использовать GeeseFS. Это не просто Fuse над S3: он поддерживает симлинки над Яндекс S3. Однако не поддерживает хардлинки, поэтому пришлось принести Pull Request, который конвертировал хардлинки в симлинки. Также он протестирован с rsync (далеко не типовое использование Fuse) и поддерживает атрибуты. За тестирование отдельное спасибо команде Storage из соседней комнаты.
Какие проблемы решает GeeseFS?
- Rsync-сервер раздаёт с GeeseFS
- Листинг Nginx с GeeseFS
- Rsync → S3 через GeeseFS
- Кеширование
Вот как выглядит схема Nginx + S3:

В нашем сервисе в S3 лежит уже около 130 ТБ, тогда как на дисковой полке осталось 110 ТБ.
Итак, мы нашли решения для нескольких проблем:
- обновили концепцию железа, теперь работать с ним легче;
- разобрались с rsync;
- выбрали S3, и теперь место у сервиса не кончается;
- победили листинг.
Но снова возвращаемся к вопросу: как быть с мастером?
На наших машинах мы делаем LXD-виртуалки, три мастера, несколько worker nodes, объединяем всё в Kubernetes®-кластер. При этом CronJobs в Kubernetes® решают проблему распределённого лока.
Получается так:

Как удалось сделать K8s легко и быстро? В службе сетевой разработки NocDev мы занимаемся этим постоянно, поскольку работаем на своём железе.
Вот наш классический стек — виртуалки, Kubespray и Cilium:

Мы используем dualstack, потому что часть репозиториев невозможно скачать по IPv6, а наши дата-центры IPv6 only. Для IPv4 используется туннелирование, при этом VXLAN в Cilium задействует транспорт IPv6 only: туннельный адрес нужен только для похода за пределы кластера. У некоторых репозиториев есть IPv6-адрес, но по нему ничего не отдаётся — это тоже частая проблема, приходится подменять DNS и прятать шестую запись. Также используем Argo CD, чтобы можно было быстро деплоить и добавлять CronJobs с помощью нейросетей.
Чем нам помогает ИИ
У нас 150 репозиториев, и нет времени. Нужно, чтобы все процессы происходили очень быстро и без затрат.
С чем нам уже помогают нейросети?
Быстрое добавление новых репозиториев
Чтобы добавлять репозиторий оперативно, нужны:
- примеры в большом количестве;
- понятный CI/CD;
- большой объём документации;
- возможность для нейросети ходить в интернет.
Таким образом, мы можем с помощью нейросети написать YAML и почти сразу его задеплоить, если в Argo CD включен autosync. Это помогает заметно экономить время.
Разбор техдолга
Техдолг — это задачи, которые надо было решить 5 лет назад, но на них не хватало рук и времени. Например, проблема листинга коснулась и Nnginx: он лочит треды при чтении списка файлов больших репозиториев — в итоге наш инстанс может отстреливаться от балансера.
Можно отключить листинг, но мы пошли сложным путём и навайбкодили на Go нужный Daemon, который делает примерно такой же листинг, но без лока тредов Nginx. Всё работает:

Борьба с DDoS-атаками
ИИ также помогает бороться с DDoS-атаками. Например, можно навайбкодить BPF-программу (фильтр), с помощью которой резать трафик ещё до попадания в основные ядерные структуры.
Так выглядит сетевой стек в Linux:

Я написал небольшую XDP-программу Rate Limiter, которая лимитирует sync-пакеты per source IP. Это срезает основной вектор атаки. Использовал для этого схему с токен-бакетами, которую придумал мой коллега.
Вот как это выглядит:

Подведём итоги: какие репозитории у нас есть сегодня?
Ubuntu, конечно, лидирует, но её уже догоняют другие дистрибутивы:

Казалось бы, внешне сервис остался практически тем же, но под капотом изменилось почти всё. Да, в сервисе нет ничего сложного, но нужно было собрать компоненты вместе так, чтобы всё работало быстро и без проблем.
В нашей команде NocDeV есть задачи для разных технических специалистов. Нужны как амбициозные middle-разработчики и опытные ведущие инженеры, так и активные технические менеджеры. Приходите вместе развивать популярные сервисы.



