[devel] IХ. Алгоритмы работы сборочницы. O commit. ч.1

Igor Vlasenko vlasenko на imath.kiev.ua
Вт Апр 2 22:30:45 MSK 2019


On Sun, Mar 24, 2019 at 03:40:02AM +0300, Alexey Tourbin wrote:
> Ну это большой отход от того, как сейчас сборочная система работает.
> Она работает как последовательная серия стадий, последняя стадия -
> commit (отсюда и название "task run", проиграть все стадии). При такой
> схеме сначала идет сборка пакетов, а потом - генерация нового
> репозитория и проверка на unmets. А при вашей схеме получается
> шиворот-навыворот: сначала надо сгенерировать репозиторий и проверить
> unmets, а потом только собирать пакеты, а потом еще раз сгенерировать
> репозиторий и проверить unmets. 

Здесь, похоже, некоторое недопонимание.
Я не предлагал сначала сгенерировать и проверить unmets,
потом собирать. Ведь предполагается, что
сгенерировать репозиторий и проверить unmets
это уже было сделано во время предыдущего commit.

Я предлагал отвязать выпуск нового репозитория
(commit check+commit) от build+postbuild check+commit check.
Т.е. собираем (build),
выполняем тесты над пакетами (postbuild check),
генерируем временный репозиторий на хардлинках и с ним
делаем commit check (проверить unmets, bad elf symbs и т.д.)
После чего собранный и проверенный task становится в очередь
на commit.

Понятно, что на этапе commit мы опять генерируем временный
репозиторий и с ним опять повотряем commit check.
Где здесь выгода?
1) если build происходил на предыдущем состоянии
репозитория, т. е. как работает последовательная сборочница,
то результаты commit check для нас не устарели
и мы можем просто пропустить commit check, т.е.
потерь производительности в последовательном режиме на
commit check не будет.
2) Для тасков build+postbuild check+commit check
запускается параллельно. Поэтому для человека
время ожидания от постановки в очередь снижается
и существенно, так как ему не нужно ждать, когда
соберутся 20 тасков последовательно, а нужно ждать,
когда соберутся 20 тасков параллельно (что дает
время как 1 самый долгий таск) + время на 21 коммит.

Плюс коммиты тоже можно ускорять параллелизацией,
я об этом писал в ранних письмах.

Итог - наблюдаемое время от заливки до выхода в Сизиф
резко упадет - для человека сборочница станет работать
быстрее, и железо будет задействовано более эффективно,
за счет параллелизации процессов.

> Не то чтобы это очень серьезный
> аргумент против, но это уже как-то по другому мыслится. Также эта
> схема более капризна/требовательна к валидности предыдущих результатов
> сборки. Сейчас кеширование работает локально, "по месту" (в случае
> чего пойдет повторная сборка). В новой схеме надо управлять
> суперпозицией состояния "какие сабтаски собрались и прошли все
> проверки, чтобы их второй раз не песочить" (напр. если какой-то
> сабтаск добавился посередине, то последующие сабтаски надо
> сбрасывать). Либо же может быть упрощенный вариант: более или менее
> любое изменение в конфигурации сабтасков сбрасывает имеющиеся
> результаты сборки у всех сабтасков.

Сейчас сборочница, как понимаю, сбрасывает имеющиеся
результаты сборки у сабтасков, если сборочное окружение изменилось.
Почему бы пока не оставить старое поведение?
Конечно, для сабтасков можно дополнительно пробовать
различные оптимизации, но разговор о них уведет нас
в сторону от главной темы, разрыва связки rebuild+commit.


> Вы преувеличиваете. Сборочница не захлебнется. Прогресс гарантируется
> тем, что один из контендеров всегда коммитится. Остальные уходят на
> второй круг. В старых книжках про Unix именно так описан планировщик
> процессов: пробуждается несколько процессов, один идет на исполнение,
> остальные засыпают до следующего раза. Аналогично pthread_cond_signal
> может разбудить несколько тредов (поэтому pthread_cond_wait надо
> заворачивать в цикл). В общем, вы жалуетесь на схему, когда ресурс
> достается только одному, а остальным - на колу мочало. Но это
> распространенная схема.

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

