Информационная безопасность
[RU] switch to English


Хакер-спец #7 20063APA3A

Производительный файловый сервер под Windows

Часть никакая - размышления без воспоминаний.

Без лишних вступлений начнем с мысли о том, что такое файловый сервер, как он функционирует и что нам потребуется, чтобы сделать файловый сервер как можно более шустрым, например, чтобы как можно полнее использовать нашу гигабитную сеть. На первый взгляд все просто. Пришел клиент, попросил файл, слазили на диск за файлом и отдали клиенту. Куда проще. На второй и более продвинутые взгляды - все гораздо сложнее. Файловый сервер это нечто большее, чем просто сетевой интерфейс к жесткому диску. Конечно, скорость чтения у современных винчестеров не маленькая, но что будет, когда придет не один клиент, а несколько десятков? Кроме того, что придется делить это самое чтение между клиентами, придется еще и прыгать, считывая данные из разных мест диска. А время доступа величина уже довольно приличная: Механика, блин, никакой производительности. Чтобы все работало быстро, и клиенты от работы с файловым сервером имели то же впечатление, что и от работы с локальным диском, надо эту механику как-то заменить на электронику. Т.е. клиенты должны получать данные не с жесткого диска, а из оперативной памяти, которой должно быть достаточно. Стандартный механизм работы файлового сервера -

Диск -> память -> сеть

Следит за всем этим, разумеется, процессор.

Итак, возьмем за исходное то, что нам следует:

  1. Много работать с памятью, перемещая данные с жесткого диска в память и из памяти - в сетевой адаптер.
  2. Делать все это одновременно.

Сделать быстрее передачу каких-либо данных можно двумя с половиной способами - увеличить скорость передачи (например, частоту шины) или распараллелить передачу.

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

Больше всего работа файлового сервера напоминает работу сердечно-сосудистой системы с двумя кругами кровообращения. И, как мы увидим дальше, экономить на нем сложно.

Часть первая - выбираем платформу.

64 бита бум?

Область оперативной памяти, в которой хранятся данные, полученные с диска, называется в Windows системным кэшем. Чем больше системный кэш, тем реже нам приходится лазить на диск за данными. Мы устраняем необходимость передачи данных с диска в память. Пол дела сделано без каких-либо усилий. 32битное адресное пространство составляет 4GB адресуемой памяти. Именно столько может адресовать любое 32битное приложение, включая и ядро самой системы. В Windows приложение может использовать 2GB (3GB при наличии ключика /3GB в boot.ini, но нас это интересовать совершенно не будет) под свои данные. Из этого следует неприятный факт - для 32битной версии Windows максимальный размер системного кэша составляет 1GB (точнее, даже несколько меньше), что по современным меркам не много. И втыкание в файловый сервер более 2Gb памяти не только не поможет, но и усугубит ситуацию, за счет менее эффективного использования процессорного кэша. Устраняется все это использованием 64 битных платформ. 64 битная версия Windows 2003 поддерживает системный кэш до 1TB. Таким образом, файловый сервер это именно то приложение, в котором использование 64 битной платформы не будет лишним, если мы хотим добиться эффективного кэширования.

Чип и сет спешат на помощь.

Давайте теперь полюбуемся на то, почему нельзя использовать в хорошем файловом сервере десктопные чипсеты, пусть даже очень хорошие и производительные. Посмотрим на примере двух <пограничных> чипсетов по разные стороны границы между сервером и рабочей станцией от Intel. У других производителей дела обстоят аналогично, но у Intel гораздо легче найти нужные картинки. Сравним самый производительный десктопный чипсет 955X (Intel выносит такие чипсеты в отдельную категорию между десктопами и серверами, которую называет "Workstation") и минимальный серверный чипсет начального уровня E7230. Характеристики чипсетов абсолютно идентичны - частоты памяти, пропускные способности шин, поддерживаемые процессоры и схема южного моста.

Отличия видны, если посмотреть на диаграммы чипсетов:

Intel 995X

рис. 1 - диаграмма чипсета высокопроизводительной рабочей станции Intel 995X.

Intel 7230

рис. 2 Диаграмма чипсета сервера начального уровня Intel E7230

