Това е статия от света на Python, но все пак е приложима за цялата област на програмирането, въпреки че мултитредингът ни позволява да обработваме заявки по-бързо, но има и таван – зелените (микро-нишки) нишки са решението.
Многопоточната разработка на софтуер решава голям брой проблеми, особено за мрежово ориентирани приложения, които изискват изискване на висока производителност за бърз отговор на потребителите. За съжаление, мултитредингът не е достатъчен за решаване на големи проблемиСъвместимостсексуални проблеми.
Решаването на тези проблеми изисква промяна на програмните модели, използвайки асинхронни събития и механизми, базирани на обратни позиви. В Druva създадохме python библиотека, наречена Dhaga, за решаване на големи задачиСъвместимост, докато моделът на програмиране не изисква значителни промени.
Софтуерните разработчици живеят в такъвСъвместимостсвят. Нишките са първокласни граждани днес, особено по време на разработката, особено когато вашето приложение извършва интензивни мрежови операции, като системата inSync (продукт за мрежова синхронизация) като Druva. Мултитредингът улеснява и подреден потокът на програмния код за мрежови операции. Когато нашето приложение се нуждае от подобрения или подобрения в производителността, то може да бъде подобреноЕластичност, можем да увеличим броя на нишките.
Но когато става дума за хиляди мащабиСъвместимостЗаявките, нишките не са достатъчни.
Открихме, че мултитредингът има следните недостатъци: 1. InSync системният клиент трябва да архивира голям брой файлове към сървъра чрез мрежови RPC повиквания. Типичен начин за разработчиците да ускорят работата е да използват нишки. Въпреки това, производителността, която носи многонишковото управление, увеличава разходите за памет и процесор; Разработчиците трябва да поддържат баланс между скорост и брой нишки.
2. Нашите сървъри трябва да обслужват между inSync системата и хиляди клиентиСъвместимостВръзки и известия. За да управляваме връзките ефективно, използваме нишки за обработка на заявки. Но нарастващият брой клиенти на inSync системи означава, че трябва да продължим да увеличаваме броя на нишките, което изразходва много сървърна памет и процесор.
3. Нашият уеб сървър трябва да обработва хиляди паралелни HTTP заявки. Повечето от работата е върху мрежовите сокети, които приемат и изпращат данни и ги предават към бекенда на inSync системата. Това кара повечето нишки да чакат мрежови операции. Причинявайки проблема с C10K, когато има хиляди синхронни заявки към уеб сървъра, генерирането на нишка за всяка заявка е доста немащабируемо (Scale).
Ограничения на асинхронните рамки Много асинхронни рамки, включително Twisted, Tornado Tornado и asyncore, могат да помогнат на разработчиците да се отдалечат от популярните начини на използване на нишки. Тези рамки разчитат на неблокиращи сокети и механизми за обратно повикване (подобно на Node.js). Ако използваме тези фреймуъркове както са, основните части на нашия код на Druva ще трябва да бъдат рефакторирани. Това не е, което искаме да правим. Рефакторирането на кода увеличава циклите на разработка и тестване, като ни пречи да изпълним изискванията за мащаб. Тъй като множество части на продукта трябва да са масивни, всеки от нас ще трябва да ги рефакторира – затова и усилието за удвояване или утрояване.
За да избегнем толкова много промени в кода, трябваше да се откажем директно от използването на съществуващата рамка. За щастие намерихме някои полезни инструменти.
Тъй като искаме да контролираме изпълнението на кода в мрежовия вход/изход, ни трябва начин да разделим нишката на микронишки. ОткривамеЗелени лети。 Той предоставя неимплицитно планиране на микронишки, наречено ко-рутинна корутина. С други думи. Полезно е, когато искаш да контролираш работата на кода си. Можеш да изграждаш микротредове за персонализирани графици, защото можеш да контролираш кога greenlet-ите дават паузи. Това е перфектно за нас, защото ни дава пълен контрол върху графика на кода ни.
Tornado е проста, неблокираща уеб сървърна рамка, написана на Python, предназначена да обработва хиляди асинхронни заявки. Използваме основния му компонент, IOLoop IOStream. IOLoop е неблокиращ гнездов I/O събитен цикъл; Използва epoll (на Linux) или опашки (BSD и Mac OS X), в противен случай изберете (на Windows), ако са налични. IOStream предоставя неблокиращи гнезда, като удобна опаковка за четене и писане. Делегираме всички операции с сокет на Tornado и след това използваме обратни позиви, за да задействаме операции с код за завършване (бележка на banq: много подобно на Node.js механизъм).
Добър старт е, но ни трябват още. Ако използваме горния модул директно в кода си, голяма част от нашия RPC код ще трябва да се промени, като планираме RPC чрез greenlets, уверяваме се, че greenlet-ите не блокират (ако greenlets се запушат, ще се запуши цялата нишка и всички останали), да се обработват callback функциите от tornado.
Нуждаем се от абстракция, която да управлява и подрежда зелените файлове, за да не ги запушваме с външни повиквания, а тази абстракция може да бъде значително мащабируема отвъд нишките. Тази абстракция е Dhaga, която позволява приложният код да се програмира като традиционна синхронна последователност, но изпълнението е асинхронно.
Дхага (от хинди, което означава нишка) е рамка за изпълнение на лека нишка, която абстрахираме. Класът Dhaga произлиза от greenlets и използва stack switching, за да изпълнява множество кодови потоци в една нишка на операционната система. Нишките на една операционна система изпълняват множество dhagas-и чрез съвместно планиране. Винаги когато дхага чака (главно чакайки връщане на RPC повикване), тя прехвърля контрола на родителското ниво (т.е. контекста на изпълнение на нишката на ниво ОС, която я е създала). Родителското ниво след това насрочва още една дхага, за да е готова за провеждане. RPC повикването ще бъде прехвърлено към tornado web сървъра, за да се запише Socket асинхронно, след което ще се регистрира обратна повикване при връщане, а когато този RPC се върне, чакащият dhaga ще бъде добавен към изпълнимата опашка и след това ще бъде взет от родителската нишка. (Бележка от Банк: подобно на принципа node.js)
Можем да използваме Dhaga вместо нишки за операции с висока латентност и използваме 512 дхаги в една нишка, когато броят на нишките надхвърли разумния лимит за пропускателна способност.
|