Карманный Groupware-сервер: оценка производительности

в 4:19, , рубрики: groupware, httpd, nginx, контроллеры, Программинг микроконтроллеров, Сетевые технологии, метки: , , , ,

Интернет пришел в Россию в 1995-96гг. Среднестатистическим компьютером тогда был AMD 486DX150 или Intel Pentium100 с RAM 4-8 Mb и HDD 100-400 Mb. Как раз тогда появился Windows 95, и именно новая ОС и потребовала апгрейдов железа до указанных величин, т.к. на типичных для 94го года компьютерах 486 SX25 или DX66 с 2-4 Mb Win95 еле ворочался. Интернет-серверами и роутерами у провайдеров в те годы были точно такие же машины, или даже более слабые, т.к. Linux тогда еще вполне комфортно себя чувствовал на 2 Мб (без GUI), сайты были в основном статическими, и почтового спама еще не было. Доступ к интернету имел в лучшем случае один на тысячу человек — по нескольку сотен человек в среднем российском областном центре, и все они работали через единичные провайдерские почтовые и веб-серверы. То есть один сервер указанной ничтожной по современным меркам конфигурации обслуживал примерно столько человек, сколько сейчас интернет-пользователей в довольно крупном предприятии. И справлялся…

Есть ли сейчас компьютеры сопоставимой мощности (если слово мощность еще применимо к такому железу), и как они используются? Есть. Нет, это не роутеры и тем более не смартфоны — те и другие заметно производительнее, даже если рассматривать только домашние роутеры и самые простые телефоны. Роутеры легко прокачивают 100Мбит, а телефоны легко крутят видео, да и память у телефонов на сотни мегабайт — ничего такого и близко не было в 96м году. Надо искать более слабые процессоры сопоставимые с Pentium100, то есть около 100МГц или до 200 DMIPS…

Самый близкий кандидат для сравнения — микроконтроллер ARM Cortex-M3 или -M4. У первого частота чуть меньше 100МГц, у второго чуть больше, декларируемая производительность 125-210 DMIPS (2.19 CoreMark/MHz — 1.25 DMIPS/MHz — как раз как у Пентиума в 96м). Встроенная SRAM контроллера всего около 100Кб, но к контроллеру можно подключить мегабайты внешней SDRAM, работающей как раз на той же частоте, что у первых Пентиумов. Итого получим примерный эквивалент материнской платы тех лет, но размер всей платы будет меньше сокета Пентиума, и потребляемая мощность на порядок меньше тогдашних (всего 10-Ваттных!) Пентиумов.

