Distcc

From Gentoo Wiki
Jump to: navigation, search
This page is a translated version of the page Distcc and the translation is 97% complete.

Other languages:
Deutsch • ‎English • ‎español • ‎français • ‎italiano • ‎日本語 • ‎한국어 • ‎polski • ‎русский • ‎Türkçe • ‎中文(中国大陆)‎


Resources

Distcc — это программа, предназначенная для распределения по сети задач компиляции в рамках набора хостов. Она состоит из серверной части — distccd и клиентской — distcc. После небольшой настройки distcc может прозрачно работать с ccache, Portage и с небольшой настройкой Automake.

Если планируется использовать distcc для начальной сборки (bootstrap) установки Gentoo, обратите внимание на раздел использование distcc для bootstrap.

Установка

Перед настройкой distcc сперва нужно установить пакет sys-devel/distcc на все хосты.

Требования для всех хостов

Для работы с distcc все компьютеры в сети должны иметь GCC одной версии. К примеру, можно использовать на разных машинах 3.3.x (где x — разные), а смешивание 3.3.x с 3.2.x может привести к ошибкам при компиляции или выполнении.

USE-флаги

USE flags for sys-devel/distcc Distribute compilation of C code across several machines on a network

gnome Add GNOME support global
gssapi Enable support for net-libs/libgssglue local
gtk Add support for x11-libs/gtk+ (The GIMP Toolkit) global
hardened Activate default security enhancements for toolchain (gcc, glibc, binutils) global
ipv6 Add support for IP version 6 global
selinux !!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur global
xinetd Add support for the xinetd super-server global
zeroconf Support for DNS Service Discovery (DNS-SD) global

Emerge

Distcc поставляется с графическим монитором для отслеживания заданий, отправляемых компьютером на компиляцию. Данный монитор включается, когда установлен USE-флаг gtk.

После настройки USE-флагов установите пакет sys-devel/distcc:

root #emerge --ask sys-devel/distcc
Важно
Убедитесь, что sys-devel/distcc установлен на все участвующие в распределённой компиляции компьютеры.

Конфигурация

Сервис

Выполните следующие инструкции для того чтобы distccd запускался автоматически.

OpenRC

Отредактируйте /etc/conf.d/distccd и убедитесь, что с помощью директивы --allow разрешены только доверенные клиенты. Для усиления безопасности можно также добавить директиву --listen, сообщив с её помощью демону distccd, на каком IP ожидать соединений (для систем с несколькими адресами). Подробнее о безопасности в distcc можно почитать в Distcc security notes.

Следующий пример разрешает distcc клиентам, работающим на 192.168.0.4 и 192.168.0.5, подключатся к локально запущенному серверу distccd:

Файл /etc/conf.d/distccdРазрешение некоторым клиентам подключатся к distccd
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distccd.log -N 15 --allow 192.168.0.4 --allow 192.168.0.5"
Важно
Использовать --allow и --listen — важно. Обратитесь к man-странице distccd или указанному выше документу по безопасности для получения дополнительной информации.

Теперь запустите демон distccd на всех участвующих компьютерах:

root #rc-update add distccd default
root #rc-service distccd start

systemd

Отредактируйте файл /etc/systemd/system/distccd.service.d/00gentoo.conf для добавления доверенных клиентов в CIDR формате. Пример ниже добавляет все IP-адреса из диапазона 192.168.1.xxx:

Файл /etc/systemd/system/distccd.service.d/00gentoo.confНастройка ALLOWED_SERVERS
Environment="ALLOWED_SERVERS=192.168.1.0/24"
Заметка
Имя "ALLOWED_SERVERS" сильно запутывает, так как на самом деле оно относится к клиентам, которым разрешено подключаться к локальному серверу distcc. Тем не менее именно эта переменная используется в сервисе distccd как значение для --allow option. Смотрите файл /usr/lib/systemd/system/distccd.service для более подробной информации.

Перезагрузите unit-файлы после изменений:

root #systemctl daemon-reload

Включите автозагрузку distccd и запустите сервис:

root #systemctl enable distccd
root #systemctl start distccd

Определение участвующих хостов

Для задания списка хостов используйте команду distcc-config.

