Производительность shared-папок в Vagrant

image

Руководя крупной и регулярно пополняющейся командой программистов, столкнулся с необходимостью быстро разворачивать среду разработки без танцев с бубном в духе «странно, у меня этот же код работает, а у тебя какая версия такой-то библиотеки?»

Получив однажды ссылку от заказчика на Vagrant с вопросом «а почему мы это сих пор это не используем?» принялся осваивать это чудо.

Спустя некоторое время подготовил Vagrantfile, за считанные минуты разворачивающий сложную систему репозиториев, библиотек, серверов и деплоеров. И все бы хорошо, но одна маленькая неприятная деталь — все это либо жутко тормозило/глючило, либо (при локальном выполнении) не обеспечивало прямого доступа к хранящимся внутри vagrant репозиториям.

Многие скажут, а зачем нужен этот прямой доступ, если можно хранить копии файлов на host машине и доставлять их на guest машину автоматически, при сохранении их в IDE.

Все верно, но есть нюанс — команде нужна возможность переключать ветви (branches) git репозиториев на сервере, наблюдать результат в браузере и редактировать код ветвей у себя в IDE не отходя от кассы.

Многие скажут, а в чем проблема, есть же ssh и консольный git и даже покажут маньяка, который вбивает команды консольного git клиента с клавиатуры быстрее, чем клиент успевает их выполнять. Можно согласиться и с этим утверждением, но имея 10 репозиториев и несколько десятков ветвей на репозиторий, я предпочитаю наблюдать и управлять всем этим визуально, через SourceTree, и иметь практически любую команду по управлению этой махиной, в досягаемости трех кликов.

Перепробовано.
  1. Shared Folders — скорость отработки скриптов оказалась в 10 раз меньше чем при выполнении с guest папок
  2. SSHFS
    • постоянные реиндексирования в phpStorm
    • выпадание всех файлов из git index при переключении ветвей, с необходимостью постоянно делать reset --hard
    • неспособность IDE и git клиентов заметить происшедшие изменения в файлах
  3. NFS и NFS Reverse — тупо отказались работать на OSX без плясок с бубном (по отзывам в интернете, тоже не решают вопрос фундаментально)

Через несколько дней (недель?) потраченных на изучение этого вопроса, выяснилось, что в своих чаяниях я далеко не одинок, но ничего умнее односторонней синхронизации через rsync, на сегодняшний день общественность толком не видела.

Самое близкое, что удалось нащупать — это утилита unison, осуществляющая двухстороннюю инкрементарную синхронизацию, и написанный под нее vagrant plugin — github.com/mrdavidlaing/vagrant-unison

Правда возникла другая проблема. Утилита сама по себе, автоматически синхронизировать папки может лишь в режиме ежесекундного перезапуска, который не поддерживался vagrant плагином. Плагин может обеспечить автоматическую синхронизацию, даже не в repeat, а в event-based режиме, но лишь в одну сторону (host->guest). Более того, плагин писался под версию vagrant 1.1, и на сегодняшний день, не выполнял даже те функции, которые в нем официально заявлены.

Чуть позже выяснилось, несмотря на то, что плагин не обновлялся автором с 26 апреля 2013, 7 месяцев назад другой программист предпринял попытку привести плагин в чувство. Результаты его работы можно наблюдать по адресу: github.com/edtoon/vagrant-unison

Даже его плагин, на последний vagrant (1.7.x) устанавливаться отказывается. Доработав его код мне удалось добиться
  1. совместимости с 1.7.x;
  2. поддержки repeat режима;
  3. возможности решать конфликт базы даных unison после «vagrant destroy; vagrant up» командой sync-cleanup.

Результат представляю вашему вниманию по адресу: github.com/dmatora/vagrant-unison
Готовый плагин: www.dropbox.com/s/1yu1s7pr3qlr8ag/vagrant-unison-0.0.15.gem — для установки через
vagrant plugin install vagrant-unison-0.0.15.gem