Как и что будем сравнивать, и главное зачем. Будем измерять производительность Cortex-M3 на нетипичных для него сетевых задачах. Ethernet-контроллеры во многих Cortex-M3 есть, причем в вариантах фирмы TI даже с встроенным PHY (т.е. не требует никаких внешних чипов, подключается сразу к MagJack'у RJ45), но считается, что использоваться это должно либо для промышленной автоматизации — гонять по сети команды управления/мониторинга, либо в быту — сетевые счетчики потребления коммунальных услуг, управление «умным домом» и т.п., т.е. задачи важные, но совсем «из другой оперы». Но раз по предполагаемой производительности он соответствует серверам, которые в прошлом «сервировали» целые города, то может не стоит ограничиваться этой традиционной нишей и имеет смысл оценить применимость контроллера для серверных задач? Не в масштабах интернета, а для локальной сети. Во времена, когда космические корабли бороздят просторы Вселенной, а ИТ-отделы предприятий аутсорсят свои внутренние задачи во внешние облака, задача поставить реальный сетевой сервис на машину, которая в сотни или тысячи раз медленнее обычного офисного ПК, может показаться бессмысленной. Но с другой стороны, если контроллер (вдруг) справится с поставленной задачей, то не делает ли это бессмысленной аппаратную «гонку вооружений» при решении этой конкретной задачи? И не в этом ли и состоит наша инженерная работа в конечном итоге — повышении эффективности работы, в т.ч. и за счет уменьшения затрат на производство? Чтобы либо (1) производилось больше за те же деньги, либо (2) столько же работы, но за меньшие деньги. Мы будем выяснять пределы наших возможностей по второму варианту.

Теперь о выборе тестовой задачи. Есть одна ИТ-задача, в которой объемы операций постоянны во времени, потому что ограничиваются не возможностями техники, а производительностью самого медленного участника техпроцессов — человека. Причем выключить это слабое звено из процесса в данном случае не получится к сожалению (или к счастью), потому что этот процесс самый человеческий — процесс принятия решений! — его человек предпочитает не поручать пока технике, т.к. техника с такими возможностями может принять решение, что человек не нужен… В чем состоит суть процесса: человек анализирует текущую ситуацию (по доступной ему информации) и решает, что делать дальше, фиксируя это решение либо в непосредственных физических действиях, либо в изменении внутреннего состояния («теперь я знаю что делать» или «я подумаю об этом завтра...»). Если не считать мелких автоматических решений, принимаемых на автопилоте — куда поставить ногу или из какого кармана достать телефон — а считать только осознанные решения, требующие фиксации внимания, то «тактовая частота» человека составляет не больше 200-300 решений в день. Если же человеку приходится синхронизировать все свои решения с другими людьми, т.е. совместно одновременно решать общие задачи, то индивидуальная производительность падает на порядок — едва ли можно провести более 20 совещаний в день, а ведь еще нужно время на подготовку информации и на претворение решений в жизнь (лично или поручив другому, что тоже требует синхронизации)… Компьютерные Groupware-системы (GWS) призваны повысить эффективность совместной работы, и сделать это они могут только превращением синхронных событий в асинхронные, исключая блокировки и ожидания между людьми: после решения/выполнения очередной задачи человек должен тут же получать от GWS полную информацию для принятия следующего решения. GWS при этом работает подобно планировщику задач в операционной системе, а люди работают подобно кассирам в супермакетах — каждый выполняет свою работу на пределе своих собственных возможностей (если к нему очередь покупателей, т.е. «задач»), работая только со своей очередью, не отвлекаясь на взаимодействие с коллегами (любое такое взаимодействие типа обращения к соседнему кассиру «Лена, разменяй 5тыщ» тут же заметно стопорит сразу две очереди), коллеги должны работать асинхронно — обеспечить запасы разменной монеты, кассовых лент, товаров на полках, покупателей в зале и т.д.

Таким образом в GWS можно оценить требуемую максимальную производительность системы: 200 умножить на количество пользователей системы. На практике, конечно, такие параметры потребуются только в очень хорошо проработанных организационных процессах. Типичным для небольшого офиса или предприятия (до 100 человек) будет скорее 200-300 решений в день на всех, тем более что далеко не все события находят отражение в GWS. Будем считать, что несколько тысяч в день закрывает (с запасом) все текущие потребности типичного офиса — для почти любой отрасли и независимо от развития технологий вокруг.

Если вы еще здесь, то начинаем переводить это в компьютерный язык. Что представляет собой событие или задача в GWS? Сообщение электронной почты, событие в календаре, задача в трекере, заявка/счет на сайте и т.п. В большинстве случаев такой файл или запись в БД имеет размер от единиц до десятков КБ. Я посчитал средний размер задачи в наших календарях (ics-файлы формата VCALENDAR с задачами VTODO или событиями VEVENT внутри) за несколько лет — 700 байт. Сообщение форума — полтора КБ. Страница внутренней wiki — 4 Кб. Письмо в техподдержке — 12 КБ (часто с прикрепленными файлами, т.е. средний размер собственно текста намного меньше). При таких размерах можно оценить объем новой информации для одного сотрудника в 1МБ в день и не более 50МБ в день для всего офиса (с учетом того, что многие элементы GWS адресованы нескольким получателям). Если объёмы выше, то значительная часть задач не будет выполнена никогда — просто физически не успеют обработать — будут удаляться без прочтения или висеть вечно (или автозакрываться/архивироваться «за давностью», что то же самое). При таких объемах информации GWS-сервер на базе современного ПК может кэшировать в RAM задачи за несколько месяцев, может «отгружать» все задачи одного сотрудника за день менее чем за одну секунду, хранить в оперативном доступе на диске все задачи всего офиса за несколько лет, и т.д. Понятно, что в зависимости от форматов баз данных, используемых протоколов, используемого серверного и клиентского ПО эти параметры могут варьироваться в широких пределах, различаться на порядок, но также понятно, что мощности обычного ПК для этих задач хватает с огромным запасом. Значит можно попробовать выполнять ту же задачу на менее мощном железе.

Производительность сервера при таких небольших объемах и применении кэширования можно считать не ограниченной в случае ПК, а для контроллера числа такие: Cortex-M3 на 80МГц копирует SDRAM-память со скоростью 16 МБ/с (средствами процессора, без использования DMA), отправляет TCP/IP-данные через 100 Мбитный встроенный Ethernet-контроллер со скоростью 4-5 МБ/с (тоже без использования DMA, т.е. есть резервы оптимизации). Выходит, что в идеале контроллер синхронизирует все календари за считанные минуты, причем для отдельного пользователя это можно сделать вообще за секунду. Но на практике все обычно очень далеко от идеала, зависит от протоколов и сценария работы.

Предположим, что для работы с событиями/задачами пользователи используют календарные-клиенты с протоколами WebDAV/CalDAV (Outlook, Evolution, SunBird, Thunderbird+Lightning и т.п. на настольных ПК, iCAL на iPhone/iPad, и т.д.), а сервер соответственно любой веб-сервер с поддержкой этих протоколов. Но мы будем тестировать не производительность клиентского ПО (ясно, что она достаточна на современных ПК), и не производительность конкретных моделей GWS (ясно, что они тормозят в широких пределах), а соотношение сил контроллера и ПК в сетевой работе на задаче этого типа. При синхронизации календарей клиентское ПО использует несколько HTTP/WebDAV-команд — OPTIONS, PROPFIND, GET, PUT — основное время проводя в команде PROPFIND, которая выбирает из списка событий на сервере подмножество, удовлетворяющее заданным критериям. Принцип примерно как при получении почты — выясняется «что нового» и скачивается новое, плюс (в отличие от почты, но подобно например новостям NNTP) выясняется, чего нет на сервере, и передается командой PUT. Мы для упрощения будем на первом этапе тестировать только GET, программой ApacheBench. Запустим множество параллельных отдельных коротких соединений с одиночными GET-запросами, имитируя неоптимальных клиентов, получающих по одной задаче. Запустим длинные соединения с несколькими GET в режиме Keep-Alive, имитируя PROPFIND с multiget'ом внутри. И будем получать в каждом тесте по нескольку сотен коротких файлов, имитируя сеансы синхронизации отдельных пользователей, получающих все задачи за один или несколько дней.

Железо. Будем сравнивать офисный ПК на экономном процессоре AMD E350 (потребляемая мощность близка к первым Пентиумам или современным Atom'ам, а производительность на два порядка выше первых Пентиумов и заметно выше, чем у Atom'ов) с 4GB RAM и коробочку 6x6 см HonixBox с ARM Cortex-M3 (TI LM3S9B95) и 8 MB RAM внутри. Они подключены к одному и тому же 100Мбитному коммутатору в одном кабинете и отделены еще двумя коммутаторами (гигабитными) от компьютера в том же офисе, на котором запускается ab, имитирующий клиентов.

Софт. На ПК работает Windows 8 beta 64bit, в качестве сервера nginx/1.0.14 (текущая стабильная сборка) для Windows. На HonixBox — самодельный веб-сервер на самодельной ОС, скомпилированных самодельным компилятором (никакой спец.оптимизации под эту задачу — сервер был написан для выдачи сетевой статистики, основной «профессии» HonixBox'а; на ассемблере во всей системе написано около 500 байт кода, все остальное написано на Форте без какой-либо оптимизации, т.к. исходная задача HonixBox'а была предельно проста, почему и была реализована на контроллере).

Тестируем. Сначала я хотел запрашивать "/" на HonixBox (небольшой скрипт, выдающий страницу с текущими настройками HonixBox и суммарной статистикой), а на nginx запускать PhpInfo(), но PHP под Windows в FastCGI-режиме не доживает под управлением nginx до 500 запросов — слетает. Не стал пока разбираться (первый раз в жизни запускал nginx), переключился на статические файлы, тем более что календари под WebDAV — наборы статических файлов.

ab -n 500 -c 100 192.168.0.156/favicon.ico (единственный файл на HonixBox'е, по размерам близкий к VTODO; а на nginx запрашиваем более короткий index.html) — имитируем получение 500 отдельных задач сотней клиентов одновременно.

Результат nginx:
Time taken for tests: 1.994990 seconds
Complete requests: 500
Failed requests: 0
Write errors: 0
Total transferred: 181000 bytes
HTML transferred: 75500 bytes
Requests per second: 250.63 [#/sec] (mean)
Time per request: 398.998 [ms] (mean)
Time per request: 3.990 [ms] (mean, across all concurrent requests)
Transfer rate: 88.22 [Kbytes/sec] received

Результат HonixBox:
Time taken for tests: 10.466127 seconds
Complete requests: 500
Failed requests: 0
Write errors: 0
Total transferred: 211500 bytes
HTML transferred: 159000 bytes
Requests per second: 47.77 [#/sec] (mean)
Time per request: 2093.225 [ms] (mean)
Time per request: 20.932 [ms] (mean, across all concurrent requests)
Transfer rate: 19.68 [Kbytes/sec] received

Пятикратное превосходство ПК над контроллером. Обращаем внимание на низкую итоговую скорость передачи в обоих случаях — всего 20-90 КБ/с. Скорее всего скорость ограничена в основном задержками на установку/разрыв множества TCP-соединений (стороны ожидают подтверждений друг от друга). Но к-во запросов в секунду вполне соответствует типичной скорости синхронизации календарей или получения email.

Убираем -c, добавляем -k (Keep-Alive) — Nginx ускоряется до 259 запросов в секунду, HonixBox до 52, т.е. однопоточный вариант (отдельный клиент получает 500 задач за 2с с Nginx и за 10с с HonixBox). Добавляем -c 10 (10 клиентов получают по 50 задач каждый одновременно) — Nginx ускоряется до 424 з/с, а HonixBox остается на 52, проигрывая в этот раз восьмикратно.

Результаты хуже, чем я ожидал — даже закрались подозрения, что что-то не то с ApacheBench под Windows — но итоговое соотношение сил ПК и контроллера наверняка от «ab» не зависит. И оно показывает, что ограничивающим фактором является не скорость процессора, а сеть (хотя по FTP между этими двумя машинами скорость 11МБ/с — в 100 раз больше, чем типичная скорость в приведенных выше тестах) и еще более схема работы — множество мелких объектов, получаемых отдельными HTTP-запросами. Ну а самое главное — разница в скорострельности ПК-сервера и контроллера-сервера всего 5-8-кратная, а не хотя бы 50-кратная, как можно было ожидать, и при этом у софта на контроллере еще непаханное пространство оптимизации, и у ПК огромный резерв неиспользованной мощности — Nginx в этом тесте напрягаться не пришлось, он в основном находился в ожидании в/в. Но и в текущем варианте оба сервера выдают данные как раз с такой скоростью, какая (или даже более низкая) обычно наблюдается при работе например в Lightning с реальным WebDAV-сервером. Т.е. пользователь вряд ли заметит разницу. Тем интереснее будет сравнить ПК и контроллер в реальной работе в режиме Groupware. Этим займемся в следующий раз, если кому-нибудь кроме меня тоже интересно.

Автор: forth


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js