В следующем примере показан список определения хостов. Вариантов из первой и второй строки в большинстве случаев достаточно. В последнем используется (число) /limit синтаксис, чтобы сообщить distcc о максимально возможном количестве задач, которые можно запустить на этом узле. Подробнее о синтаксисе, использованном в третьей и четвертой строках, можно прочитать в man-странице distcc.

Код Примеры задания хостов
192.168.0.1          192.168.0.2                       192.168.0.3
192.168.0.1/2        192.168.0.2                       192.168.0.3/10
192.168.0.1:4000/2   192.168.0.2/1                     192.168.0.3:3632/4
@192.168.0.1         @192.168.0.2:/usr/bin/distccd     192.168.0.3

Есть также несколько других методов для настройки хостов. За подробностями обратитесь к distcc man-странице man distcc.

Если локальная машина должна участвовать в компиляции, поместите localhost в список хостов. Наоборот, если локальная машина не должна участвовать в компиляции, не включайте её в список хостов. Использование localhost на медленной машине может, как ни странно, замедлить процесс. Всегда проверяйте влияние настроек на производительность.

Настроим distcc для компиляции на хостах из первой строчки примера:

root #/usr/bin/distcc-config --set-hosts "192.168.0.1 192.168.0.2 192.168.0.3"

Также, distcc поддерживает режим "pump" через вызов команды pump. Такой режим может значительно сократить время сборки при компиляции нескольких файлов параллельно. Он кэширует нужные заголовочные файлы перед компиляцией на сервере, и, как следствие, не требуется повторная загрузка и обработка этих файлов.

Чтобы настроить хост для работы в режиме pump, добавьте суффикс ,cpp,lzo в определение хостов. Для режим pump необходимы оба флага cpp и lzo (независимо от того, какие файлы будут компилироваться C или C++).

root #/usr/bin/distcc-config --set-hosts "192.168.0.1,cpp,lzo 192.168.0.2,cpp,lzo 192.168.0.3,cpp,lzo"

Использование

С Portage

Весьма легко настроить Portage для работы с distcc. Речь идет о включении функции distcc, а также о настройки подходящего количества одновременно выполняемых задач (так как distcc увеличивает доступное количество ресурсов для компиляции).

Установите переменные MAKEOPTS и FEATURES как показано ниже.

Общепринятая стратегия

  • установите N в удвоенное значение от всех (локальных + удалённых) ядер CPU + 1,
  • установите M число равное количеству локальных ядер CPU.

Использование -lM в переменной MAKEOPTS предотвращает запуск чрезмерно большого количества заданий в случаях, когда некоторые distcc хосты кластера недоступны (увеличивая количество одновременных заданий для других систем) или когда ebuild настроен так, что устанавливаемый пакет запрещает удаленную компиляцию (например, gcc). Это достигается за счет отказа начинать новые задачи компиляции, если нагрузка на систему становится равной M или выше.

Файл /etc/portage/make.confУстановка переменных MAKEOPTS и FEATURES
# Замените N и M на подходящие значения, как писалось ранее в статье
MAKEOPTS="-jN -lM"
FEATURES="distcc distcc-pump"
Заметка
Установка значения network-sandbox в переменной FEATURES на клиенте, по видимому, не позволяет клиенту передавать данные компиляции на другие сервера, так как это значение блокирует сетевое взаимодействие. Убедитесь, что это значение не установлено (отсутствует) или отключено (-network-sandbox).
Заметка
Режим pump в distcc может сильно сократить время сборки для больших пакетов. Более подробную информацию смотрите в разделе определение участвующих хостов.

Например, если distccd запущен на двух четырехъядерных хостах, а локальный компьютер оснащен двухъядерным процессором, то переменная MAKEOPTS может выглядеть так:

Файл /etc/portage/make.confПример MAKEOPTS для 1 двухъядерного (локального) и 2 четырёхъядерных (вспомогательных) компьютеров
# 2 удалённых хоста с 4 ядрами каждый = 8 удалённых ядер
# 1 локальный хост с двумя ядрами = 2 локальных ядра
# общее количество ядер — 10, N = 2*10+1 и M=2
MAKEOPTS="-j21 -l2"

CFLAGS и CXXFLAGS