Пользуюсь уже несколько дней и до сих пор щипаю себя, чтобы убедиться, что отсутствие тормозов и глюков мне не снятся.
Правда, по слухам, для комфортной работы нужен 4 ядерный процессор (и желателен SSD + Parallels)

P.S. В связи с появившимися комментариями, прикрепляю иллюстрацию из статьи
Vagrant — NFS shared folders for Mac/Linux hosts, Samba shares for Windows
image

P.S. Не смотря на то что мой fork привлек внимание (в основном буржунета) и до сих пор живет своей жизнью, вынужден заявить что на данный момент я все-же пользуюсь nfs_guest. Я пытался воспользоваться им перед unison, но на моем OSX он тихо отказывался работать, пока я не выяснил, что для работы nfs на OSX необходимо иметь запись localhost в /etc/hosts. nfs к сожалению не сообщает приложениям о событиях в файловой системе, но на фоне проблем с синхронизацией и нагрузкой на процессор, это терпимо. Невыносимые моргания SourceTree, как выяснилось, можно отключить в настройках (Refresh automaticly when files change)
Поделиться публикацией

Похожие публикации

Комментарии 32

    0
    для тех же целей использую samba (сами файлы в виртуалке), лет 5 уже, полет нормальный
      0
      Сталкиваемся с медленной работой гита + samba. Огромный репозитарий, куча веток и т.п. Чем больше история, тем дольше выполняются команды гит, например доходит до того, что git status выполняется 15-20 сек. Пока решаю проблему через ssh и консольный гит в системе.

      В начале разницы вообще не ощущалось, где-то через 2 месяца разработки проекта, стали заметны задержки и пока они только увеличиваются каждый день.
        0
        > для тех же целей использую samba (сами файлы в виртуалке), лет 5 уже, полет нормальный
        Нет, не нормальный.
        С ним те же самые проблемы, что и с SSHFS:
        > выпадание всех файлов из git index при переключении ветвей, с необходимостью постоянно делать reset --hard

        Для себя решил, что идеальный вариант Shared Folders:
        > Shared Folders — скорость отработки скриптов оказалась в 10 раз меньше чем при выполнении с guest папок
        А еще в пять раз оно медленнее за счет того, что это dev-среда, стоит отладчик, нет оп-кешера.
        И пусть медленнее. Не жалко.
        Зато отлично работает.
          0
          > С ним те же самые проблемы, что и с SSHFS
          я прям не знаю что ответить, вы заставляете меня усомниться в том что я вижу каждый день…
          реально что-то подобное можно сделать только если пытаться одновременно git запустить и на хостовой машине и через ssh

            +2
            neolink Вы сейчас похожи на того программиста-доктора из анекдота: «А у меня такая же нога, и она не болит».
            Если бы эта ошибка была у кого-то одного, это могло бы быть случайностью, но в данном случае она уже и у меня, и у автора статьи. Кроме того, я слышал о такое проблеме еще от нескольких людей.
            Причем не каждый раз при изменении файла, а при очень быстром тяжелом действии, таком, как переключение ветки в гите с большим количеством изменений.

            E_STRICT На гостевую машину ставить нельзя NFS, smbd и т.д. — иначе индексация на хосте в IDE будет вечной.
              0
              OnYourLips У автора нет упоминания про samb'у это вы придумываете. Отсылки про то что вы слышали тоже достаточно виртуальны. Неуместные сравнения тоже не делают вам чести, а заявляете вы гораздо безапелляционнее, что ваше мнение единственно верное.

              Я описываю свой опыт, внизу даже привожу некие цифры по которым можно прикинуть масштаб проблемы. Более того я даже пробовал такое в рамках локальной сети и оно по скорости не сильно медленее чем на одном хосте
              Да это медленнее чем держать файлы локально, но не настолько чтобы это было проблемой.
              Да первичное индексирование занимает пару минут, но никаких вечных индексаций я не всречал.
              Зато скорость выполнения больше чем если бы я на Windows поднял бы тот же apache + php, нет глюков как с Shared Folder когда внутри виртуалки видно только половину файла. или не видно его вовсе.

              С синхронизацией есть большая проблема если вам нужно что-то делать и локально и внутри виртуалки, так как по сути это 2 копии файлов.
                +2
                иначе индексация на хосте в IDE будет вечной

                Давно пользуюсь такой схемой. Отлично работает.
            0
            если вы уверены что зависит от размера именно истории попробуйте
            git gc

            а так 4000 файлов в индексе, +20000 у зависимостей, 6500 коммитов, 120 веток, — 7 секунд, через IDEA секунды 3-4
              0
              Пробовал, не помогает
              0
              events.yandex.ru/lib/talks/2588/ — гит в принципе тормозит на больших проектах.
              Почему бы в один из релизов не продолжить разработку в чистом репозитории?
                0
                Я захожу на машину через ssh и все летает как и должно быть, тут дело точно не в гите.
                  +1
                  гм, так вы под вагрантом git гоняете… а зачем?
            +1
            NFS и NFS Reverse — тупо отказались работать на OSX без плясок с бубном (по отзывам в интернете, тоже не решают вопрос фундаментально)
            NFS отлично решает этот вопрос. Важно, чтобы NFS сервер был именно в гостевой машине. SSHFS тоже неплохо работает. Конечно если вы запускаете Вагрант не на локальной машине, а где то на действительно удалённом сервере, то нужно иметь достаточно быстрое интернет подключение.
              0
              Мы работали на одном проекте по samba с гостя, очень успешно. Только надо помнить, что гит должен работать на той же системе, на которой лежат файлы. Т.е. в данном случае — на госте через ssh. Все девелоперы (и верстальщики) юзали консольный гит по ssh и не парились. Но у такого сетапа есть два минуса: 1) vagrant up надо делать не в рабочей копии проекта, а в другом месте, а потом уже рабочую копию вручную маунтить на хост, что не очень удобно, 2) IDE не то чтобы сильно быстро индексирует файлы, которые доступны через шару (не очень критично на самом деле для нас оказалось, приходилось подождать изредка 30 сек, нуок).
              Теперь я юзаю везде NFS (файлы на хосте), на OSX без вопросов завелся, даже на винде. Но тоже есть проблемы вечно какие-то, то файл не сразу увидит, то время изменения неверное видно, хз. Надо будет попробовать ваш способ.
                +2
                Linux, NFS — полет нормальный.
                  +1
                  OSX, NFS, SSD — полет нормальный, необходимости в штуках типа unison/rsync для локальной машины не вижу. Единственное что чуть побаловался с настройками маунтинга NFS (размер буферов чуть увличил, кеширование включил ну и другие мелочи).
                0
                В qemu/kvm в качестве протокола для shared folders используется сетевая файловая система 9p, которая обеспечивает бОльшую производительность. Virtualbox, кажется, сам не поддерживает 9pfs, но всегда можно сделать сеть между хостом и гостем, и примонтировать shared folder через 9p по сети.
                  +4
                  У нас на работе отлично у всех работает NFS на OSX без тюнинга.

                  В конфиге просто указано:
                    config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp', 'fsc']
                    config.nfs.map_uid = Process.uid
                    config.nfs.map_gid = Process.gid
                  


                  Особенно разительна разница в проектах на Symfony2 (php)
                    0
                    Я еще actimeo подправил — ватчеры для сборки фронтэнда отрабатывают чуть шустрее, в смысле от момента сохранения файла на хосте до срабатывания ватчера.
                      +1
                      Аналогично, никаких плясок с бубном для NFS в OS X (10.8, 10.9, 10.10)
                        0
                        Утянул ваш конфиг себе. Надеюсь мои проблемы с NFS решатся вашими mount_options =).
                          –2
                          У меня работает на OSX так:

                          config.vm.synced_folder "/.", "/www/project/code/local", type: "nfs"
                          
                          0
                          Я сделал так. В вагранте у меня крутится серверное окружение (LAMP с кучей нужных плагинов, extension'ов, и базой данных).
                          БД тестовая, но на 18 гигабайт. Изначально у меня база была на удалённом сервере, но от этой практики отказались в пользу локальной базы в виду низкой скорости коннектов к базе. А вот удалённый сервер — там и мастер ветка, и база данных, и используется уже для тестов перед деплоем на продакшн. К нему гитом лезем через нативную консоль, не через вагрант, т.к. неоднократно было замечено, что в вагранте даже при 4 гигах памяти гит работает недостаточно быстро.
                          А вот файлы веток у нас тоже нативно лежат, и подключаются в вагрант как shared_folder.
                          Хост Ubuntu 14.04, вагрант тот же, FS ext4. Ну и естественно, бокс запакован и раздаётся всем девелоперам. Доступ к удалённому серверу по ssh ключам, которые уже прописаны в боксе.
                            0
                            Я в PHPStorm делал через Remote SSH External Tools в котором была команда запуска rsync и рисовал более менее адекватный прогресс исходя от вывода rsync.

                            Ничего более адекватного по скорости я не нашел :(
                              0
                              Для синхронизации локальной версии проекта с хостом можно использовать realsync. Работает на основе rsync.
                              Скорость синхронизации мгновенная
                                0
                                Добрый день, поставил плагин, не могу запустиь виртуалку, при vagrant up в консоль вываливается:

                                There are errors in the configuration of this machine. Please fix
                                the following errors and try again:
                                
                                Unison:
                                * translation missing: en.vagrant_sync.config.host_folder_required
                                * translation missing: en.vagrant_sync.config.guest_folder_required


                                Код с гитхаба в конфиг вставлял.
                                Подскажете куда копать?
                                  0
                                  Свяжитесь со мной в скайпе ( dmitry.matora ) и покажите экран — разберемся.
                                    0
                                    $ vagrant -v
                                    Vagrant 1.7.1
                                    
                                    $ vagrant reload
                                    There were warnings and/or errors while loading your Vagrantfile
                                    for the machine 'default'.
                                    
                                    Your Vagrantfile was written for an earlier version of Vagrant,
                                    and while Vagrant does the best it can to remain backwards
                                    compatible, there are some cases where things have changed
                                    significantly enough to warrant a message. These messages are
                                    shown below.
                                    
                                    Warnings:
                                    * Unknown configuration section 'sync'. If this section was part of
                                    a Vagrant 1.0.x plugin, note that 1.0.x plugins are incompatible with 1.1+.
                                    
                                    There are errors in the configuration of this machine. Please fix
                                    the following errors and try again:
                                    
                                    Unison:
                                    * translation missing: en.vagrant_sync.config.host_folder_required
                                    * translation missing: en.vagrant_sync.config.guest_folder_required
                                    


                                    Vagrant::Config.run do |config|                                                                                                                                                                    [80/9750]
                                      config.vm.box = "virool"
                                      config.vm.box_url = "/Users/trybeee/Dropbox/Vagrant/package.box"
                                      config.ssh.forward_agent = true
                                      config.vm.network :hostonly, "33.33.33.10"
                                      config.vm.share_folder("vagrant-root", "/vagrant", ".", :nfs => true, :nfs_version => 3)
                                    
                                      config.sync.host_folder = "./"  #relative to the folder your Vagrantfile is in
                                      config.sync.guest_folder = "./" #relative to the vagrant home folder -> /home/vagrant
                                      # config.sync.ignore = "Name {.idea,.DS_Store}"
                                    
                                    
                                      0
                                      Необходимо использовать Vagrant.configure(«2»)

                                      Vagrant.configure("2") do |config|
                                        config.sync.host_folder = "./"
                                        config.sync.guest_folder = "./"
                                        ...
                                      end
                                      

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое