Про зеркала репозиториев Centos и выбор лучшего из них
В прошлом году мы организовали у себя в сети общедоступные зеркала для нескольких Linux дистрибутивов. Это не сложный процесс и для больших проектов, вроде Ubuntu, почти полностью автоматизированный. В других случаях необходимо тем или иным способом связаться с проектом, например, в списке рассылки и явно высказать своё желание.
Технически это rsync , обычно по расписанию. Кто-то для этого предоставляет готовый набор скриптов, как Fedora, а кто-то просто говорит что надо синхронизироваться вот с этого сервера и рекомендуемый набор параметров. Самый затратный ресурс это место, мы недавно добрались до 4 терабайт и это дорого в нашем случае для того что не генерирует никакой прибыли. Взамен мы получили локальную доступность используемых нами дистрибутивов, это позволило упростить первоначальную настройку серверов исключив из неё обязательный доступ к Интернет. А ещё конечно мы рады что приобщились к чем-то большому, даже если наше участие в этом не сильно заметно.
Наше зеркало публичное, с него могут получать обновления все желающие, что собственно и происходит если судить по статистике обращений. В основном это Россия, но не только. Про то как так получается и как вообще происходит выбор конкретного сервера для обновлений на примере Centos седьмой версии этот пост.
Будем говорить о пакетном менеджере yum с установленным по умолчанию плагином fastestmirror и нас будет интересовать только процесс выбора конкретного зеркала.
Список зеркал
Известно, что список репозиториев задаётся в файлах в каталоге /etc/yum.repos.d/ если не указано иное. Вот так выглядят настройки репозитория Base в файле /etc/yum.repos.d/Centos-Base.repo :
Здесь видно две опции которые задают место откуда можно получать данные. Первая baseurl непосредственно указывает зеркало, никакого выбора тут не нужно. Вторая mirrorlist указывает ссылку по которой будет возвращён список из 10 зеркал из которых и будет делаться выбор, именно эта опция активна. Также мы видим несколько переменных внутри ссылки, все они в конечном итоге отражают конкретное место в дереве каталогов репозитория:
- release – версия: 6 , 7 , 8 , 8-stream . Более старые версии выведены из действующей инфраструктуры, но снимки их репозиториев можно найти на http://vault.centos.org/
- arch — архитектура, например i386 или x86_64 . Для некоторых версий некоторые архитектуры будут отсылать к альтернативным репозиториям и другой системе зеркал, но при этом инфраструктура выбора зеркала остаётся общей. Для 7 версии единственно поддерживаемой базовыми зеркалами является x86_64 , альтернативной i386 . Для первой будет формироваться список в базовой структуре зеркал, для второй из альтернативной
- repo – в нашем случае os , но может быть updates или другим, собственно тип репозитория отражает какие данные нам нужны. Для 8 версии аналогом os будет baseos
- infra – могу осторожно предположить, что до сих пор не используется, как минимум я не смог найти его обработку при формировании списка зеркал. Он равен stock , но если опустить этот параметр никаких видимых изменений не последует
- cc – код страны, для США и Канады ещё и код штата. Его нету в примере из файла выше, так как страна вычисляется при запросе по IP адресу запрашиваемого. Эту переменную можно использовать чтобы исключить ошибки геопозиционирования. Для России будет cc=ru
Для 7-й версии Centos получим вот такую строчку http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock по которой будет выдан список из 10 зеркал примерно такого вида:
Обратите внимание, что конкретный путь для каждого зеркала точно соответствует переменным в запросе. Указана полная версия вместо старшей, хотя можно использовать и её: http:// /7/os/x86_64/ тоже существует, реализовано с помощью символической ссылки на последнюю версию.
Реализация
Теперь к реализации, которую можно найти на https://github.com/CentOS/mirrorlists-code, нам интересно то как формируется список зеркал. Этим занимается перловый скрипт makemirrorlists-combined.pl. Основная его задача проверить живость зеркала путём сравнения хеша файла repodata/repomd.xml с эталонным для данной версии и архитектуры. Соответственно файл должен существовать для всех доступных комбинаций версий, типов репозиториев и архитектуры.
Проверка осуществляется по списку в следующем порядке (цитирую из кода):
Пункты 1 и 2 работают или-или, чтобы проверить не только код страны, но и код штата. По сути происходит попытка выбрать ближайшие географически серверы. Для каждого шага выполняется запрос из базы данных, например:
Потом идёт проверка живости зеркал по этому списку путём сравнения хешей, как написано выше. Если набирается 10 живых, то на этом требуемая задача выполнена, работа завершена. Если не набирается то переходим к следующему шагу чтобы добрать общий список до 10 или пока не исчерпаем все варианты. Результат сохраняется в файле и отдаётся на откуп фронтенд части представленной Python скриптом ml.py, задача которого выбрать и отдать нужный файл, предварительно выяснив страну источника запроса по IP адресу. Также учитывается и тип протокола IPv4 или IPv6, для которых формируются разные списки.
Вернёмся к запросу в котором используется ORDER BY RAND() , означает ли это что список будет случайным? Да, насколько случайна само реализация в СУБД, но это касается только порядка внутри каждого шага. То есть, если для конкретной страны набирается больше 10 зеркал нужного типа репозитория и архитектуры (для России всего 17), то в итоге каждый раз мы будем получать перетасованный список из 10 разных зеркал в одной стране. Если их меньше, то вверху списка всегда будут перетасованные репозитории из одной страны, дальше перетасованные репозитории из ближайших стран и так далее по шагам. В итоге получаем не совсем случайный список состоящий из нескольких случайных частей. Это имеет значение когда рабочих зеркал внутри одной страны не так много, например IPv6 зеркал в России всего 7 и они всегда будут вверху списка:
http://mirror.corbina.net/pub/Linux/centos/7.7.1908/os/x86_64/
http://mirror.yandex.ru/centos/7.7.1908/os/x86_64/
http://mirrors.powernet.com.ru/centos/7.7.1908/os/x86_64/
http://mirror.reconn.ru/centos/7.7.1908/os/x86_64/
http://mirror.sale-dedic.com/centos/7.7.1908/os/x86_64/
http://ftp.nsc.ru/pub/centos/7.7.1908/os/x86_64/
http://dedic.sh/centos/7.7.1908/os/x86_64/
http://ftp.funet.fi/pub/mirrors/centos.org/7.7.1908/os/x86_64/
http://centos.mirror.far.fi/7.7.1908/os/x86_64/
http://mirrors.glesys.net/CentOS/7.7.1908/os/x86_64/
Ещё хуже дело обстоит с архитектурой i386 это альтернативная архитектура для Centos 7 и отдельная система зеркал. В России всего один такой сервер который поддерживает альтернативные архитектуры, он всегда будет на первом месте:
http://mirror.vpsnet.com/centos-altarch/7.7.1908/os/i386/
http://mirrors.huaweicloud.com/centos-altarch/7.7.1908/os/i386/
http://linux.darkpenguin.net/distros/CentOS-AltArch/7.7.1908/os/i386/
http://ftp.agdsn.de/pub/mirrors/centos-altarch/7.7.1908/os/i386/
http://mirror1.hs-esslingen.de/pub/Mirrors/centos-altarch/7.7.1908/os/i386/
http://mirror.infonline.de/centos-altarch/7.7.1908/os/i386/
http://ftp.rz.uni-frankfurt.de/pub/mirrors/centos-altarch/7.7.1908/os/i386/
http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos-altarch/7.7.1908/os/i386/
http://mirrors.daticum.com/centos-altarch/7.7.1908/os/i386/
Список перестал быть случайным, если ориентироваться на первую строчку то выбор предопределён. Поддержка репозиториев для альтернативных архитектур Centos в принципе вызывает озабоченность, но тут для многих чистый альтруизм.
Сканирование репозиториев происходит постоянно и не учитывая механизмы кеширования результат обновляется примерно раз в 3 часа. Цитата из mirrorlist_crawler_deployment_notes.txt:
— A full scan of all repos and all versions without any cached data is going to take close to 3 hours, but typically altarch is
На практике, я запустил получение вариантов списка зеркал в России для IPv4 и IPv6 раз в минуту для репозитория Base Centos 7 — http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock&cc=ru и вышло вот так за пару суток наблюдений:
синим IPv4 список, красным IPv6. Изменение происходит не каждые 25 минут, но и не раз в 3 часа — всё умещается в интервале от получаса до двух. Картина с архитектурой i386 и альтернативными зеркалами кардинально другая — http://mirrorlist.centos.org/?release=7&arch=i386&repo=os&infra=stock&cc=ru около недели наблюдений:
Можно ожидать что каждые 15 минут у нас будет новый список, за 30 минут какие-то изменения в нём произойдут обязательно. Но! Помним что чем меньше активных зеркал тем менее случаен порядок и на первом месте сейчас в России всегда одно и то же зеркало.
Fastestmirror
Итого, список зеркал формируется в лучшем случае случайно, что наверное не плохо для балансировки нагрузки. В худшем мы можем ожидать что выбирая только первое зеркало из списка у нас будет отсутствовать выбор как таковой. В дополнение к этому территориальное деление по странам в случае большой страны, как наша, может сыграть злую шутку, поставив наверх списка зеркало из Петропавловск-Камчатского http://mirror.vilkam.ru для клиента из Сочи. Поэтому неплохо бы оценить доступность зеркал из этого списка. Этим занимается плагин fastestmirror. Суть которого сводится к простому действию:
Никаких HTTP или ICMP , открываем сокет для узла, считаем сколько на это ушло времени, к результатам применяем sort() . На вход параметрами подаются все те 10 зеркал которые были получены на предыдущем шаге, в виде полного URL из которого используется только имя узла. Плагин легко заставить работать отдельно от yum , надо только закомментировать строчки 52 и 55:
Обработка происходит в несколько потоков поэтому ждать долго не приходится, даже для всех 17 зеркал которые числятся в России. Результат работы в виде двух списков, первый в котором указано время выполнения является отладочным и он не отсортирован, хотя может так показаться. Второй после слова Result отсортирован от меньшего отклика к большему, именно он используется для дальнейшей работы в полученном порядке.
В dnf тоже используется fastestmirror из набора библиотек RPM, но там это решено через libcurl и в целом всё сложнее устроено.
В конечном итоге всё зависит от того насколько быстро будет получен ответ от зеркала, при этом стоит учесть кеширование, то есть непосредственное вычисление задержки производится не всегда. На временные интервалы сильно влияет собственная производительность локальной машины и её загруженность. Близкие узлы показывающие похожие результаты, наверное будут часто меняться местами. Но тут достигается, как мне кажется главная цель — не отправить узел из Сочи за обновлением в Петропавловск-Камчатский, сходить до Москвы или Волгограда вполне допустимо. На что ещё обращаем внимание, выбор производится из списка который получен на первом шаге до fastestmirror , если этих данных ещё нет в кеше, то самое близкое зеркало с первой попытки может не стать самым лучшим, просто потому что оно даже не будет анализироваться не попав в искомую десятку.
На практике получились следующие результаты первого места на недельном опросе через каждые 10 минут. Цифры — количество раз сколько узел выигрывал при сравнении, для fastestmirror и fping :
1422,1013 mirror.logol.ru
534,986 mirror.docker.ru
28,8 mirrors.datahouse.ru
16 centos-mirror.rbc.ru
6 mirror.sale-dedic.com
5,7 mirror.reconn.ru
2 dedic.sh
1 mirror.corbina.net
1989,1980 mirror.reconn.ru
18,34 mirror.sale-dedic.com
7 dedic.sh
Видно что выбор не прямо однозначный, но тут скорее всего играет роль близость точки с которой я делал опрос — до нескольких зеркал, разница меньше миллисекунды. Второй момент, IPv6 список отличается и он хуже — ближайший IPv6 узел дальше чем ближайший IPv4 и выбор меньше. С учётом приоритета IPv6 получается не очень. Результаты fping лаконичнее, меньше выигрывавших узлов, но в целом одинаковы с fastestmirror .
RIPE Atlas
С локальным выбором более менее всё понятно, теперь посмотрим как обстоят дела в рамках всей страны. Для чего воспользуемся услугами https://atlas.ripe.net/ — набор зондов (пробников) и инструментария для работы с ними под эгидой RIPE NCC, сразу предупрежу, это не самый быстрый и поворотливый сайт. Получить пробник может любой желающий, так же как и воспользоваться этой сетью. Но для запуска тестов нужна внутренняя валюта, которая копится с тех устройств которые за вами числятся и активны. Я выбрал все устройства в России которые поддерживают одновременно IPv6 и IPv4, таких получилось 82. По результатам измерений часть пришлось отсеять, поэтому осталось 67 из более чем 400.
Вариантов тестов которые можно запустить несколько, конечно там нет такого какой используется в fastestmirror , но есть обычный ping . Для всех зеркал, за исключением mirror.linux-ia64.org для которого ICMP зафильтрован и mirror.axelname.ru которое появилось после того как были сделаны тесты, со всех выбранных устройств, отдельно для IPv6 и IPv4, каждые 3 часа в течение недели выполнялось по 10 запросов. Среднее время ответа записывалось. Из всего набора измерений, около 50 по каждому зеркалу, бралась медиана и сравнивалась с остальными зеркалами на этом пробнике. Зеркало с наименьшим временем ответа выигрывало.
22 mirror.docker.ru
12 mirror.awanti.com
10 centos-mirror.rbc.ru
6 dedic.sh
4 mirror.truenetwork.ru
3 mirror.corbina.net
3 mirrors.powernet.com.ru
2 ftp.nsc.ru
2 mirrors.datahouse.ru
1 mirror.reconn.ru
1 mirror.vilkam.ru
1 mirror.yandex.ru
20 dedic.sh
20 mirror.reconn.ru
10 mirror.yandex.ru
8 mirror.sale-dedic.com
5 ftp.nsc.ru
3 mirror.corbina.net
1 mirrors.powernet.com.ru
centos-mirror.rbc.ru,105.4163369
dedic.sh,109.2160474
ftp.nsc.ru,106.4012836
mirror.awanti.com,107.0802782
mirror.corbina.net,98.5339837
mirror.docker.ru,102.7883347
mirror.logol.ru,105.9588192
mirror.reconn.ru,106.5717624
mirror.sale-dedic.com,106.1676841
mirror.truenetwork.ru,110.9780753
mirror.tversu.ru,107.9966083
mirror.vilkam.ru,25.1486164
mirror.yandex.ru,99.7320257
mirrors.datahouse.ru,103.6546383
mirrors.powernet.com.ru,116.4087614
centos-mirror.rbc.ru,59.9632155
dedic.sh,63.765421
ftp.nsc.ru,59.349309
mirror.awanti.com,75.8998928571
mirror.corbina.net,59.906047
mirror.docker.ru,65.8720585
mirror.logol.ru,63.2041255
mirror.reconn.ru,63.7120505
mirror.sale-dedic.com,63.052342
mirror.truenetwork.ru,61.2567465
mirror.tversu.ru,66.2593372222
mirror.vilkam.ru,138.3730595
mirror.yandex.ru,63.4150445
mirrors.datahouse.ru,59.304435
mirrors.powernet.com.ru,78.7411795
Послесловие
Для тех кто добрался до этого места отвечу на вопрос который будет обязательно задан — наше зеркало http://mirrors.powernet.com.ru и вот как его используют:
При этом доля этого трафика изнутри нашей сети ничтожна.
Вот так на нём заканчивается место:
Хорошо различимые ступеньки — моменты когда мы добавляем новый дистрибутив. Когда всё начиналось это был VirtualBox работающий под Windows на офисном компьютере на котором хранились видеоархивы нашего рекламного отдела. Потом мы перебрались на боевую систему виртуализации и стало чуть полегче:
Для сравнения у mirror.truenetwork.ru отдача в 3 Гбит/c трафика с двух серверов. У нас всё гораздо скромнее и в общем нам более чем достаточно получать удовольствие от процесса, а также редкие удивлённо-восторженные отзывы от друзей и абонентов, когда кто-то замечает внезапно знакомые строчки во время обновления своей системы. А ещё, иногда мелькать на заднем плане в различных статьях и руководствах, где в логах или на снимках экрана видны ссылки на наше зеркало.
Посмотреть статус всех известных в Centos зеркал можно вот тут, а прочитать про то как присоединиться к проекту вот тут, это и просто и ответственно одновременно, но точно не бесполезно.
Источник