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-разработчики и опытные ведущие инженеры, так и активные технические менеджеры. Приходите вместе развивать популярные сервисы.

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

Mirror.yandex.ru — старый сервис в новой реальности

Читать также

Войдите, чтобы сохранить пост