Масштабирование и производительность - еще раз о главном

Мы не раз обсуждали вопросы производительности и масштабирования систем (этому и посвящен этот блог). Тем не менее, иногда очень полезно возвращаться к истоку этих понятий. Это важно для понимания их сути, а следовательно и для того, чтобы принимать правильные решения в нужные моменты времени.
Зачастую эти два понятия тесно связаны, но представляют собой два абсолютно разных свойства системы:
- Производительность - способность системы выполнять операцию за определенное допустимое время (другими словами, достаточно быстро)
- Масштабируемость - способность системы справляться с увеличивающимися нагрузками (обычно - путем наращивания аппаратных ресурсов)
Почему эти важно?
Если не думать об этих вопросах, не будет шансов для роста. Производительность Вашей системы означает, что Вы справляетесь с запросами сегодня. Масштабируемость же обеспечит способность справиться с запросами в будущем.
Оба свойства тесно связаны друг с другом и оказывают влияние друг на друга. Как ни странно, именно это позволяет добиваться наиболее эффективных решений в терминах затрат при удачной комбинации внедряемых улучшений. Если Вашей системе нужно справиться с 10%-ым ростом нагрузки, наверняка имеет смысл подумать об оптимизации. Оптимизация во многих случаях может дать выигрышь в производительности в несколько раз, освобождая таким образом ресурсы для большей нагрузки (при сохранении аппаратной части без изменений).
Какой язык выбрать?
Это неважно! В большинстве своем проблемы производительности лежат вне кода системы. Проблемы таятся в архитектурных решениях, но очень редко в их реализации. Даже столкнувшись с неудачной реализацией, затраты на ее исправление не сравняться с затратами на изменение архитектурных решений.
По этой причине выбор языка (или платформы) разработки стоит рассматривать только со стороны ее потенциальной стоимости, сложности и скорости разработки. Как хорошо Вы знакомы с технологией, наскольк быстро Вы сможете ее освоить, сколько Вам придется прочитать, какова рыночная стоимость разработки - это вопросы стоит задавать при выборе языка разработки.
Когда начать?
Начинать решать вопросы производительности и масштабирования нужно только (и только!) тогда, когда они возникают. Никогда не стоит заниматься решением несуществующих проблем во время разработки системы. Опыт говорит о том, что абсолютно все системы испытывающие потребность в росте в большинстве случаев сталкиваются с проблемами, о которых на стадии разработки и предположить не могли.
Вам всеравно придется что-то менять и переписывать, поэтому лучше приготовиться к этому максимально хорошо. Пишите код, который можно легко менять и которым можно легко управлять (легко сказать, но этого нужно добиваться). Разрабатывайте гибкую архитектуру, компоненты которой максимально изолированы друг от друга и поддаются легкому изменению.
Когда остановиться?
В каждый момент времени Вам необходимо думать об эффективности принимаемых Вами решений (как бы это примитивно не звучало). Необходимо держать баланс проведения работ по оптимизации, наращиванию аппаратного обеспечения, а также функциональных особенностей самого приложения. В какой-то момент затраты на оптимизацию системы могут перерасти затраты на расширение парка серверов (или наоборот) - не упускайте такие ситуации.
Существуют очень много информации и подходов к оптимизации, и если придется с ними столкнуться то придется иметь дело с большинством из них. Некоторые из них малозатратны, некоторые - наоборот - трудоемкие для реализации и внедрения. Единственное, что нужно обеспечить - это готовность к таким изменением и понимание того, когда они понадобятся (если понадобятся вообще).
Общие правила эффективности
Опыт многих и многих можно свести к нескольким очень важным рекомендациям:
- Профилируйте всегда и с самого начала
- Тестируйте изменения на реальных данных (Вы не представляете, какие затычки можно будет обнаружить)
- Собирайте статистику и следите за динамикой всех аппаратных и програмных узлов
- Не делайте предположений, и не решайте несуществующих проблем - это может стать самой большой ошибкой
- Планируйте изменения, но не делайте их без надобности
Вопросы масштабирования
- Изолируйте компоненты системы (как програмно, так и аппаратно)
- Кешируйте
- Распределяйте СУБД по разным физических серверам (федерация)
- Используйте репликацию
- Анализируйте все технологические решения на предмет масштабирования и избегайте тех, с которыми могут возникнуть проблемы
Вопросы оптимизации
- Разрабатывайте системы с учетом возможности внедрения кеширования данных (всех данных!)
- Используйте внешние ресурсы максимально редко (если есть возможность не инициировать соединение с СУБД на каждой странице, обязательно используйте ее)
- Не изобретайте велосипед - используйте средства платформы максимально обширно (а современные платформы имеют огромные арсеналы всевозможных инструментов)
- Используйте прекомпиляцию и кеширование кода (естественно в случаях, когда этого не предусматривает стандартная поставка платформы)
- Избегайте огромных циклов или высокой вложенности рекурсий
К дополнение ко всему написанному, обязательно посмотрите отличный доклад, посвященный обсуждаемой тематике (по нему и была написана эта обзорная статья):
Scalability and Performance Best Practices -
Как Вы планируете изменения при росте?


# Распределяйте СУБД по разным физических серверам (федерация)
почему именно федерация?
простите, но статья сразу и обо всем и не о чем. Где-то перепутали местами, где-то намешали в
Вопросы масштабирования
1. Изолируйте компоненты системы (как програмно, так и аппаратно): статика, БД, кэш, возможно отдельные сервисы
2. предусмотрите работу с несколькими серверами для каждого компонента (репликации, разнесение файлов по нескольким серверам без использования NFS)
3. Постарайтесь предусмотреть вариант кэширования отдельных частей программы
@tarasov
Потому, что федерация не имеет SPOF в отличие от кластерного решения
@tarasov
Спасибо!
Как Вы знаете не существует четко определенного ряда правил, который позволяет сделать любую систему масштабираемой. Целью этой статьи было не систематизирование правил (что бессмысленно), а обзор наиболее часто применяющихся. В любом случае тот свод правил, который Вы описали, это опять же только примерная и частная картина. Именно поэтому свод правил в статье состоит просто из перечня нескольких популярных практик.
Ребят, а вы не выскажите свое мнение по поводу чатов. Какая производетельность должна быть, точнее, как обстоят дела с чатами.
Например, если я хочу в локальной сети на сервере сделать очень много чатов, например, если их там будет 100 и более.
Как чаты кушают ресурсы?
Я никогда с таким не сталкивался, может скажите пару слов?
@TFR
Не существует такого понятия, как “производительность чатов”. Если Вы планируете разрабатывать чат самостоятельно с вероятно большой нагрузкой, взгляните на jabber серверы: http://www.jabberes.org/servers/
Все зависит от того как чат будет реализован и какой функционал навесите.
В базовом случае производительность четко коррелирует с количеством соединений. Лучше писать standalone-приложение, а не на базе веб-сервера, использовать event-программирование и long-pooling или http-stream (chunked) соединения.
На следующем уровне дополнительный функционал - авторизация по БД, всякие обработчики сообщений (например матотестеры) и прочее.