Итак, вы нашли ключевой момент в использовании «большой нотации O». Это одно измерение, которое, безусловно, может укусить вас сзади, если вы не обращаете внимания. В игре есть и другие измерения, которые некоторые люди не видят сквозь очки с большой буквой «О» (но если вы присмотритесь, они действительно есть).
Простым примером такого измерения является соединение с базой данных. Существуют «лучшие методы» построения, скажем, левого внутреннего соединения, которые помогут сделать SQL более эффективным. Если вы разберете реляционное исчисление или даже посмотрите на план объяснения (Oracle), вы можете легко увидеть, какие индексы используются в каком порядке и происходят ли какие-либо сканирования таблиц или вложенные операции.
Концепция профилирования также является ключевой. Вы должны быть тщательно инструментированы и с правильной степенью детализации во всех движущихся частях архитектуры, чтобы выявить и исправить любую неэффективность. Скажем, например, вы создаете трехуровневое многопоточное веб-приложение MVC2 с широким использованием AJAX и обработки на стороне клиента вместе с OR Mapper между вашим приложением и БД. Упрощенный линейный поток одного запроса/ответа выглядит так:
browser -> web server -> app server -> DB -> app server -> XSLT -> web server -> browser JS engine execution & rendering
У вас должен быть какой-то метод измерения производительности (время отклика, пропускная способность, измеренная в единицах времени и т. д.) в каждой из этих отдельных областей, а не только на уровне устройства и ОС (ЦП, память, дисковый ввод-вывод, и т. д.), но специфичные для каждой службы уровня. Итак, на веб-сервере вам нужно знать все счетчики используемого вами веб-сервера. На уровне приложений вам понадобится это, а также видимость любой виртуальной машины, которую вы используете (jvm, clr, что угодно). Большинство OR-сопоставителей проявляются внутри виртуальной машины, поэтому убедитесь, что вы обращаете внимание на все особенности, если они видны вам на этом уровне. Внутри БД вам нужно знать все, что выполняется, и все конкретные параметры настройки для вашей разновидности БД. Если у вас есть большие деньги, BMC Patrol — довольно хорошая ставка для большинства из них (с соответствующими модулями знаний (KM)). В более дешевом конце вы, безусловно, можете кататься самостоятельно, но ваш пробег будет варьироваться в зависимости от вашей глубины знаний.
Предполагая, что все синхронно (нет вещей, основанных на очередях, которые вам нужно ждать), существует множество возможностей для проблем с производительностью и / или масштабируемостью. Но поскольку ваш пост посвящен масштабируемости, давайте проигнорируем браузер, за исключением любых удаленных вызовов XHR, которые вызовут другой запрос/ответ от веб-сервера.
Итак, учитывая эту проблемную область, какие решения вы могли бы принять, чтобы помочь с масштабируемостью?
Обработка соединения. Это также связано с управлением сеансом и аутентификацией. Это должно быть максимально чистым и легким без ущерба для безопасности. Метрика — максимальное количество подключений в единицу времени.
Отработка отказа сеанса на каждом уровне. Необходимо или нет? Мы предполагаем, что каждый уровень будет представлять собой кластер ящиков по горизонтали под неким механизмом балансировки нагрузки. Балансировка нагрузки обычно очень легкая, но некоторые реализации аварийного переключения сеанса могут быть тяжелее, чем хотелось бы. Кроме того, если вы работаете с закрепленными сеансами, это может более глубоко повлиять на ваши параметры в архитектуре. Вы также должны решить, привязывать ли веб-сервер к конкретному серверу приложений или нет. В мире удаленного взаимодействия .NET их, вероятно, проще связать вместе. Если вы используете стек Microsoft, может быть более масштабируемым сделать двухуровневый (пропустить удаленное взаимодействие), но вам придется пойти на существенный компромисс безопасности. Что касается Java, я всегда видел как минимум 3 уровня. Нет причин делать это иначе.
Иерархия объектов. Внутри приложения вам нужна максимально чистая и легкая структура объектов. Приносите данные, которые вам нужны, только тогда, когда они вам нужны. Злобно отсекайте любое ненужное или лишнее получение данных.
ИЛИ неэффективность картографа. Существует несоответствие импеданса между объектным дизайном и реляционным дизайном. Конструкция «многие ко многим» в РСУБД находится в прямом конфликте с иерархиями объектов (человек.адрес против местоположения.резидент). Чем сложнее ваши структуры данных, тем менее эффективным будет ваш преобразователь OR. В какой-то момент вам, возможно, придется отказаться от приманки в разовой ситуации и применить более... ну... примитивный подход к доступу к данным (хранимая процедура + уровень доступа к данным), чтобы выжать больше производительности или масштабируемости из конкретного уродливый модуль. Поймите связанные с этим затраты и примите осознанное решение.
XSL-преобразования. XML — прекрасный, нормализованный механизм для передачи данных, но он может быть очень производительным псом! В зависимости от того, сколько данных вы носите с собой, какой парсер вы выберете и насколько сложна ваша структура, вы можете легко загнать себя в очень темный угол с помощью XSLT. Да, с академической точки зрения это блестяще чистый способ создания уровня представления, но в реальном мире могут возникнуть катастрофические проблемы с производительностью, если вы не уделите этому особого внимания. Я видел систему, потребляющую более 30% времени транзакций только в XSLT. Некрасиво, если вы пытаетесь увеличить базу пользователей в 4 раза, не покупая дополнительные коробки.
Можете ли вы купить выход из затора масштабируемости? Абсолютно. Я наблюдал, как это происходит больше раз, чем я хотел бы признать. Закон Мура (как вы уже упомянули) действует и сегодня. На всякий случай имейте при себе немного наличных.
Кэширование — отличный инструмент для снижения нагрузки на движок (удобным побочным эффектом является увеличение скорости и пропускной способности). Однако за это приходится платить с точки зрения объема памяти и сложности при аннулировании кеша, когда он устарел. Мое решение состояло бы в том, чтобы начать с полной очистки и постепенно добавлять кеширование только там, где вы решите, что это полезно для вас. Слишком часто сложности недооцениваются, и то, что начиналось как способ решения проблем с производительностью, в итоге приводит к функциональным проблемам. Кроме того, вернемся к комментарию об использовании данных. Если вы каждую минуту создаете объекты на гигабайты, не имеет значения, кэшируете вы их или нет. Вы быстро исчерпаете свой объем памяти, а сборка мусора испортит вам день. Таким образом, я думаю, вывод состоит в том, чтобы убедиться, что вы точно понимаете, что происходит внутри вашей виртуальной машины (создание объекта, уничтожение, GC и т. д.), чтобы вы могли принимать наилучшие возможные решения.
Извините за многословие. Просто покатался и забыл посмотреть. Надеюсь, что-то из этого затрагивает дух вашего расследования и не является слишком элементарным разговором.
person
Ed Lucas
schedule
16.09.2008