Вопрос в том, куда мы будем бросать кости, в смысле втыкать оборудование. В 955x скоростная 8-Гигабитная шина PCI Express x16 используется для графики. Для подключения дисковых и сетевых адаптеров мы можем использовать PCI или PCI-X через южный мост (ICH7R). Но производительность шины DMI между южным и северным мосто составляет <всего> 2GB/s, которые будут делиться между диском и сетью. Шина синхронная и здесь гигабайты, а не гигабиты, т.е. скорость вполне приличная, но все же... Серверная платформа имеет дополнительный PCI Hub, обеспечивающий подключение к портам PCI-X через шину PCI Express x8 и порты PCI Express x8 и x4, позволяющие на полную использовать даже 10 гигабитный Ethernet, причем при всем этом дисковая подсистема сможет использовать другую шину. Чем <сервернее> платформа, тем <севернее> располагаются скоростные периферийные шины и тем больше этих шин подключено непосредственно к северному мосту, позволяя с минимальными задержками перемещать данные от внешних устройств к памяти и процессору.

Память

С памятью все ясно. Этот ресурс для нас самый критичный, поэтому память должна быть максимально шустрая.

Процессор? Какой процессор?

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

  1. Как ни странно это звучит для знатоков параллельных вычислений, лучше два медленных процессора, чем один быстрый, и чем больше различных контроллеров и адаптеров мы имеем, тем больше преимуществ от многопроцессорности мы получим.
  2. Чем больше параллельных обращений к памяти (больше системный кэш), тем сильней влияет размер процессорного кэша. Причем кэши двух разных процессоров не суммируются.
  3. Много мощных процессоров потребуется, когда мы дойдем до многогигабитной сети.
  4. Частота шины процессора может влиять на частоту шины памяти. Поэтому надо выбрать процессор, работающий с частотой шины, не замедляющей работу с памятью.

Сетевая подсистема.

Как мы уже подсчитали, 1 Gb/s (Гигабит в секунду) и 1GB/s (Гигабайт в секунду) - это совсем не одно и тоже. Если мы будем смотреть на гигабитный Ethernet, то реальная скорость передачи за более-менее длительный период времени в нем будет не более 90 MB/s по одному порту из-за асинхронности шины. И, чтобы обслуживать большое количество клиентов, гигабитного Ethernet может быть недостаточно. Первая альтернатива    перейти на 10 гигабитный Ethernet, что дорого и не очень стандартно. Особенно это касается адаптеров, способных работать по скоростным версиям PCI-X или PCI Express x4/x8. Подобное решение может окупиться на серверах корпоративного уровня. В качестве более дешевой   и менее скоростной альтернативы можно иметь много гигабитных адаптеров. Драйверы многих адаптеров позволяют объединять их в один виртуальный для повышения производительности. Но запомним, что такой режим работы может вызвать недоумение у некоторых коммутаторов (свитчей) и обязательно требует тщательного тестирования. Производительности шины PCI не хватает даже для гигабитного адаптера, с учетом дуплексной передачи, лучше, конечно, использовать PCI Express или PCI- X адаптеры. Не рекомендуется использовать сдвоенные адаптеры. Для Ethernet 10 Gb/s необходимо использовать порты PCI-X 266/533 или   PCI Express x4/x8. PCI-X - синхронная шина и реальная ее производительность близка к максимальной 1 GB/s для PCI-X, 2 GB/s для PCI-X 266 и 4 GB/s для PCI-X 533.   PCI Express - асинхронная шина и реальная скорость передачи ниже теоретической максимальной. Но идеологически к Ethernet ближе PCI Express.

В большинстве современных адаптеров поддерживаются возможности "TCP Offload" - т.е. перенос вычислительных задач, связанных с организацией сетевого соединения с процессора на сетевую карту. Обычно поддерживается выполнение как минимум двух задач: вычисление контрольных сумм пакета (Checksum Offload) и сегментирование больших пакетов (TCP Segmentation offload, в некоторых драйверах Realtek и HP это называется TCP Large Send Offload). Для производительного сервера на гигабитных скоростях эти задачи критичны, т.к. составляют до 30% всех вычислительных задач сервера из-за того, что весь поток данных пойдет в процессор для вычисления контрольных сумм. Поэтому очень важно, чтобы сетевой адаптер выполнял эти задачи, причем выполнял корректно. В случае, когда необходимо шифрование трафика, сетевой адаптер должен поддерживать и IPSec Offload. Адаптеры с поддержкой IPSec стоят существенно дороже, но даже на них производительность в несколько гигабит останется мечтой.

Дисковая подсистема

Первый вопрос - SCSI или SATA.

