2008-12-19 update протокол

by Vasil Kolev

На рождения ден на Венски с Бачийски почнахме интересен разговор за масов update на вече deploy-нат софтуер (писан на скриптов език, но май няма чак такова значение). Той искаше да смъкне времето за deployment под текущите 45 секунди, и мисля да опиша една от идеите, които ми хрумна, а после Пенчев (който участваше в дискусията) да и намира кусури.

Основният принцип е следният – един сървър пуска по multicast пакети с update (във вид на diff например), а машините го поемат и слагат. Ето и принципно как би трябвало да работи протокола:

1. Главният сървър пуска към multicast групата един пакет, че следва update.
2. Изчаква timeout T1 и ако някой не отговори (той има списък с машините) праща пак.
3. Стъпка 2 се повтаря 3 пъти, ако има не-отговорила машина, се вади от списъка и се праща notification.
4. Изпраща се update, разделен на пакети, като всеки пакет:
4.1. Съдържа ID на update (пореден), като всеки клиент има списък с updates които е получил
4.2. Номер на пакета в update (за да се следи за загуби)
4.3. Подпис на пакета (md5sum на съдържанието + shared secret)
4.4. Diff в някакъв вид.
5. Всеки клиент, получил update:
5.1. Проверява дали вече не го е apply-нал, и ако да, не му обръща внимание, само праща обратно потвърждение
5.2. Ако има дупки в него, не праща потвърждение.
5.3. Ако update не е пореден на предишния приложен, не праща потвърждение и известява администраторите.
5.4. Ако е получил целия update, проверява дали може да бъде приложен. Ако не – праща известяване и не потвърждава.
5.5. Ако е получил целия update без проблеми и може да се приложи – прилага го, отбелязва, че е приложен и праща потвърждение.
6. Ако централният сървър за timeout T2 не получи потвърждение от всички, повтаря т.4 три пъти. За тези, от които не е получил потвърждение, известява администраторите.

Спорът е, дали протоколът има някакви сериозни проблеми и дали може да бъде реализиран в рамките на ден-два от нормален програмист (не мързел като мен). Също така, дали някой не му е хрумнало да напише такова нещо :)

Tags:

16 Responses to “2008-12-19 update протокол”

  1. Апостол Апостолов Says:

    При цялото ми уважение към вас, но винаги, щом се сблъскам с такова четиво, се сещам за една смешна думичка от времето на комунизма- “денгуба”. Вместо да печелите пари от Нета, вие се занимавате с… ей такива нещица…

  2. Alex Stanev Says:

    ОК, по темата:
    с. 3: С 3те пъти няма да върши винаги работа. Машините се намират на различни места, различни инфраструктурни проблеми могат да им влияят. Добре би било да се поддържа примерно хеш-таблица с опитите и сървърите, която да се попълва/обновява с адаптивен алгоритъм;
    с. 4.3: Защо preshared key? Единствената причина, за която се сещам е, че въпросния скриптов език няма (ширпко разпространени и инсталирани) bindings към библиотека за асиметрично криптиране. Може да се намери имплементация само на верификацията на съответния език и да се използва. Всичко друго е хакваш една от машините и own-ваш зялата мрежа;
    с. 5.1: Въпросната проверка може да се направи по много начини – прост лог, директно сравняване с patch, сетване на маркери и т.н. Не забравяйте, че ъпдейта ще включва и нови двоични файлове и т.н. Подхода за проверка трябва да е комбиниран. А ако потребителя някъде е пипнал нещо на ръка? Може би нещо малко?
    с. 5.3: СПАМ! Трябва да се опита да си ги дръпне и ако не успее, тогава. При много машини – много СПАМ :)
    с. 6: като с. 3. Ограничението трябва да е по време, а не по брой опити. SLA :)

    Нормални програмисти няма.

    Ай наздраве!

  3. Vasil Kolev Says:

    @Апостолов, ние караме нещата да работят. Те парите си идват така или иначе:)

    @Алекс Станев:
    за 3: идеята е, че всичко е в един сегмент (пропуснал съм да го кажа). Така и така ползвам multicast, отказвам да разчитам на routing за multicast-а, понеже е боза. Идеята е във всеки datacenter по една машинка, дето локално насипва на останалите.
    за 4.3: защото най-лесно се реализира. В case, който обсъждахме, машините са еднакви, ако си намерил начин да влезеш на една, той важи и за останалите.
    за 5.1: само log, той може и да е пипнал локално, ако се получи конфликт, ще се обади в 5.4.
    за 5.3: Не знам защо не добавих NACK в протокола, т.е. да си каже, че не е станало и да не опитва. Иначе не трябва да дърпа нищо, идеята е push, а не pull.
    За 6, пак като за 3 :)

  4. Антон Попов Says:

    5.1 не ми харесва много:
    “5.1. Проверява дали вече не го е apply-нал, и ако да, не му обръща внимание, само праща обратно потвърждение.”

    Не би трябвало да се случват такива неща – така че правилното в случая е да се отбележи някъде че един и същ patch е дошъл многократно. Може да е в лог, а може и направо нотификация на админите.

    Още нещо:
    Този протокол ще върши работа за прости задачи – да се смени един .js или .php файл с друг.
    Не мисля, че може да бъде универсален и приложим за updates на всякакъв тип приложения. За по-сложни updates може да се появят проблеми.

    Освен това, доколкото разбирам, машините ще работят независимо една от друга, нали?
    Как ще обновим даден сайт, ако имаме 5 машини, които го и три от тях обслужват базата и две са web сървъри?
    Естествено, едно от решенията в тази ситуация ще изисква някои от машините да бъдат временно изключени от инфраструктурата на сайта, за да не се получи така, че имаме примерно стара и нова база в даден момент.
    Което ни отвежда отвъд простотата и чистотата на протокола и ни изпраща в custom сценариите.

  5. tie Says:

    Нов протокол за такава задача? Просто намерете начин на изпълните svn update на клиентските машини.

  6. Vasil Kolev Says:

    @tie, проблема е, че като пуснеш svn up на 100-200-300 машини към едно място, то се срива, за това се обсъждаше тоя проблем.

    @Антон Попов, идеята е съвсем еднакви машини, един сайт на тях (задачката е за wordpress.com и deployment-а на нови версии в/у него). За 5.1 съм съгласен, трябва да се отбелязва.

  7. tie Says:

    Сриването при svn up е проблем на управлението на ресурсите и може да се избегне (напр. увеличаваш броя на сървърите). Освен това има достатъчно алтернативи на svn (git, mercurial, bazaar, etc) – не съм ги използвал, но подозирам че сред тях има по-ефективни от svn.

    Това, което ти трябва на практика е svn update, който работи в “push”, а не в “pull” режим. Сега ми хрумна, че технически може да се направи така, че да има repository на всяка клиентска машина. Ъпдейтващия сървър (или сървъри) прави commit към всяка от клиентските машини, и със post-commit hook новия код се прехвърля от repository към локалното работещо копие. Разбира се това е грозен хак, но за сметка на това не ти трябва специална инфраструктура или протокол. Някоя от distributed source control системите вероятно ще се справи и по-добре в този сценарий.

  8. Антон Попов Says:

    @tie
    Човек, недей така да изпростяваш нещата :)
    Пътят от сорсове до деплойнато web приложение е много, много дълъг.
    Сериозно ли си представяш на всяка клиентска машина да има сорсове и сорс контрол софтуер?!
    Ами че ти ако деплойваш направо сорсове си за оплакване – къде отиде минимизането на HTML-а, CSS-a и JavaScript-a? Да не говорим, че за купчината настройки, които естествено няма да ги пазиш в source contol системата и които се правят в процеса на деплойване? И после, няма ли да тестваш онова, което се build-нало от тия сорсове или ей тъй, ще ги деплойваш урбулешката? Да не би да си мислиш, че софтуера е безгрешен и бъгове няма?

    А това пък ме разсмя:
    “има достатъчно алтернативи на svn (git, mercurial, bazaar, etc) – не съм ги използвал, но подозирам че сред тях има по-ефективни от svn.”
    Подозирам, че си прав, само че не мога да разбера, като не си ги използвал защо изобщо даваш акъл? SVN-a е боза, той не става за това, за което е писан ( система за сорс контрол), а ти се опитваш да му вменяваш функции, които изобщо, ама изобщо не са му работа!

  9. Vasil Kolev Says:

    @tie, идеята е да не се слагат милиони сървъри (щото трябва първо да update-неш тях), и винаги тия системи са тежки – никой versioning control не е мислен да може да се ползва в такава ситуация (пиково натоварване от много потребители), живия пример е колко зле е sourceforge. Всяка от тия системи освен всичко се хваща да проверява цялото локално копие до какво ниво е, което в нашия случай може да се пренебрегне.

    Освен това при много машини unicast-а не се scale-ва особено добре, аз за това го мислих с multicast (въпреки че в тоя случай и broadcast би свършил работа).

    И да добавя, задачата е много ограничена – тя е само за прост update на количество файлове с някакъв diff много бързо на много машини в един локален мрежов сегмент. Ако се разпъне на по-голяма мрежа с multicast routing, може да се наложи да се разшири с ползване на два multicast адреса и динамично влизане/излизане, но това може да се остави за версия 2 :)

  10. Антон Попов Says:

    @Vasil Kolev
    “никой versioning control не е мислен да може да се ползва в такава ситуация (пиково натоварване от много потребители)”
    При цялото ми уважение, тук не мога да се съглася, да ме прощаваш. Има два типа системи за source control (или поне аз два знам) – такива, които използват централизиран сървър – като бозите CVS, SVN и т.н. и такива, които са разпределени (distributed). Такива са GIT, BitKeeper, Mercurial.
    Това, което си написал, се отнася до централизираните системи за сорс контрол.
    При дистрибутираните, този въпрос е решен по Сталински:
    “Нет много потребители на един сървър – нет проблема”.
    За повече информация гледайте прекрасната лекция на Линус Торвалдс относно GIT тук:
    http://www.youtube.com/watch?v=4XpnKHJAok8

  11. Vasil Kolev Says:

    @Антон Попов, виж заданието бре – имаме 500 сървъра, на тях се deploy-ва директно без тестване целия сайт, от 4 машини в 4те места, в които са тия сървъри (истински случай, wordpress.com), и трябва да стане за под 40 секунди. Дистрибутиране на много машини не е решението, а и колкото и да е бърз git-а и което и да е, 500 fork-а в един момент на една машина и паленето на един daemon не е от най-леките неща.
    (лекцията мисля, че съм я гледал :) )

  12. Антон Попов Says:

    @Vasil Kolev
    Това задание го казваш подир байряма; в първоначалния ти постинг няма нито дума за 500 сървъра, нито че се deploy-ва директно, без тестване (което общо взето си е чиста глупост), нито че става дума за wordpress.com :)
    Пише единствено да се намерят грешки в протокол, който да обезпечи някакъв deploy за под 45 секунди :)
    “Дистрибутиране на много машини не е решението…” – съгласен съм, но надявам се не си заключил, че точно аз твърдя, че това е решението?

  13. tie Says:

    @Антон Попов
    “Сериозно ли си представяш на всяка клиентска машина да има сорсове и сорс контрол софтуер?!”
    Ами в света на PHP (WordPress), Ruby, Perl, Python и прочее интерпретирани езици – ДА, на всяка клиентска машина има сорсове. Представяш ли си да няма? Колкото до сорс контрол софтуера – той е като всеки друг utility софтуер на машината. Дрои да кажем че го няма, може да се имплементира като библиотека на съответния език. Доста по-лесно и преносимо от това да имплементираш чисто нов IP-базиран протокол, заседно с прилежащите му клиент и сървър.

    “Ами че ти ако деплойваш направо сорсове си за оплакване – къде отиде минимизането на HTML-а, CSS-a и JavaScript-a?”
    Нали знаеш, че сорс контрол системите могат да синхронизират даже и минимизирани JavaScripts? Дори и с binary файлове работят, да им се ненадяваш :) С други думи – каквото пъхнеш във фурната, такова ще ти “деплойнат” – това не е проблем на системата, а на фурнаджията.

    Тестването на уеб приложението не влиза в scope-а на подобна ситема – то е работа на система за автоматично тестване. Тази част идва след като уеб приложението е ъпдейтнато. Оправянето на бъговете изисква човешка намеса при всички случаи.

    Ъпдейта на настройките наистина е по-сложна задача. Остава си сложна и за multicast/broadcast протокол за ъпдейтване.

    @Vasil Kolev
    Факт е, че general-purpose системите за синхронизация ще са доста по-неефективни от custom multicast протокол, когато става дума за няколкостотин машини на един сегмент. Другия факт, е че въпросите съществуващ general-purpose системи покриват като фунционалност почти всичко което би ти потрябвало в разни edge cases. Представи си, че новата версия се деплойва и приложението се чупи на всички няколкостотин машини. Как ще revert-неш към старата версия? Теоретично протокола ти може да направи нов ъпдейт, но е още нещо което трябва да се имплементира на сървъра. Друг проблем – за да ъпдейтнеш машина от версия 1 до версия 1000 ще трябва да наспамиш цялата мултикаст група с 1000 ъпдейта – неефективно като време и като трафик.

    Иначе самия протокол изглежда добре. Само добави ID-тата на ъпдейта и на поредния пакет от ъпдейта в подписа, че иначе се отваря протокола за много лоша replay атака:)

  14. Георги Чорбаджийски Says:

    maniaxе не се занимвай с глупости :) За теб една дума: rdist – http://www.benedikt-stockebrand.de/rdist-intro.html

  15. Николай Недялков Says:

    Чадо, само да те светна, че 2010-2011г M$ ще пуснат multicast и “torrent”/p2p протоколи за updates на всички свои приложения. Освен това, подписа на всеки пакет ще е реализиран с алгоритъм базиран на elliptic curves.

    Мога да ти пратя презентацията на шефа на R&D департмента им, който дойде да ни го обяснява миналата година на Crypto07 (на който чадо не дойде) и който чадо сме съорганизатор.
    http://sage.math.washington.edu/home/jetchev/public_html/docs/charles-talk.pdf

  16. Vasil Kolev Says:

    @Недялков, на нещо от MS ще повярвам само като го видя :) Освен това 1) multicast-а в големия internet е загубена кауза, а остналото звучи като списък от buzzwords…

    Ще им погледна документацията за кво става въпрос, но то пак няма да реши точно тоя case, за който аз съм писал :)

Leave a Reply