в мрежата

уроци за компютри мрежи и сигурност

Начало операционни системи Общи за Windows Network performance tuning в Windows 2000/XP/Vista


Network performance tuning в Windows 2000/XP/Vista

Е-мейл
Оценка на читателите: / 5
Слаба статияОтлична статия 

Едно от нещата, които ме дразнят в Windows е изключително консервативната му конфигурация на Networking. Още от Windows for Workgroups 3.11, Microsoft разглежда операционната си система и потребителите и като врагове на мрежата. Тогава те си имаха свое Network API, и ако не бе Intel (и други) да портва BSD Sockets в това, което днес наричаме WinSock (както и куп други „оптимизатори”), може би днес Windows щеше да е с по-скоро IBM/SNA подобна система за комуникация, каквато бе идеологията в началото.

Всеки път, когато инсталирам нова машина се налага да поправям в registry-то конфигурацията по подразбиране. Което не винаги е особено лесно, защото архитектурата на Networking-а на Microsoft е доста хаотична. Това е така, защото Windows (в противоречие на масовото мнение) е всъщност една дистрибуция от кодове и софтуери написани от различни производители, за които Microsoft често плаща royalty такси (една от причините да имат гранична цена, под която се приема, че продават на загуба). Специално в Networking-а използват кодове от BSD, IBM, Intel, Shiva, Bay Networks (Nortel) и Cisco (IKE). Всеки един от тези производители разбира се, се бие у рунтавите буки, че едва ли не е написал всичко (например Cisco се биеше у гърдите, че е написал IPSec кода на Windows, но като се вгледа човек в лицензните споразумения, които между впрочем са публични, те не са писали нищо – само са предоставили права върху елементи от имплементацията на IKE протокола, който между впрочем е имплементиран много по-чисто от Microsoft, отколкото от Cisco в собствените им продукти, и това може да се види като бъгове спрямо съотношение на употреба в публичните документации и на двете компании), което разбира се не е вярно. Ако се абстрахираме от краденето от BSD (кода на Socket-ите и почти всички Applications) може би най-големите писачи на код за Networking в Windows са Intel (Socket-ите и оптимизациите, VLAN-ите, QoS, Bond-инга, IPSec + offload-инга му в мрежовите карти и т.н.) и Bay Networks (NAT, OSPF, Routing rules). Често се случва определени API-та да са дублирани в кодовете писани от различните производители, поради което се налага поправката на registry key и за двете, за да има общ ефект. Някой преконфигурации (дори през графичният интерфейс) изискват unload/load на DLL-ите наново, което може да ошашави някой приложения. Сигурно сте се чудили защо на мрежова карта като смените IP адрес след това се чака неопределено дълго време докато се задейства а някой приложения прекъсват сесиите си, в противоречие с нормалното поведение под други операционни системи? Това е заради reload на съществена част от кода (който може и да не се reload-ва, но този факт показва това, че писалият графичния интерфейс си е нямал никаква идея от начина на работа на underlying кода).

С тази прелюдия искам да отбележа какво ме дразни в нормалната конфигурация на мрежовият стек:

Windows 95/98/ME, Windows NT 3.5/4, Windows 2000, Windows XP TCP Receive Window е установен на 8KB, MSS е изключен, PMTU е изключено, Black Hole Detection на PMTU-то е изключено по подразбиране. Hash-а на броя на сесиите е оптимизиран за 1000 сесии на Workstation и за 2000 сесии на сървър. Поддържа до 1000 Half Open TCP сесии.

Windows 2000 SP3+, Windows XP SP2+, Windows Vista, Windows 2003 – TCP Receive Window Size се смята динамично, вече се поддържат големи сегменти (4GB), MSS е включен по подразбиране, PMTU не, Black Hole Detection не. Hash-а на броя на сесиите е оптимизиран за 1000 сесии на Workstation и за 2000 сесии на сървър. Поддържа само 10 half open TCP сесии (без Windows 2000).