Если мы не гонимся в сторону сотен мегабайт в секунду, то сойдет и SATA. Для высокопроизводительных систем, конечно все-таки SCSI. Недостаток решений на шине SCSI - маленькие объемы и высокая стоимость на единицу объема. Но она быстрее. 320 MB/s в Ultra320 SCSI это процентов на 10% быстрее, чем 3 Gb/s в SATA II, опять же из-за фокусов последовательной шины, которой является SATA. Реальная устоявшаяся скорость чтения/записи передовых моделей SCSI дисков так же примерно в полтора раза выше, чем дисков SATA-II, приближаясь к 100 MB/s. Еще одно преимущество дисков SCSI - их гораздо проще набить в большом количестве. Чем больше мы набьем дисков, тем выше будет производительность дисковой подсистемы, т.к. доступ к дискам может осуществляться параллельно. Конечно, имея в распоряжении практически <халявный> SATA, грех им не воспользоваться хоть как-то, например, разместить на нем систему или даже часть данных.

Исходя из приведенных цифр, можно настоятельно порекомендовать использовать двухканальные или четырехканальные SCSI контроллеры и не вешать на канал SCSI более 2-3х дисков. При необходимости иметь более 6 дисков, надо иметь четырехканальный контроллер, использовать несколько контроллеров SCSI или смотреть в сторону более скоростных интерфейсов, таких как Fibre Channel. На сегодня имеется уже достаточное число производительных контроллеров SCSI, например, MegaRAID от LSI с поддержкой PCI Express до x8. Нам вполне хватит PCI-X или PCI Express x4 для хорошо набитого дисками двухканального контроллера, но обычного PCI Express будет маловато. Идеологически SCSI адаптер ближе к PCI-X.

Второй вопрос: какой RAID использовать?

Вопроса, использовать ли RAID для файловых серверов, не стоит. Задачи для RAID в данном случае две - обеспечить отказоустойчивость дисков и максимально повысить быстродействие дисковой подсистемы за счет распараллеливания записи и чтения по дискам. Конечно, самый быстрый RAID - это RAID 0. Однако отказоустойчивостью он не обладает. RAID 5, к сожалению, замедляет операцию записи, особенно при записи небольших кусков данных, но при этом остается весьма быстрым на чтении. Это следствие необходимости пересчитывать и перезаписывать контрольные суммы во время записи неполного блока. Хорошо сбалансированную производительность на чтение и запись имеет RAID 10 (один-ноль), но при этом мы теряем половину емкости дисков. Поэтому, можно порекомендовать RAID 10 для хранения данных, с которыми идет постоянная работа,   например, текущих документов, RAID 5 для различных архивов и хранилищ и RAID 0 для временных данных, таких как кэш оптимизирующего прокси-сервера. Естественно, для более качественного распараллеливания, лучше использовать в RAID'е максимальное число дисков и желательно с разных каналов.

Корпус

Ну, а как вы сами думаете, какой нужно иметь корпус, чтобы в него все это:

  • Влезло
  • Электропиталось
  • Не расплавилось

??

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

Часть вторая - выбираем и тюнингуем систему.

Выбираем систему

С выбором все просто, необходим Windows Server 2003, для 64битной платформы - 64bit edition. Особых преимуществ от Enterprise Edition мы иметь не будем, если не требуется кластеризации. Нам не надо большого количества процессоров, в случае 32 битной версии мы все равно не будем втыкать более 2GB памяти, а в случае 64битной версии ограничения по объему памяти не критичны.

Лучше использовать англоязычную версию системы на серверах  - в случае возникновения проблем легче найти соответствующую статью в базе знаний Microsoft.

Настраиваем систему

Собственно, стандартная настройка системы под файловый сервер минимальна. В свойствах сетевого подключения необходимо открыть свойства File and Printer Sharing for Microsoft Networks (службы доступа к файлам и принтерам) и поставить жирную точку на Maximize data throughput for file sharing.

Оптимизация Windows под файловый сервер

Рис.3 выбор оптимизации Microsoft File Sharing

В Windows NT была ошибка, значения Maximize data throughput for file sharing и Maximize data throughput for network applications были инвертированы, но в Windows 2003 этот недостаток устранен, но часто можно встретить устаревший, а потому неправильный совет менять их местами.

