вторник, 4 февраля 2014 г.

Зарисовка из жизни: опыт борьбы за производительность сборочного сервера (начало)

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

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

Началось всё с того, что одна из команд разработчиков "дозрела" до применения такой полезной функции TFS как gated build для защиты репозитория от ломающих изменений. Это было сделано, но быстро выяснилось, что сборка занимала слишком много времени: один check-in занимал 15-20 минут, тогда как разработчикам хотелось бы, чтобы это происходило моментально. По результатам проведенного const/benefit analysis удалось договориться о том, что целевая длительность gated build - 5 минут.  Этого удалось достичь путем исключения интеграционных тестов из сборки, а также отказом от сборки инсталляционных пакетов, что в итоге дало время сборки ~4.5 минуты.

Но это было лишь началом. Спустя примерно два месяца от этой команды поступили жалобы на медленную сборку, которая вместо целевых пяти минут стала занимать около 20-25 минут. Поскольку наша сборочная инфраструктура виртуализирована, то было три уровня, на которых могли быть расположены причины деградации:
1. Исходный код и скрипты сборки, которые могли замедлиться в ходе развития;
2. Виртуальная машина сборочного сревера.
3. Виртуальная инфраструктура, поддерживавшая сборочный сервер, производительность которой могла деградировать по независящим от нас причинам.

Чтобы проверить первый вариант, я произвёл ряд тестов с исходными кода проекта двухмесячной давности, которые показали, что старый исходный код собирается так же медленно, как и новый. Это позволило исключить гипотезу о том, что причиной замедление стало развитие базы исходных кодов.

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

Однако я это предложение отверг, так оно основывалось на предположении, которое не объясняло тот факт, что производительность деградировала при неизвенных настройках виртуальных контроллеров. Внятного объяснения этой нестыковке он дать не смог, и мы провели вторую серию экспериментов, которая была направлена уже не на замеры счетчиков производительности внутри VM, а на физический хост, её исполнявший.

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

Продолжение следует.

Комментариев нет:

Отправить комментарий