Когда это время исчисляется часами, люди готовы терпеть,
когда сутками - недовольны, когда неделями - хотят революцию.

Кроме того, нужно учесть, что сборочница многоаккаунтовая,
и очередь дополнительно разбита по аккаунтам.
Соответственно, у более активных пользователей проблемы
постоянно (сегодня, к примеру, я еще жду пакет, залитый в
сборочницу полсуток назад, и это для моих пакетов быстро),
у менее активных проблемы начинаются только при авралах,
наподобие идущего сейчас бранчевания.
сборочницы и структура недовольства получается неоднородная,
прямо как в нелинейной civilization:
Сначала 100 довольны. Потом 5 недовольны, 95 довольны.
потом 1 хочет революцию, 9 недовольны, 90 довольны, и т.д.
 
> Теперь поближе к цифрам. Стоимость повторного проигрывания задания на
> самом деле состоит из двух частей: константная цена для любого
> задания, порядка минуты, плюс переменная цена в зависимости от
> количества пакетов, по несколько секунд на пакет. Если в задании много
> пакетов, то переменная цена доминирует, и шансы такого задания
> закоммититься резко падают (любое другое задание с одним пакетом его
> обгонит). Старвейшон это называется по-научному (несправедливое
> лишение доступа к ресурсу). Можно попытаться защитить ресурс для
> заданий, которые слишком много раз подряд уходят на второй круг.
> Например, можно взять эксклюзивный лок на репозиторий. Но если
> начинается повторная сборка пакетов, то эксклюзивный лок надо
> отпустить! Потому что остальные задания стопорятся на неопределенно
> долгое время, а не "несколько секунда на пакет". Справедливость - дело
> такое. (Тут часть проблемы чисто техническая - сложно это на шелле
> изобразить, взять лок в одном скрипте и отпустить его в другом.)
> 
> В общем мне конечно не нравится что большие задания тяжело
> закоммитить. Но это не значит, что вся схема негодная. Мне кажется,
> что по крайней мере для маленьких заданий пропускной способности
> должно хватать. Зачем рекордных показателей добиваться мне не понятно.

Дело не в том, чтобы рекордных показателей добиваться.
Сейчас, если заливать по нескольку пакетов в сутки,
то сборочницей вполне можно пользоваться.
Но там обратная связь - чем больше пользуешься,
тем хуже обслуживание, которое в первую очередь
задевает наиболее активных майнтайнеров.
Поэтому если кто-то из читателей скажет,
что у него все в порядке, это будет как в анекдоте,
когда бабушка говорит внучку, что ей плохо,
а тот в ответ "А я себя чувствую просто великолепно".

Если же заливать большой таск или много маленьких,
то сборочница и вовсе поворачивается задней частью к пользователю.
Ждать заданий неделями приходилось достаточно часто,
чтобы мне это опротивела эта полная ... Старвейшон, как это
называется по-научному?.

Да, не всем это нужно, но мне не отвертеться,
так как на мне от пятой до четверти Сизифа
(по acl трудно сосчитать, так как тот же
perl по факту за мной, но остался со старыми acl).
Чтобы более комфортно работать со сборочницей,
можно попытаться раздать 9/10 своих пакетов в Сизифе,
чтобы свести число поддерживаемых пакетов до среднего.
тогда поддерживающие эти пакеты майнтайнеры
будут заливать их под своими разными аккаунтами,
чтобы плохело всем равномерно.

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

А по поводу рекордных показателей -- они выйдут сами собой.
Современное железо любит параллелизуемые алгоритмы.
Это как заменить в скрипте бекапов 10-летней давности
gzip на pigz и тут же получим рекорд - скрипт отработает
за 20 сек. вместо 5 мин.