Создаем необходимые разделы на жестких дисках, разумеется, используя файловую систему NTFS. Устанавливаем необходимые разрешения доступа (ACL). Список ACL должен быть как можно короче. Правильный список содержит, как правило, 1-2 записи, для обычных пользователей и администраторов. Список ACL проверяется при каждом открытии файла, чем он короче, тем меньше времени требуется для проверки. Microsoft рекомендует следующий алгоритм:  учетные записи пользователей группируются по небольшим глобальным (Domain Global) группам, обычно в соответствии с функциональными обязанностями. Для доступа   к ресурсам создаются доменные локальные (Domain Local) группы, в которые включаются доменные глобальные группы тех пользователей, которым необходим доступ. Это позволяет минимизировать размер как списков ACL, так и списков SID (идентификаторов безопасности) в токене доступа пользователя. Открываем совместный доступ к файлам, настраиваем различные вспомогательные задачи, такие как резервное копирование и дефрагментация. Сервер готов к работе.

Как работает <служба доступа к файлам и принтерам> и системный кэш?

При запуске службы доступа к файлам и принтерам ( LanmanServer) создается пул рабочих потоков (thread pool)   и рабочая очередь на каждый из имеющихся процессоров. Каждый поток <выхватывает> задание из очереди, обрабатывает его и принимается за следующее задание. Что происходит, если клиент пытается открыть файл по сети? Служба перенаправителя (redirector) передает запрос службе клиента для сетей Microsoft (LanmanWorkstation), которая формирует запрос SMB и отправляет его на файловой сервер, службе LanmanServer, где он попадает в одну из очередей в виде <задания> (work item). Когда очередь доходит до него, освободившийся поток берет задание из очереди и выполняет запрос, обращаясь к запрошенному фрагменту файла. При обращении к файлу используется интерфейс MDL (Memory Descriptor List). Если фрагмента файла еще нет в системном кэше, то его необходимо получить с диска. В таком случае, на время работы с файлом <задание> ставится в отдельную блокирующую (blocking) очередь, пока файловая операция не будет завершена и рабочий поток начинает обрабатывать следующее задание из очереди. Интерфейс MDL возвращает список страниц реальной (физический) памяти из системного кэша, по которому находятся запрошенные данные. Если задание находилось в блокирующей очереди - оно переводится в основную очередь и ожидает продолжения обработки. Затем рабочий поток формирует служебные данные для ответного SMB пакета и передает эти данные, а так же полученный реальный адрес из системного кэша сетевому адаптеру. Сетевой адаптер получает данные непосредственно из системного кэша, используя прямое обращение к памяти (DMA), и отправляет их клиенту вместе со служебным заголовком. Таким образом, обращение к данным в памяти происходит всего один раз - сетевым адаптером. Процессор эти данные не обрабатывает. Если клиент записывает какие-либо данные, то они так же меняются в кэше, и сбрасываются на диск, когда он переходит в режим простоя или по мере необходимости.

По умолчанию размер системного кэша составляет всего 8 MB (это для Windows NT и Windows 2000, к сожалению, документации для Windows 2003 пока нет). Установка параметра Maximize data throughput for file sharing (рис. 3) реально меняет два ключика реестра. Ключик Size в HKLM\CurrentControlSet\Services\LanmanServer\Parameters устанавливается в значение 3 (Large). Этот ключик оптимизирует различные параметры рабочих очередей и пула потоков LanmanServer на работу с большим количеством клиентов.  Ключик LargeSystemCache в HKLM\CurrentControlSett\Services\SessionManager\Memory Management устанавливается в значение 1 (on). При этом под системный кэш отводится 80% всей незанятой памяти системы, что ощутимо увеличит производительность выделенного файлового сервера.

Я регулярно слышу что-нибудь вроде <А в наших тестах SAMBA под Linux оказалась быстрее Windows 2003>. Очень часто причиной подобных высказываний является то, что для тестирования выбирается сервер с маленьким кэшем и используется один клиент. Все сетевые операции на клиенте так же кэшируются. Одинаковый размер кэша и алгоритм кэширования приводит к тому, что в кэше клиента и сервера находятся одни и те же данные, т.е. все запросы, которые доходят на сервер, пролетают мимо кэша. Конечно, это приводит к тому, что сервер работает достаточно медленно. Windows 2003 проявит себя по полной, при условии правильного подобранного оборудования, соответствующей настройки, и на достаточно большом количестве клиентов.

Оптимизация и разгон файлового сервера.

Сейчас я всех сильно разочарую. Реальная оптимизация файлового сервера происходит на уровне оборудования, что мы уже обсудили. Тот <разгон>, о котором мы будем говорить, даст выигрыш более 10% только на плохо сбалансированном оборудовании. Устранение узкого места в оборудовании (например, замена процессора) в таком случае даст гораздо лучшие результаты. Как мы видим, работа файлового сервера достаточно проста. Все что мы можем - это сократить какие-либо <начальные> задержки - время, уходящее на открытие/закрытие файла, на простой запроса в очереди и т.д. Все остальное - исключительно вопрос оборудования.