Не используйте -march=native в переменных CFLAGS и CXXFLAGS файла make.conf. Если march установлен в native, то distccd не сможет распределить работу по другим машинам. Подходящее значение для march можно получить с помощью следующей команды:

user $gcc -v -E -x c -march=native -mtune=native - < /dev/null 2>&1 | grep cc1 | perl -pe 's/^.* - //g;'

Подробности можно найти на странице Inlining -march=native for distcc.

A GCC bug has recently been fixed in the 8.0 dev tree which facilitates a more reliable and succinct mechanism for extrapolating appropriate machine flags. The fix has been backported to the 6 and 7 branches and should be released fairly soon. Some processing is still required and a script can be found in the distccflags repo, or via wget:

Предупреждение
Downloading scripts and executing them without any validation is a security risk. Before executing such scripts, take a good look at what they want to accomplish and refrain from executing it when the content or behavior is not clear and purposeful.
user $chmod +x distccflags
user $./distccflags -march=native

С automake

Иногда это проще настройки Portage. Всё, что нужно сделать, это обновить переменную PATH, добавив /usr/lib/distcc/bin/ перед каталогом, содержащим gcc (/usr/bin/). С одной оговоркой. Если используется ccache, то нужно поместить путь к distcc после пути к ccache:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

Поместите это в пользовательский ~/.bashrc или его эквивалент, чтобы переменная PATH устанавливалась при каждом входе пользователя в систему, либо задайте ее глобально через файл /etc/env.d/.

Вместо вызов одного make, добавьте -jN (где N — целое число). Значение N зависит от сети и используемых для компиляции компьютеров. Эвристический подход к определению правильного значения N упоминался ранее в этой статье.

Для bootstrap

Для использования distcc для bootstrap (то есть скомпилировать рабочие toolchain перед установкой оставшейся части системы) требуются некоторые дополнительные шаги.

Шаг 1: настройка Portage

Загрузите новую машину с Gentoo Linux LiveCD и следуйте инструкциям по установке, учитывая инструкции по начальной сборке (bootstrapping) в FAQ по Gentoo. Затем настройте Portage для использования distcc:

Файл /etc/portage/make.confНастройка Portage для использования distcc
FEATURES="distcc"
MAKEOPTS="-jN"

Также, обновите переменную PATH в установочной сессии:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

Шаг 2: установка distcc

Установите sys-devel/distcc:

root #USE='-*' emerge --nodeps sys-devel/distcc

Шаг 3: настройка distcc

Запустите distcc-config --install для настройки distcc; замените в примере host# на IP-адреса или имена хостов, принимающих участие в компиляции.

root #/usr/bin/distcc-config --set-hosts "localhost host1 host2 host3 ..."

Distcc теперь настроен для bootstrap! Продолжайте следовать соответствующим инструкциям по установке и не забудьте запустить emerge distcc после запуска emerge @system. Это нужно, чтобы убедиться, что все необходимые зависимости установлены.

Заметка
В процессе начальной установки (bootstraping’а) и выполнения emerge @system distcc может не использоваться. Это ожидаемое поведение: некоторые файлы ebuild плохо работают с distcc, поэтому distcc отключён в них преднамеренно.

Дополнительно

У программы distcc есть множество дополнительных возможностей и приложений, помогающих работать в окружении distcc.

Утилиты для мониторинга

Distcc поставляется с двумя инструментами мониторинга. Текстовая утилита для мониторинга собирается всегда и называется distccmon-text. Интерфейс поначалу может смутить, но на самом деле использовать его очень просто. Если запустить программу без параметров, она просто запустится однократно. Однако, если передать ей в качестве параметра число N, то информация будет обновляться каждые N секунд.

user $distccmon-text 10

Другая утилита для мониторинга включается с помощью USE-флага gtk. Она основана на GTK+, запускается в окружении X и достаточно приятна. В Gentoo, чтобы избежать путаницы, GUI-монитор переименован в distccmon-gui (оригинальное название — distccmon-gnome).

user $distccmon-gui

Чтобы наблюдать за тем, как Portage использует distcc, запустите:

root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-text 10
root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gui
Важно
Если каталог distcc находится где-нибудь в другом месте, измените переменную DISTCC_DIR соответствующим образом.