> > К примеру, по такой логике такие пакеты, как
> > янв  4 2005 xlhtml-0.5.1-alt2.src.rpm
> > десятилетиями каждый день получают новые поводы, чтобы
> > пересобраться, но почему-то до сих пор не пересобраны.
> >
> > Чем 2 пакета, собранные за 5 минут до прихода в Сизиф
> > новой libfoo, хуже, чем 200 пакетов, собранных еще раньше?
> > Ничем не хуже. Даже лучше с точки зрения необходимости
> > пересборки, так как собраны на более свежем Сизифе.
> 
> Вы (в частности) хотите сказать, что вот мы так скрупулезно
> отслеживаем влияние пакетов в пределах задания, а когда пакеты все же
> попадают в репозиторий, то последующие потенциальное влияние на
> пересборку пакетов уже никак не отслеживается. У меня когда-то была
> идея сделать "метарепозиторий", в котором как раз бы отслеживались все
> промежуточные состояние тестовых пересборок, даже если результат
> пересборки отбрасывается. Но что-то до ума я это дело не довел, может
> потому что выпивал много. Эх, как там писал Ерофеев, вставай Модест
> Петрович, садись дописывать свою божественную оперу Хованщина. А
> Модесту Петровичу без выпивки оперу писать вдохновения нету. А как
> выпьет, так уж не до оперы.

Да, это хотел сказать.
Спасибо, что потратили время прочитать и разобраться.
 
> Все-таки слабое место в вашей схеме -  это суперпозиция валидности при
> кешировании. Вы вот пишете, что таск может собираться на каком-либо
> старом состоянии репозитория R_k. Если максимально кешировать
> результаты сборки, то получится, что таск собирался на состояниях
> $R_{k_1},$R{k_2},\ldots$. То есть таск может видеть разные состояние
> репозитория. В результате пакеты в таске могут собраться с разными
> версиями библиотек!

В "если максимально кешировать" - ключевое слово
"если". Сейчас сборочница не производит такого максимального
кеширования, и я не предлагал его внедрять, но и возражать
не буду, если в будущем кто-то это корректно реализует (с
учетом концепции воспроизводимости сборки, которую выдвинул
Дмитрий, для этого в архиве в собранном taskе нужно будет
хранить информацию, на каком репозитории какой сабтаск был
собран).
Для начала достаточно старой логики, когда результаты
кеширования валидны до тех пор, пока не изменилось сборочное
окружение.

Я в первую очередь предлагаю убрать из commit принудительную
сериализацию уже реализованной параллельной сборки.

Работает эта сериализация параллелизации следующим образом:
отправляем в Сизиф в очередь 20 пакетов в состоянии AVAITING1.
Пока они стоят в очереди на commit, они параллельно
собираются и переходят в состояние AVAITING1.2.
Когда у них доходит очередь до commit, сборочница
отправляет их на пересборку еще раз, не потому,
что пакеты не прошли проверку целостности (unmets,
bad elf symbols, ...) а на всякий случай,
из-за изменения их сборочного окружения.
Это
1) превращает сборочницу в последовательную,
крайне неэффективно использующую железо и искусственно
торможенную.
2) чтобы от пересборки пакетов из-за изменения
их сборочного окружения был какой-то эффект,
ее нужно делать для всех затронутых пакетов,
в том числе пакетов, уже находящихся в Сизифе,
причем лучше делать отдельным фоновым роботом-
пересборщиком, и процесс пересборки оттягивать,
чтобы не раздуть архив Сизиф.

Попытка встраивания этой пересборки в сборочницу
заявленных целей пересборки не достигает,
является логической ошибкой,
которая проявляется как искусственно
созданные тормоза в работе сборочницы.

-- 

I V


Подробная информация о списке рассылки Devel