Ввиду особенности работы кэша и обработки очереди запросов, файловый сервер не будет показывать чудеса производительности, если на нем крутятся какие-либо приложения, интенсивно использующие память (особенно с постоянным выделением и освобождением) или неравномерно загружающие процессор. Не стоит давать файловому серверу какие-либо дополнительные роли в сети, кроме, может быть, роли контроллера домена и сервера Active Directory, при условии очень небольшого числа (порядка десятков) пользователей сервера.

Оптимизация работы с оборудованием

Microsoft рекомендует, чтобы в многопроцессорных системах (реально многопроцессорных, речь не идет о технологии гипертридинга) прерывания от одного и того же сетевого адаптера обрабатывались одним и тем же процессором. По умолчанию прерывание может быть обработано любым процессором. Можно использовать IntFiltr ( ftp://ftp.microsoft.com/bussys/winnt/winnt-public/tools/affinity/) для привязки прерываний определенного устройства к одному процессору.

REG_DWORD

HKLM\System\CurrentControlSet\Session Manager\I/O System\CountOperations

Со значением 0 отключает различные счетчики для жесткого диска, что может ускорить операции ввода/вывода.

REG_DWORD

HKLM\System\CurrentControlSet\Services\miniport_адаптер\Parameters\DeviceXX\NumberOfRequests

Аппаратный RAID контроллер может выполнять больше запросов SRB за счет распараллеливания. Рекомендуется поднять это значение в диапазоне от 32 до 96.

REG_DWORD

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\ IoPageLockLimit

Сколько памяти (в килобайтах) может заблокировать система под операцию ввода/вывода. Значение по умолчанию 512 KB. Увеличение этого параметра приведет к увеличению объема данных, которые можно передать за одну операцию. Можно встретить рекомендации увеличить это значение аж до 128Мб, однако, увеличение свыше нескольких мегабайт (например, в пределах 8-16) вряд ли будет эффективно.

Оптимизация параметров файловой системы

REG_DWORD

HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PagedPoolSize

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

REG_DWORD

HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation

Запрещает создание коротких псевдонимов имен файлов. Эта возможность требуется в том случае, если на диске будут храниться данные, обрабатываемые приложениями MS-DOS или Windows 3.x (нужно иметь в виду, что таковыми являются многие инсталляторы). Отключение (значение 1) незначительно ускоряет процедуру создания файлов.

REG_DWORD

HKLM\System\CurrentControlSet\Control\FileSystem\Disablelastaccess

При установке в 1 запрещает изменение времени доступа при обращении к файлу на чтение. Время последнего доступа применяется крайне редко (в отличие от времени создания и модификации). Запрет его обновления позволяет ускорить процедуру открытия файла на чтение.

Оптимизация сетевых параметров

Не плохо бы начать с того, что отключить все неиспользуемые сетевые соединения (для минимизации роутинговой таблицы), протоколы и клиенты. Можно заглянуть сюда:

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TcpWindowSize

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TCP1323Opts

Размер окна TCP.   Размер окна следует увеличить в сетях   с высокой пропускной способностью и большими задержками. Это могут быть: сети производительностью в несколько гигабит в секунду, сильно удаленные сети (через спутник или несколько маршрутизаторов), загруженные сети, в которых достаточно высоко количество устранимых коллизий, сети со слабыми клиентами, например со старыми компьютерами. При увеличении окна (TcpWindowSize) свыше 65,535 (близкое к этому значение используется для гигабитных и выше интерфейсов) следует поставить в 1 значение TCP1323Opts.

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\MaxHashTableSize

Указывает на размер хэш-таблицы TCP-соединений (по умолчанию 128). Максимальное значение - 65535. Оптимальное значение - не меньше числа ожидаемых одновременных подключений. Можно поднять и до максимального значения.

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\интерфейс\TcpAckFrequency

Указывает на сколько TCP пакетов (по умолчанию 2) посылается ACK. Microsoft рекомендует увеличить это значение до 13, чтобы снизить число передаваемых по сети пакетов.

На этом - все. Пишите. Делитесь впечатлениями. Замечаниями. Советами.

Перепечатка данной статьи невозможна без разрешения издательства Gameland

О сайте | Условия использования
© SecurityVulns, 3APA3A, Владимир Дубровин
Нижний Новгород