Files
hse-2026/materials/04-group-comm/seminar/gossip/readme.md
T
2026-10-01 22:08:30 +03:00

12 KiB
Raw Blame History

Знакомство с gossip

В этой работе сравним push, pull и push-pull в симуляторе на AnySystem. Перед каждым экспериментом запишите прогноз, затем сравните его с результатом и объясните различия.

Подготовка

Откройте корень репозитория курса в IDE. Для VS Code с Pylance стаб AnySystem подключается через настройки проекта. Для другой IDE укажите папку typings в корне репозитория как каталог стабов. Стаб содержит объявления и документацию API; реализация доступна в исходнике AnySystem 0.3.0.

При запуске симулятора локально или в Docker Python-модуль встроен в AnySystem. Отдельный anysystem.py и настройка PYTHONPATH не нужны.

Из корня репозитория перейдите в каталог лабораторной:

cd materials/04-group-comm/seminar/gossip

Если установлен Rust, соберите текущую версию симулятора:

cargo install --locked --path simulator
distsys-gossip -h

Для запуска в Docker соберите образ из текущего кода:

docker build -t distsys-gossip-seminar simulator
docker run --rm -t -v ./:/impl distsys-gossip-seminar -h

Далее заменяйте distsys-gossip на docker run --rm -t -v ./:/impl distsys-gossip-seminar. Команды выполняются из каталога gossip. Если оболочка не передаёт относительный путь монтирования, в PowerShell используйте --mount "type=bind,source=$($PWD.Path),target=/impl" вместо -v ./:/impl.

Модель и метрики

Распространяется одно сообщение, изначально известное процессу 0. Все узлы знают состав группы и выбирают случайных соседей, исключая себя. Сетевая задержка равна 0,1 единицы модельного времени, периодический таймер срабатывает через 1. В этих экспериментах узлы не отказывают; можно задавать вероятность потери сетевого сообщения.

Основные параметры:

Параметр Значение
-i Файл реализации
-n Число узлов, не меньше 2
-f Число соседей для одного обмена, от 1 до n - 1
-d Вероятность потери сообщения, от 0 до 1
-s Seed для воспроизведения запуска
-t Положительный лимит модельного времени
-q Завершить симуляцию при обнаружении полного охвата

В таблице вывода time — модельное время, delivered — число узлов, доставивших сообщение приложению, stopped — число узлов, прекративших периодические инициативные обмены, messages — накопленное число сетевых отправлений, включая запросы и ответы. STOPPED не означает выключение узла: он сохраняет информацию и может отвечать на входящие запросы.

Симулятор выводит статистику после продвижения времени интервалами по 1. В итоговой строке First full-coverage sample указаны время первой напечатанной строки с delivered = n и число отправлений к ней. Обозначим их t_all и M_all. Это показатели с дискретностью вывода, а не точные мгновение последней доставки и число отправлений в это мгновение.

Строка Finished объясняет завершение:

  • full coverage (--quick-mode) — сработало условие -q;
  • no pending events — в симуляции не осталось событий;
  • time limit reached — достигнут лимит времени.

Если условия совпали, отсутствие событий проверяется первым, затем полный охват с -q, затем лимит. Строка Final state всегда показывает фактический охват и трафик к завершению. Если полного охвата не было, выводится Full coverage: not reached. Завершение по лимиту не означает, что алгоритм сам остановился.

1. Сравнение push, pull и push-pull

Изучите push.py, pull.py и push_pull.py. В push информированный узел посылает данные соседям. В pull неинформированный узел запрашивает их; после получения перестаёт инициировать запросы, но продолжает отвечать другим. В push-pull запрос сам может нести информацию, а информированный получатель отвечает своими данными.

До запуска ответьте:

  1. Какой подход быстрее распространит информацию в начале, когда источник один?
  2. Какой подход быстрее найдёт последних неинформированных участников?
  3. Должен ли самый быстрый вариант отправить меньше всего сообщений?

Запустите алгоритмы с одинаковыми параметрами:

distsys-gossip -i push.py -n 1000 -f 2 -s 123 -d 0 -t 60 -q
distsys-gossip -i pull.py -n 1000 -f 2 -s 123 -d 0 -t 60 -q
distsys-gossip -i push_pull.py -n 1000 -f 2 -s 123 -d 0 -t 60 -q

Заполните таблицу. Если полного охвата нет, укажите достигнутый охват и число отправлений к лимиту вместо t_all и M_all.

Алгоритм n f d seed t_all M_all Причина завершения
push 1000 2 0 123
pull 1000 2 0 123
push-pull 1000 2 0 123

Сравните начальный рост и доставку последним узлам. Объясните результат через действия отправителей. Флаг -q использует глобальную статистику симулятора: сами процессы не узнают, что сообщение уже получили все. В push и push-pull периодические обмены без этого ограничения продолжаются.

2. Изменение одного параметра

Выберите один алгоритм и сравните каждый следующий запуск с его базовым результатом. В командах замените push.py на выбранный файл.

Сначала увеличьте fanout с 2 до 4:

distsys-gossip -i push.py -n 1000 -f 4 -s 123 -d 0 -t 60 -q

Затем верните fanout 2 и добавьте вероятность потери 0,2:

distsys-gossip -i push.py -n 1000 -f 2 -s 123 -d 0.2 -t 60 -q

Для каждого запуска сначала запишите прогноз, затем добавьте строку результатов в таблицу. Как изменились время и цена охвата? Почему больше контактов за раунд не обязательно означает пропорционально меньшую задержку? Что можно заключить, если охват не достигнут за 60 единиц времени?

Один запуск показывает конкретное выполнение. При наличии времени повторите сравнение на seed 124 и 125. Одинаковый seed воспроизводит запуск данной реализации; разные алгоритмы расходуют случайные числа по-разному, поэтому их контакты и потери не обязаны совпадать. Если меняете лимит времени, используйте один лимит для сопоставляемых запусков.

3. Полный охват и прекращение обменов

Изучите push_pull_stop.py и запустите его без -q:

distsys-gossip -i push_pull_stop.py -n 1000 -f 2 -s 123 -d 0 -t 60

При повторном получении информации через got_info узел с вероятностью 0,8 отменяет свой таймер и выдаёт STOPPED. Он продолжает отвечать на запросы. Неинформированные узлы продолжают искать данные; остановка таймера у держателя не удаляет доступную копию.

Выпишите показатели первой строки с полным охватом и показатели завершения. Совпадают ли они? Какой трафик возникает между ними? Подтвердите по Finished, что запуск завершился из-за отсутствия событий, а не по лимиту.

Для сравнения стоимости распространения используйте M_all всех четырёх вариантов. Число отправлений к концу запуска с остановкой — другая метрика. Итоговые max/min/mean отправлений по узлам также относятся к концу запуска, который может наступить позже полного охвата.

Обсуждение

  • Какие оптимизации могут уменьшить число повторных передач?
  • Почему успешный запуск при потерях не доказывает Uniform Agreement при отказах процессов?
  • Какая дополнительная информация и логика понадобятся для нескольких сообщений и причинного порядка доставки?

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