Windows 2003 SP2, Windows Vista SP1, Windows XP SP3 – PMTU black hole detection e включен по подразбиране. 64 Half Open TCP сесии.

Какво всъщност значи всичко това:

TCP протоколът е този, който се използва в над 90% от вашата комуникация по Интернет или в локалната мрежа. Той цели да осигури сигурен пренос на данните – тоест данните се изпращат и се потвърждават че са получени правилно (пресмята се контролната им сума и се сравнява с тази записана във всеки пакет). Ако не са получени правилно не се потвърждават. Изпращащата страна изчаква малко време и изпраща непотвърдените участъци пак. За да не се налага да се потвърждава всеки пакет, преди да бъде изпратен следващия (понеже това ще ограничи максималната скорост на сесия в посока до големината на пакета за RTT време (RTT е времето необходимо за отиване и връщане на пакет), понеже всеки пакет с данни трябва да бъде потвърден преди да се изпрати следващия) потвържденията се правят на сегменти, които се наричат Windows (няма общо с Microsoft). Всяка страна казва на отсрещната непрестанно какъв е нейния моментен прозорец, от максимум байтове, които могат да бъдат изпратени към нея без потвърждение. Смисъла на това е, че така приемащата страна може да има нещо като Flow Control механизъм – ако има малък по размер буфер, ще е сигурна, че изпращача няма да изпрати повече данни от размера на този буфер (ако ние сме му казали максимален Receive Window <= на размера на буфера). Ако пък приложението четящо данните се бави, намаляваме Receive Window-а, и така намаляваме количеството данни, които да се трупат в буфера, до на практика пълното им спиране. Като прост ефект от това следва и формулата за максимална скорост на предаване на данни чрез TCP протокол в посока – тя е един Receive Window за RTT време. Или ако RTT е в милисекунди, то скоростта е (Receive Window * 1000)/RTT байтове в секунда.

И сега да се върнем към Windows – при него по подразбиране Receive Window е 8KB/17KB (при Linux е 32KB или 64KB в зависимост от Kernel-а). Следователно ако между двете комуникиращи си машини ping-а дава средно закъснение от 100мс, максималната скорост на трансфер към Windows ще бъде 8KB*1000/100 за секунда, или 80KB/сек. За пример Linux ще постигне при същите параметри 320KB/сек, само поради разликата в конфигурацията. Да, това не се усеща в LAN мрежа, където закъсненията се движат в порядъците на милисекунда. Но може да се вижда изключително силно в сателитна мрежа, където закъсненията се движат в порядъци на 500мс (и на мен ми се е случвало не веднъж). Защо Microsoft са го конфигурирали така? Защото изпращащата страна трябва да пази поне един отсрещен receive window буфер в паметта, за да повтори данните в случай, че са се загубили. Така за един корпоративен Windows Server ще се наложи да пази 8MB памет за буфери за 1000 сесии към работни станции заявяващи 8KB receive window, и 64MB ако са заявили 64KB. И понеже Microsoft разглеждат собствените си операционни системи като врагове, те отрязват техните прозорци за да не се случи претоварване. Аз обаче задължително си поправям този параметър. Това се прави с Registry-то:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters се създава DWORD Key с име „TcpWindowSize” и стойност (аз слагам 65535 десетично). Този параметър може да се слага и на интерфейс, но аз си го слагам глобално. Могат да се слагат и стойности на 64К, но само ако RFC1323 опциите са активирани и двете комуникиращи си страни ги поддържат. Поради това че Windows 95/98/ME използват друг winsock там registry key-а е различен. Естествено след това трябва “reboot” (това да не ви е Linux?).

Специално в Windows XP SP2/Windows 2003 обаче има частен случай с afd.sys – това е kernel driver с оптимизиран TCPIP код. Той взима превес над нормалният tcpip.sys и wsock защото те го използват него за част от операциите си. Ако параметрите на AFD са по-консервативни от тези на tcpip.sys то те се взимат по подразбиране. Следователно ако сме с XP SP2 или Windows 2003 то трябва освен tcpip\parameters да поправим и afd\parameters. Ето къде са те:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Afd\Parameters се създава DWORD Key с име „DefaultReceiveWindow” и стойност 65536.

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Afd\Parameters се създава DWORD Key с име „DefaultSendWindow” и стойност 65536 (това има вътрешно значение като максимално ограничение на изходящият буфер). Стойностите по подразбиране са 8K и на двете.

