В одном нецентральномотдаленном регионе нашей необъятной страны как-то раз проходил очередной региональный этап Всероссийской олимпиады школьников по информатике и программированию. До 2014 года всё было хорошо, проводили олимпиаду на старой системе, написанной в далеких 2004 годах очень одаренным программистом, на Delphi. С тех пор его никто не менял — работал, ну и ладно. В 2014 году решили попробовать ejudge. Поднимать всё с исходников не стали, решили взять готовое, образ для виртуальной машины. Всё было хорошо, все работало.
Но тут наступил 2015 год, в котором некоторые пункты проведения олимпиады немножко, совсем чуть-чуть поменяли, и нужные «человеки» об этих изменениях узнали только за 1-2 дня до начала…
Тут-то и начинается самое веселое.
Дело в том, что почти все эти изменения касались только нас двоих(я + ripatti).
Я отвечал за сервер (fedora19, ejudge) и его работоспособность, он отвечал за подготовку тестов, конфигурации туров в целом. У него в этом довольно богатый опыт.
Итак, пойду по хронологическому порядку.
21 января, среда
Меня спрашивают, смогу ли я поднять сервер для олимпиады на базе выделенных машин университета, на что я отвечаю отрицательно, ибо времени оставалось мало, и среда для меня может быть незнакомой (думал, что там VMWare, а я только на Virtual Box мог). В общем, я не смог дать гарантию, что всё будет хорошо.
22 января, четверг
Узнаю, что появилось такое понятие, как токены. Это означало лишь одно: решения участников должно проверяться во время тура, а не после. Вспомнив прошлогодний тур, решил, что один сервер всё потянет. В прошлом году же ничего не упало, все сработало, все были довольны. Начал работать над сервером. Привез машину (железо) в стены университета.
Вечером узнаю от напарника, что предыдущая версия ejudge (2.3) не удовлетворяет требованиям. Как раз к этому времени Александр Чернов выложил рабочую версию. Даже специально завел новый репозиторий со всеми настройками пробного тура. Было очень заманчиво, потому что у меня в голове была идея настроить старую версию. Решили собрать новую версию из исходников, так как готового образа не было. Тут начались первые проблемы.
Проблема: как пустить ssh по не 22 порту?
На самом деле, я и сам пытался это сделать, но не смог.
Вырезки из того, что он потом прислал:
в-третьих, настройки ssh-сервера хранятся в /etc/ssh/sshd_config, а не ssh_config, я добавил в первом
Port 22
Port 5000
PermitRootLogin noи все вывесилось как надо:
[root@localhost ssh]# service sshd status
Redirecting to /bin/systemctl status sshd.service
sshd.service — OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
Active: active (running) since Thu 2015-01-22 21:01:38 YEKT; 4min 53s ago
Ур-р-а!
Порт 500 для ssh свободен, я могу к нему зайти.
Но ни гитхаба, ни yum update, ничего…
Точнее, ночью я эти вещи не смог настроить.
В 7 утра позвонил (разбудил напарника), всё рассказал. Проблема стояла в том, что мы тупо не могли скомпилировать исходный код, ибо некотоые библиотеки отсутствовали, я стягивать их нельзя (ssh 5000). Пытался по одному, но там, блин, зависимости, очень хорошие.
Решили создать другой сервер с полными настройками ejudge (3.3) так, чтобы потом не пришлось заходить к серверу (она находилась в серверной, под замком, было проблематично получить физический доступ к машине).
23 января, пятница, начало пробного тура в 16:00
В 9 утра иду сдавать коллоквиум по Функану, декан что-то поставил, не смотрел. Вроде не «неуд».
В 10 часов начинаю собирать новый ejudge параллельно с Артемом. У него это получается чуть быстрее, я же остановился на мелком шаге и перестал дальше думать.
Вторая проблема.
Стягиваем исходный код с гитхаба, запуск.
git clone https://github.com/blackav/ejudge.git
cd ejudge/
./fedora-configure
./configure
make
su #ejudge не умеет sudo
make install
#Вроде теперь надо просто запустить ejudge-control, но:
ejudge-control
Tue Jan 27 01:24:35 2015:info:ej-users 2.3.29, compiled Sat Dec 14 07:58:33 2013
mysql: SELECT config_val FROM config WHERE config_key = 'version' ;
Tue Jan 27 01:24:35 2015:info:ej-super-server 2.3.29, compiled Sat Dec 14 07:58:33 2013
Tue Jan 27 01:24:35 2015:info:configuration file parsed ok
Tue Jan 27 01:24:36 2015:info:ej-jobs 2.3.29, compiled Sat Dec 14 07:58:33 2013
Tue Jan 27 01:24:36 2015:info:ej-contests 2.3.29, compiled Sat Dec 14 07:58:33 2013
Tue Jan 27 01:24:36 2015:info:using files as the new-server database
Да, именно, ejudge-conrtol подцепил старую версию.
Всё заработало, заходим на веб версию — видим старое.
Переименовал папку, где находился старая версия бинарника. При этом преследовал 2 цели: сделать так, чтобы он пропал из путей и сделать бэкап старой версии.
Теперь запускаем заново ejudge-control, который находится в /usr/bin/ejudge-control:
[ejudge@localhost ~]$ ejudge-control start
2015-01-27T19:03:18Z:info:ej-users 3.3.1, compiled 2015-01-23 09:25:21
mysql: SELECT config_val FROM config WHERE config_key = 'version' ;
2015-01-27T19:03:18Z:info:ej-super-server 3.3.1, compiled 2015-01-23 09:25:21
2015-01-27T19:03:18Z:info:configuration file parsed ok
2015-01-27T19:03:19Z:info:ej-jobs 3.3.1, compiled 2015-01-23 09:25:21
2015-01-27T19:03:19Z:info:ej-contests 3.3.1, compiled 2015-01-23 09:25:21
2015-01-27T19:03:19Z:info:using files as the new-server database
Ещё немножко шаманства, и пробный тур готов!
Это мы сказали, когда время было примерно 17:00.
Я побежал с дистрибутивом в серверную. Прихожу, а там экран только потух. Думал, уснул монитор. Всё хуже — только что сисадмин по непонятной мне причине орубил питание у моего железа. Теперь я жду, пока windows server 2008 загрузится, дальше копирую, импортирую в virtual box, запускаю, проставляю статические адреса, настраиваю ssh. Из-за того, что в прошлый раз мне его настраивал мой науч.рук (Юлдашев Артур Владимирович), в этот раз пришлось потратить кучу времени. Усугублялось всё это тем, что в серверной у меня не было возможности погуглить.
Время 17:45, пробный тур почти закончился, у нас сервер до сих пор не встал… Поступают множество звонков — отвечаем, мол, всё, закругляемся, сервер не успеем поднять.
Время 18:00, сервер ещё не встал. Собрались с другими жюри, думаем, как выйти из этой ситуации.
Было решено следующее: Мы с Артемом не спим, допиливаем пробный тур и первый, приготовим всё к 10, с 10:00 по 11:00 запускаем пробный тур, а в 11:00 запускаем 1 тур. Так мы лишились сна на 2 ночь.
Попрощались и поехали домой. Дома стали заново всё настраивать, настроили. К утру всё было готово.
24 января, суббота, 1 тур (официальное расписание)
Начинается пробный тур, и тут мы, наконец, поняли, с чем имеем дело.
В прошлом году была следующая ситуация: участник отправляет исходный код на тестирующую систему, которая, в свою очередь, проверяет только на тестах, которые показаны на примере к задаче. Если посылка их не проходит, то она не становится в очередь для полной проверки. Поэтому наш почетный один сервер спокойно справлялся со всей нагрузкой(всего было 150 участников).
В этом году мы должны были проверять решение сразу на всех тестах. Чтобы участники не злоупотребляли этим, было введено это понятие — токены. Это, так сказать, право посмотреть результат своей посылки. Он был равен 10. То есть, я могу посылать решение задачи сколько угодно раз, но посмотреть смогу лишь 10 раз. Последующие посылки на свой страх и риск.
Пробный тур начался, а у нас задержка сервера уже 15 минут. То есть участник отправляет решение на сервер, а оно там проверяется только через 15 минут. Не испугались мы этого. А зря. Подумали, что пройдет.
Я делаю Reload contest, сбрасываю весь очередь посылок. При этом никому об этом не сообщил. В итоге за 10 минут до конца пробного тура нас снова забрасывают посылками. Тихонько закрываем контест, открываем контест 1 тура.
11:00, 1 тур
Буквально через 15-20 минут приходят несколько посылок, появляется нехорошая очередь. Артем сразу дал понять. В первой задаче, в самой легкой, как ожидалось, всего 48 тестов. Решение есть в лоб, который набирает 50 баллов из 100, а есть хорошее решение, до которого нужно додуматься. Но об этом большинство должно было узнать только после того, как их решение получило TLE. Как вы поняли, одна посылка задачи А, решенная в лоб, занимало у сервера 24 секунды. Таких посылок становилось всё больше и больше, стали поступать вопросы к жюри по поводу времени тестирования. Артем всё грамотно пояснил, отправил сообщение для всех. Но даже при этом, почти каждый отправил хотя бы одно «халявное» решение А. И тут очередь закономерно начал возрастать. Сперва 15 минут, потом резко 45. Все, особенно участники, были обеспокоены, напряжены, недовольны. В первую очередь нами. Артем в это время сидел дома, я был на месте и слышал в свой адрес почти всё, что должен был услышать. Начали думать, нужно как-то попытаться выходить из ситуации. Нашли нужную статью в документации, но не смогли воспользоваться. После этого мы просто закрыли глаза на 30 вопросов и ждали, когда всё это закончится.
Наконец, закончился! Задержка проверки — 1 час. Участник должен был отправить решение за час до конца, чтобы успеть посмотреть протокол проверки.
16:00, иду в актовый зал. Встречаю недовольные глаза. Ещё бы, я только что лишил детей выхода на финал. Как на меня ещё можно было смотреть. С одним очень известным учителем пересекся, рассказал, в чем проблема, какие есть решения — распараллелить. Пожелал мне удачи.
Всем объявили о проблеме, открыто. Сказали, что мы не ожидали таких нагрузок и тому подобное. Сразу же начали думать, искать выход из положения.
Вариант №1. Поставить в каждом дисплейном классе по 1 серверу, в больших классах — по 2. После олимпиады все результаты соберем, проблем с сетью не будет ни у кого, нагрузку можно будет снизить в порядок, что и даст возможность отвечать всем требованиям на 100%. Очевидны изъяны: сейчас суббота, почти все дисплейный классы уже закрыты, в том числе серверная. Серверов у нас под рукой нет, образов 2 тура тоже. Дисплейные классы находятся слишком далеко друг от друга, в 3 корпусах. Про доступ по ssh можно и не говорить. 2 тур начинается в понедельник 9 утра, железно. За утро понедельника такое дело не сделать, ибо нас всего лишь двое.
Вариант №2: подключить вычисляющие узлы к основному серверу. Этот случай идеальный. Ничего не нужно менять в плане организации олимпиады. Единственная проблема — создать эти вычисляющие узлы.
Под рукой тогда ничего не было. 1 звонок — и через час у нас 13 ноутбуков, core-i7, по 8 ГБ ОЗУ. Единственный образ машины, который у меня был — образ пробного тура.
20:00, сидим на кафедре, настраиваем сервер для 1 ноутбука. Позвонили Артему, пусть приезжает, помогает мне всё настроить (я не умел настраивать тур). Вдруг в голову организатора приходит мысль — дом же пустой (жена с внуками прилетает только воскресенье днем), пойдем ко мне, на ночь.
Все довольны, точнее, мы с Артемом. С нами едет ещё один учитель, помогать нам.
25 января, ночь — день
Взяли с собой 7 ноутов, приехали, распаковались. Приготовили нам вкусную еду, и мы, набравшись сил, начали.
Настроили 2-й тур, скинули образ в накопитель и задумались, а может попробовать распараллелить?
Времени много, сил, вроде, тоже.
А теперь самое интересное. Как устроен ejudge.
Есть служба (демон), отвечающий за компиляцию, запуск, тестирование программ — ej-super-run. Данные он берет из /home/judges/, где обычно расположены конфигурационные файлы, тесты, чекеры и присланные решения.
Не знаю, какой именно процесс отвечает за веб-интерфейс, но мы запускали ejudge-control, который запускал всю систему. Вдаваться в подробности не стал.
Под распараллеливанием предлагалось расшарить папку /home/judges/. Причем не важно как — SSHFS, Samba, NFS.
Но для этого нужно собрать заново с определенным ключом рабочие узлы, как их называют в распределенных системах — slaves. Лабораторные работы по ОС включали в себя создание сетевых папок при помощи NFS и Samba. Я с легкостью принялся за самбу и тут же уперся в первую проблему, которую уже лень было решать. бросив его, принялся за NFS. Закономерно было ожидать, что тут я тоже встречу множество проблем. Осталось последнее, более знакомое мне SSHFS. Знакомо потому, что с SSH я как-то дружил, часто работал с ним.
sshfs ejudge@192.168.1.11:/home/judges/ /home/judges/
После этого директория /home/judges/ становится общей с серверным. Для полного удобства можно смонтировать его, но мы этого не стали делать, ибо уже утро.
Если нужно указать другой порт, то следует добавить параметр -p
sshfs -p 5000 ejudge@192.168.1.11:/home/judges/ /home/judges/
В случае с нашим сервером это было актуально.
И, Слава Богу, заработало!
В качестве сервера выбрали один ноут, в качестве slave — другой. Речь идет и виртуальных машинах, поднятых на них.
Через веб интерфейс запустил 2 посылки (с while(true), чтобы выдавал на всех тестах TLE), которую сам же сервер и выполнил, засекли время. Запустили ej-super-run на рабочем узле, снова отправили на перепроверку 2 задачи — счастье.
Рабочий узел подхватил посылку, начал тестировать. Время проверки почти в 2 раза меньше, 30 секунд против 50.
Следующим шагом связали рабочий узел с реальным сервером, ведь теперь 5000 порт нам не страшен.
Начали заливать на остальные ноуты, попутно оптимизируя настройки. Хотели скрипт красивый написать, который легко мог бы прописать все настройки, но, увы — кривые руки на то и кривые, что такие вещи сразу не могут сделать. Все настройки прописывал руками. На сервере остановили процесс ej-super-run, пусть занимается только веб интерфейсом.
Далее мы задумались: на каждом ноуте имеется 4 ядра, 1 рабочий узел может проверять только в однопоточном режиме.
Дай человеку гору золота он ещё одну захочет
Либо мы поднимаем 1 виртаульную машину, даем ему много ресурсов, а в ней распараллеливаем по ядрам, либо просто поднимаем 2 виртуальные машины, по 2 ядра.
Нам было всё равно, насколько ускорялась система — в 2 или 3 раза, если всё равно машин у нас много. Решили остановиться на достигнутом, поднимать по 2 машины на ноуте. Когда все 7 ноутбуков были готовы, мы решили себя наградить сном в 12 часов.
26 января, 08:30
Уже свеженький, в университете, Артем тоже приехал. Достали все 13 ноутов, ребята из «службы по сетям» оперативно обжали провода, настроили сеть, в итоге 12 их них уже были в сети, 13-ый ноут выхода в интернет так и не получил, провод, видимо, был старый. Быстро поднял 7 первых, после чего веб интерфейс начал ужасно тормозить, видимо sshfs скачивал к себе всю директорию, которая была довольно-таки пухленькой.
2 тур начался, у нас уже 14 рабочих узлов! Тихонько стал подключать узлы к системе, по одному, чтобы не перегружать систему.
Очереди на сервере не превышало 10 одновременно выполнявшихся тестирований. То есть, в принципе, достаточно и 5 ноутов, чтобы провести полноценный тур.
Приходили из телевидения, им сказали, что у нас 24 рабочих узла. Пришлось до конца олимпиады поднять все, чтобы сдержать слово.
В итоге 2-й тур участники написали гораздо лучше, чем 1-й, хотя в 1-м туре был участник, который написал на 400, а на 2 туре, набрали только 370.
Альтернатива
На самом деле, всем всё было давно известно, и для этого даже прибегли к помощи Яндекса. Последний принимал заявки от регионов, которые не могли самостоятельно провести региональный этап по новым требованиям. Заявки нужно было подать за 10 дней до олимпиады, поэтому мы этот способ не рассматривали. К Яндексу обратились 26 регионов.
Также сказали, что в других регионах тоже не всё хорошо, баллы низкие в целом.
Вот так мы, технические жюри, позорно провели региональный этап Всероссийской олимпиады.
Вывод
Даже не знаю, что тут писать. Короче, будьте.
Автор: ilnuribat