Трюк: задайте DISTCC_DIR в переменном окружении:

root #echo 'DISTCC_DIR="/var/tmp/portage/.distcc/"' >> /etc/env.d/02distcc

Теперь, обновите окружение:

root #env-update
root #source /etc/profile

И наконец, запустите графическую оболочку приложения:

root #distccmon-gui

SSH для взаимодействия

В настройке distcc через SSH есть подводные камни. Во-первых, сгенерируйте ключевую пару SSH без пароля. Учтите, что Portage компилирует программы из-под пользователя portage (по умолчанию как root, если не включена FEATURES="userpriv"). Домашний каталог пользователя portage — /var/tmp/portage/, поэтому ключи должны храниться в /var/tmp/portage/.ssh/.

root #ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa

Во-вторых, сделайте для каждого хоста раздел в файле конфигурации SSH:

Файл /var/tmp/portage/.ssh/configРазделы для хостов
Host test1
    HostName 123.456.789.1
    Port 1234
    User UserName
 
Host test2
    HostName 123.456.789.2
    Port 1234
    User UserName

Отправьте публичный ключ на все ноды, участвующие в компиляции:

root #ssh-copy-id -i /var/tmp/portage/.ssh/id_rsa.pub UserName@CompilationNode

Убедитесь также, что каждый из хостов есть в файле known_hosts:

root #ssh-keyscan -t rsa <compilation-node-1> <compilation-node-2> [...] > /var/tmp/portage/.ssh/known_hosts

Измените владельца так:

root #chown -R portage:portage /var/tmp/portage/.ssh/

Чтобы настроить хосты test1 и test2, выполните:

root #/usr/bin/distcc-config --set-hosts "@test1 @test2"

Обратите внимание на знак @, с его помощью в distcc указываются ssh-хосты.

Наконец, сообщите distcc какой бинарный файл SSH нужно использовать:

Файл /etc/portage/make.conf
DISTCC_SSH="ssh"

Если взаимосвязь distcc осуществляется через SSH, нет нужды запускать distccd init-скрипт на хостах.

Тестирование

Чтобы протестировать работу distcc напишите простую Hello distcc программу и запустите distcc в подробном режиме (verbose), чтобы убедится, что взаимосвязь между хостами distcc работает хорошо.

Файл main.c
#include <stdio.h>
 
int main() {
    printf("Hello distcc!\n");
    return 0;
}

Далее, включите подробный режим, скомпилируйте программу с помощью distcc и слинкуйте сгенерированный объектный файл в исполняемый:

user $export DISTCC_VERBOSE=1
user $distcc gcc -c main.c -o main.o # or 'pump distcc <...>'
user $gcc main.o -o main
Заметка
Замените команду distcc на команду pump distcc, чтобы использовать режим pump.

There should be a bunch of output about distcc finding its configuration, selecting the host to connect to, starting to connect to it, and ultimately compile main.c. If the output does not list the desired distcc hosts, check the configuration.

Наконец, проверьте, что скомпилированная программа работает хорошо. Чтобы протестировать все хосты, перечислите все хотсы компиляции в файле hosts.

user $./main
Hello distcc!

Устранение проблем

Следующий раздел может помочь в решении проблем, если такие встречаются при использовании distcc.

ERROR: failed to open /var/log/distccd.log