По подразбиране Satellite TCP не е активирано в повечето версии на Windows (само в XP SP2, Windows Server 2003 и Vista). Това е поправка на Receive Window Size в TCP протокола. Нормално тази опция може да има стойности от 0 до 65535. Обаче ако имаме трасета, в които няма загуби, но имат много високи закъснения, и скорост ще постигнем ефекта, че максималната теоретична достижима скорост на една сесия ще бъде 64KB*1000/RTT за секунда, или при RTT от 2000мс максималната скорост ще бъде 32KB/сек, ограничена от самият TCP протокол. Големите закъснения ошашкват и механизма за потвърждение на получените данни. Например ако една секунда нямаме потвърждение, това на какво се дължи – на закъснение или на загубени данни? Ако препращаме данните отново и отново всяка секунда, ако не са потвърдени, при 4 сек RTT ние ще сме ги изпратили 4 пъти, без да е имало нужда, или ще сме заели 4 пъти повече капацитет от необходимото. За това се появява едно RFC1323, в което се добавят няколко нови екстри. Първо Timestamp опция, с която се замерват закъсненията – всяка страна отбелязва timestamp времето в което изпраща пакет, и връща това, което отсрещната страна и е пратила. Така всяка страна може да разбере какво е било времето за стигане на този пакет до другата страна, и какво е RTT времето отделно, за отиване и връщане. Отделно чрез хитър механизъм се увеличава максималният прозорец за потвърждение, защото квантуването вече не е в байтове, а в MSS сегменти (които можем на кратко да оприличим на максимален размер на данните на пакет). Така теоретично можем да постигнем скорост от над 4GB за RTT, без да имаме рискове от безсмислено повторение на данните поради големи закъснения. Новите опции се договарят по време на установяването на сесията – едната страна предлага, другата потвърждава. На пръв поглед всичко е чудесно. Но не и за Windows. Тези опции не са активирани по подразбиране да се договарят с отсрещната страна. Така комуникация Windows-Windows ще бъде по старият метод (понеже нито една страна няма да предложи тези опции), или ще си работи бавно. За да се активира това трябва да се пипне отново registry key:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters се създава DWORD Key с име „Tcp1323Opts” и стойност 3 (0 е изключено, 1 е MSS и Window Scaling, 2 е TimeStampOnly и 3 e MSS и TimeStamp).

PMTU е Path Mtu Discovery. MTU е максималният по размер пакет преминаващ през дадена медия. Например по подразбиране за Ethernet тази стойност се движи в промеждутъка между 1514 и 10000 байта. Но IP пакета може да бъде до 65535 байта дълъг. За да бъде пренесен през медия, която поддържа по-малки пакети той се фрагментира на фрагментчета, които натоварват процесора на маршрутизаторите и особено в миналото фрагментацията е забавяла значително скоростта на комуникация. И тук идеята е проста – ако изпращащата данни машина ги форматира в пакети не по-големи от най-малкото MTU по пътя на трафика, никога няма да се налага фрагментация и комуникацията ще върви спрямо RFC1323 (MSS, виж предната опция) максимално бързо и с големи сегменти. Обаче как да разберем кое е най-малкото MTU? И тук идва PMTU-то. Използва малък трик – слага бит в IP пакета, който забранява фрагментацията. Така маршрутизатор, който види медия с по-малко MTU от размера на пакета няма да го фрагментира. Вместо това той ще го дропне и ще върне ICMP MTU Error в чието съдържание ще запише размера на MTU-то. Изпращащата машина ще го вземе в предвид и няма да изпраща повече към този peer пакети с по-голяма от посочената дължина. Този трик оптимизира ефективно работата най-вече на RFC1323, но е приложим и в други ситуации. За съжаление е изключен по подразбиране от масовият Windows, и се налага да си го включвам на ръка:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters се създава DWORD Key с име „EnablePMTUDiscovery и стойност 1.

PMTU Black Hole Detection е необходимо в следните ситуации – понякога стари маршрутизатори не връщат MTU-то на медията, заради която дропват по-големият пакет. Но по-лошото е ако ICMP-то е изфилтрирано. В не малко Интернет доставчици работят хора с „ъкъл море – глава шамандура”, които не знаят как работят протоколите в Интернет и излизат с идеи, които са крайни и смешни. Когато по Windows се разпространяваха червеи проверяващи на къде да отидат с ICMP echo request, те филтрираха всички ICMP-та. Без да разбират че ICMP е контролен протокол, той се използва и в нормалната комуникация (например ICMP source quench е NACK алгоритъма на TCP-то) и не съществува без причинно и никога не трябва да се изфилтрирва. Винаги има друг начин от бруталното отрязване на цялото ICMP. Така или иначе ефекта бе че ICMP не минава и следователно PMTU-то не минава. Представете си как реагира TCP-то в този случай – изпраща пакет от 1500-байта, той се дропва някъде защото е много голям, но машината не разбира това понеже няма ICMP. Тя си мисли че е дропнат поради претоварване например. И го изпраща пак – 1500 байта. И се получава същото. Така няколко пъти, докато на края сесията се прекъсне или Window Size не падне под размера на MTU-то по пътя. Ефекта за потребителя – сесията се отваря, тръгва бързо и изведнъж зависва, и започва да влачи много бавно, от време на време някакви данни. Случвало ли ви се е? На мен непрестанно. Имаше един момент, когато бе направо епидемия в България. Това не е от Интернета, нито от протоколите, а от умни администратори не разбиращи как работят комуникациите в Интернет. Този ефект се нарича MTU black hole. И има различни алгоритми за откриването му (например ако получим ICMP отговор без MTU вътре слагаме MSS-а на най-малкото възможно разрешено MTU – 576, ако пък не получаваме ICMP за отговор на определени времена правим проби – с различни размери, често директно падаме до 576). Black Hole Detection по принцип не би трябвало да е необходим ако най-големия враг на комуникацията не са хората, които конфигурират мрежите. Но за съжаление е необходим. В Windows той е изключен по подразбиране. Освен в Windows 2003 SP2, Windows XP SP3 (oще не излязъл) и Windows Vista SP1. Ето как се активира изрично:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters се създава DWORD Key с име „EnablePMTUBHDetect и стойност 1.