По состоянию на 22 января 2015 года файл distccd.log в /var/log/ не правильно создается. По-видимому это затрагивает только версию 3.1-r8 distcc. Эта ошибка еще решается (смотрите bug #477630). Ее можно решить самостоятельно, создав файл журнала и назначив ему правильного владельца. После этого перезапустите демон distccd:

root #mkdir -p /var/log/distcc
root #touch /var/log/distcc/distccd.log
root #chown distcc:daemon /var/log/distcc/distccd.log

Затем, в конфигурационном файле distccd, который располагается в /etc/conf.d/distccd, измените /var/log на каталог distcc, который был создан ранее:

Файл /etc/conf.d/distccdИзменение пути для лога
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distcc/distccd.log -N 15

Наконец, перезапустите сервис distccd:

root #/etc/init.d/distccd restart

Некоторые пакеты не используют distcc

Можно заметить, что сборка некоторых пакетов не распределяется по хостам (и не происходит параллельно, т. е. в несколько процессов). Такое может происходить, когда Makefile пакета не поддерживает параллельные операции, или мейнтейнер ebuild’а явно отключил их, чтобы избежать известных проблем.

Иногда distcc может вызывать сбой при компиляции пакета. Если такое происходит, пожалуйста, сообщите об этом.

Смешанные версии GCC

Если на взаимодействующих хостах разные версии GCC, то велика вероятность возникновения очень странных проблем. Решение — установить на все хосты одну версию GCC.

После недавных обновлений Portage стал использовать ${CHOST}-gcc (минус gcc) вместо gcc. Это значит, что совместное использование i686-машин с машинами других типов (i386, i586) может вызвать проблемы со сборкой. Обходным решеним может быть запуск:

root #export CC='gcc' CXX='c++'

Можно задать переменные CC и CXX в /etc/portage/make.conf в списком значений из команды выше.

Важно
Так вы явно переопределите некоторую часть поведения Portage, что может привести к странным результатам в будущем. Делайте так, только если использование разных CHOST’ов неизбежно.
Заметка
Просто установленной в слот подходящей версии gcc недостаточно. Portage использует distcc как замену для компилятора, который обозначен в переменной CHOST (например x86_64-pc-linux-gnu), а distccd вызывает его точно с таким же именем. Правильная версия gcc должна быть установлена в качестве системного компилятора на всех хостах, используемых для компиляции.

-march=native

GCC, начиная с версии 4.3.0, поддерживает параметр -march=native, который включает автоматическое определение CPU, на котором запущен GCC, и оптимизаций, которые стоит включить для него. Это создает проблемы при использовании distcc, так как допускает смешивание оптимизированного для разных процессоров кода. К примеру, запуск distcc с -march=native на системе с процессором AMD Athlon и на другой системе с процессором Intel Pentium приведет к смешиванию кода, скомпилированного на обоих процессорах.

Обратите внимание на следующее предупреждение:

Предупреждение
Не используйте -march=native и -mtune=native в переменных CFLAGS и CXXFLAGS файла make.conf при компиляции с помощью distcc.

See the CFLAGS and CXXFLAGS section and Inlining -march=native for distcc for more information.

Получение более подробного вывода в логах emerge

Можно получить более подробное журналирование, если включить подробный режим. Этого можно добиться, если добавить DISTCC_VERBOSE в /etc/portage/bashrc:

Файл /etc/portage/bashrcВключение подробного журналирования
export DISTCC_VERBOSE=1

Подробный журнал потом можно найти в /var/tmp/portage/$CATEGORY/$PF/temp/build.log.

Keep in mind that the first distcc invocation visible in build.log isn’t necessary the first distcc call during a build process. For example a build server can get a one-minute backoff period during the configuration stage when some checks are performed using a compiler (distcc sets a backoff period when compilation on a remote server failed, it doesn’t matter whether it failed on local machine or not).

Поищите в каталоге /var/tmp/portage/$CATEGORY/$PF/work/, что изучить такую ситуацию. Найдите другие журналы или вызовите make непосредственно из рабочего каталога.

DISTCC_SAVE_TEMPS — это еще одна интересная переменная. Когда она установлена, сохраняется стандартный поток вывода/ошибок с удаленного компилятора, который использует Portage, в файлы расположенные в каталоге /var/tmp/portage/$CATEGORY/$PF/temp/.

Файл /etc/portage/bashrcСохранение временного вывода
export DISTCC_SAVE_TEMPS=1

Смотрите также

  • Руководство по кросс-компиляции с distcc расскажет как компилировать программу на компьютере одной архитектуры для выполнения ее на другой архитектуре при помощи distcc. Это может быть так же просто, как компилировать на Athlon (i686) для выполнения на K6-2 (i586), или компилировать на SPARC для выполнения программы на PowerPC.

Внешние ресурсы


This article is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Lisa Seelye, Mike Gilbert (floppym), Erwin, Sven Vermeulen (SwifT), Lars Weiler, Tiemo Kieft, and Joshua Saddler (nightmorph)
They are listed here as the Wiki history does not allow for any external attribution. If you edit the Wiki article, please do not add yourself here; your contributions are recorded on the history page.