Half Open TCP сесиите е един от най-големите проблеми в конфигурацията по подразбиране на Windows. Когато една TCP сесия се установява, докато не е преминал целият 3-way handshaking тя не е отворена, но заема ресурси в таблиците на сесиите. Така това позволяваше една от най-елементарните атаки в миналото (от преди 10 години) – така наречената SYN Flood атака. Изпращаш много TCP пакети „отварящи” сесия, и машината получаваща ги започва да се претоварва създавайки огромни структури за хилядите TCP сесии. Преди 10 години тези проблеми бяха решени в Unix света чрез различни трикове и промяна на вътрешната архитектура. Днес те не постигат никакъв ефект. Windows пък бе пазен от Firewall-и базирани на Unix/Linux или някаква RTOS (макар на вас като потребители да изглеждат като Black Box), който да ограничава този тип атаки да стигат до тях. Но от Windows XP SP2 и Vista, Microsoft реши да се пребори с този проблем, по истински Microsoft-ски начин – а именно ужасно некадърно. Сложена е квота на количеството Half-Open TCP сесии, които може да има машината. И тази квота е 10 за XP SP2, и Vista. Но за Vista Home е 2, а за Vista Ultimate е 25 (малко грозен номер да ограничават използването на машините за сървъри, и да ги разделят по мрежова производителност). Вярно, това решава проблема – не може никой да претовари Windows-а. Нещо повече, не можете и да претоварвате чужди машини със софтуер инсталира на Windows и нормална употреба на WSock32 (защото има начин). Но същевременно в типично монополистки стил, решението отваря повече проблеми, отколкото е решило. Сега ако ползвате софтуер, който агресивно отваря TCP сесии за да постигне по-висока производителност (Emule, BitTorrent, Opera, Firefox с fasterfox или просто имате много програми или сървъри на компютъра) той ще забакне, защото отварянето на TCP сесия, когато квотата е изчерпана се забавя докато се освободи място. В резултат се получава следният видим ефект – пуснали сте си bittorrent и след това отваряте browser. И виждате че bittorrent-а тегли с да речем 30K/sec а Browser-а ви се влачи, при условие че нормално би трябвало да постигате скорости от 2MB/sec. Като спрете torrent-а, и всичко се оправя. Кой ли е виновен… Торента? Интернет доставчика ви? Microsoft? И тук предубедените към Microsoft познават. Да ги обвиниш първи за проблем, на който не му знаеш причината си е направо „safe bet” – като да заложиш на сигурно. Можете да проверите дали имате този проблем като отворите EventViewer и гледате дали имате грешка с ID 4226. Как се оправя това? Не особено лесно – трябва да подмените tcpip.sys с такъв от Windows XP SP1. Обаче трябва първо да го направите в dllcache под директорията на Windows. Защото Microsoft измисля едни убийствено смешни защити, които само затрудняват потребителите, но не и хакерите. Какво прави dllcache? За да не може някой да подмени системен DLL на Windows (например едно време троянските коне правеха така – подменят DLL-а за Wsock или за keylogger-а, и когато стартираш програмка зареждаш техният код, а те зареждат преименувания оригинален DLL и проксират извикването на функциите, а те си логват каквото искат, пък не ги виждаш като процеси в паметта). И как Microsoft се пазят от това? Копират всички системни DLL-и на две места (така че те заемат поне два пъти място) и един процес на 10 секунди гледа дали в Windows/System всеки DLL/SYS е същия като в dllcache. Ако не, копира dllcache, освен ако този в dllcache няма по-нова дата от този в System32. Ако е така пробва следния трик – първо гледа дали в инсталационния път го има този DLL, ако да го копира от там (тоест ако сте си направили „backup” на инсталационните файлове, както Windows ви предлага по време на инсталация) и на двете места, а ако не го намери задава въпрос „има тука един странен DLL искате ли да се запази или не?” ако му кажеш „не” иска инсталационно CD. Та има как да се подмени tcpip.sys – ако го смениш едновременно в dllcache и в system32 (lock-ването поради зареждане не е проблем, защото то не пречи на преименуване – процеса е прост – преименуваш tcpip.sys на tcpip.org, копираш новия в dllcache и в system32 на мястото на преименуваният и това е, но трябва да стане бързо в рамките средно на 5 секунди, което не е лесно на ръка). Или просто взимаш готов bat файл и той свършва всичко за теб - http://www.mydigitallife.info/2007/04/09/windows-vista-tcpipsys-connection-limit-patch-for-event-id-4226/ или от тук за XP2 SP2 http://www.brothersoft.com/tcpip.sys-patcher-69268.html

В Windows освен това е ограничено количеството TCP сесии, които могат да бъдат отворени по подразбиране. Това се прави поради лошо проектирана вътрешна архитектура на буферите, голямото количество отворени TCP сесии, без значение дали се ползват или не натоварва CPU-то с pooling и сканиране. За това на Workstations по подразбиране това число е 1000 или по-малко, а на Server е 2000. Допълнително е ограничено още при XP SP2 и Vista (не Ultimate Edition). Това се оправя със следният ключ в registry-то:

В HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters се създава DWORD Key с име „TcpNumConnections и аз слагам стойност 10000. Ако сложиш стойност 0, не могат да се отварят никакви TCP сесии. Ще бъде много весело ако някой погоди на някой друг такъв номер.

Също така централно Hash-а на сокетите и преалокирането на буфери за TCP сесиите не е конфигурирано по подразбиране за много сесии и за агресивно отваряне затваряне на такива дори за Windows Server. Вероятно това е така защото малко хора реално разбират как точно тези неща работят и какъв е техният смисъл и как това увеличава производителността. Имайки в предвид външният произход на стека, е много вероятно дори в Microsoft да няма много хора с идея по въпроса. За мен обаче това не е нещо особено тайно, защото стека е като цяло откопиран от BSD 4.4 Lite и който е чел книжките на Стивънс (и по специално TCPIP Illustrated Vol 2) не би трябвало да има проблем с това. Така или иначе аз си модифицирам тези стойности, но не препоръчвам да бъдат модифицирани ако не знаеш какво правиш.

Обръщам внимание, че API-то на Sockets позволява чрез setsockopt повечето от тези параметри да се установяват или променят динамично от програмата, която си комуникира за всяка сесия по отделно. Въпреки това по правило повечето програми не ги пипат, било то защото програмистите не знаят истинското значение на тези стойности, или било то за да оставят администраторите да конфигурират нещата през OS-а според ситуацията. Много малко програми (като някой bittorrent клиенти и emule) позволяват конфигуриране на тези стойности от програмата, и то само ако изрично сте отбелязали, че желаете да го направите.

Като цяло в повечето версии на Windows TCPIP сокетите са реализирани като външна библиотека. Постепенно от Windows 2000 нагоре започват да вкарват елементи в Kernel-а (tcpip.sys, afd.sys) но все още основната част от API-тата и обработката е на ниво библиотека. Конфигурациите на hash-овете, буферите, pooling-а, event-ите са изключително консервативни и ориентирани към машини с малко сесии, което е нормално, предполагайки се затворена „enterprise работа на OS-а. Разликите между различните видове ОС на Microsoft в повечето случаи са само конфигурационни (ако се абстрахираме от разликата в цената) и могат да бъдат лесно компенсирани. В Интернет трябват устройства с други настройки и по подразбиране Windows не е особено подходящ. Не е подходящ за всякакви приложения с агресивно отваряне затваряне на сесии (Network Management, новите сървъри), освен ако някой сериозно не си поиграе да го пренастрои (и то не само по параметрите, които отбелязах). Това се и вижда на независимите сравнения Linux-Windows – винаги на първи тест Network Performance на Linux излиза по-добро (а то например е по-консервативно конфигурирано по подразбиране от това например на FreeBSD) и едва ако Microsoft изпратят „специалист” на втори тест разликите излизат по-малки или в полза за Windows, докато някой не настрои и LinuxJ Може да звучи смешно, 98% от прокламираните разлики в производителността се дължат на не оптимизирани настройки.

Пиша всичко това, защото вчера ми се налагаше да тюнвам” поредната машина, и малко се издразних. Скоро ще излезе Windows XP SP3 и в него ще има някой добри поправки в конфигурацията по подразбиране на мрежовият стек на Windows. На обратно обаче, ще се наложи отново да си оправям Half-Open TCP сесиите, защото както споменах тук ограничението е заради пазарни интереси, а не поради друго.

Автор: Делян Делчев


 

Добавете коментар

Вашето име:
Заглавие:
Коментар:
  Кодът за потвърждение. Само малки символи без разстояния между тях.
Секретен код:

последно от форума

в МРЕЖИ от maxell, 24-07-10 16:43
в Софтуер от Svilen.Dimitrov, 25-06-10 11:59
в МРЕЖИ от protoberans, 16-06-10 13:23
в МРЕЖИ от mnk, 12-06-10 19:14
в Романтика, любов и секс от 4oki, 07-05-10 09:04

Поща



Не си логнат.

Ако това което четете тук ви харесва гласувайте за нас!
Ако това което четете тук ви харесва гласувайте за нас!

Кой е на линия

В момента има 73 посетителя в сайта