Как сделать так, чтобы мои приложения хорошо масштабировались?

В целом, какие дизайнерские решения помогают хорошо масштабировать приложение?

(Примечание: только что узнав о Обозначение Big O, я хочу собрать здесь больше принципов программирования. Я попытался объяснить нотацию Big O, отвечая на свой вопрос ниже, но я хочу, чтобы сообщество улучшило как этот вопрос, так и ответы .)

Ответы на данный момент
1) Определите масштабирование. Вам нужно масштабировать для большого количества пользователей, трафика, объектов в виртуальной среде?
2) Посмотрите на свои алгоритмы. Будет ли объем выполняемой ими работы линейно масштабироваться в зависимости от фактического объема работы, т. Е. Количества элементов, которые нужно просмотреть, количества пользователей и т. д.?
3) Посмотрите на свое оборудование. Разработано ли ваше приложение таким образом, что вы можете запускать его на нескольких машинах, если одна из них не успевает?

Вторичные мысли
1) Не оптимизируйте слишком быстро - сначала протестируйте. Возможно, узкие места возникнут в непредвиденных местах. 2) Возможно, необходимость масштабирования не опередит закон Мура, и, возможно, обновление оборудования будет дешевле, чем рефакторинг.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
1 064
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Джефф и Джоэл обсуждают масштабирование в Подкаст Stack Overflow # 19.

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

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

Решите, что на самом деле означает масштабирование для вашего проекта. Бесконечное количество пользователей, может ли он обрабатывать косую черту на веб-сайте, это циклы разработки?

Используйте это, чтобы сосредоточить свои усилия на разработке

Ответ принят как подходящий

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

Сначала создайте максимально простой код, затем профилируйте систему и оптимизируйте только тогда, когда есть очевидная проблема с производительностью.

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

Хорошая идея - определить, сколько работы создает каждая дополнительная задача. Это может зависеть от того, как устроен алгоритм.

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

Один из способов приблизиться к этому:

    for each car {
       determine my position;  
       for each car {  
         add my position to this car's map;  
       }
    }

Это кажется простым: посмотрите на позицию первой машины, добавьте ее на карту каждой другой машины. Затем посмотрите на положение второй машины, добавьте ее на карту всех остальных автомобилей. И Т. Д.

Но есть проблема масштабируемости. Когда есть 2 машины, эта стратегия требует 4 шага «добавить мою позицию»; когда есть 3 машины, нужно 9 шагов. Для каждого «обновления местоположения» вы должны прокручивать весь список автомобилей - и каждая машина нуждается в обновлении своего местоположения.

Игнорирование того, сколько других вещей нужно сделать с каждой машиной (например, может потребоваться фиксированное количество шагов для вычисления положения отдельной машины), для N автомобилей для запуска этого алгоритма требуется N2 "посещений автомобилей".. Это не проблема, когда у вас 5 машин и 25 ступенек. Но когда вы добавите машины, вы увидите, что система увязнет. 100 автомобилей сделают 10 000 шагов, а 101 автомобиль сделает 10 201 шаг!

Лучшим подходом было бы отменить вложенность циклов for.

    for each car {  
      add my position to a list;  
    }  
    for each car {    
      give me an updated copy of the master list;  
    }

При этой стратегии количество шагов кратно N, а не N2. Таким образом, на 100 машин потребуется в 100 раз больше работы, чем на 1 машину, а НЕ в 10 000 раз больше работы..

Эта концепция иногда выражается в «нотации большого O» - количество необходимых шагов составляет «большое O из N» или «большое O из N2».

Обратите внимание, что эта концепция касается только масштабируемости, а не оптимизации количества шагов для каждой машины. Здесь нас не волнует, 5 шагов или 50 шагов на машину - главное, чтобы N машин делали (X * N) шагов, а не (X * N2).

FWIW, большинство систем будут наиболее эффективно масштабироваться, игнорируя это до тех пор, пока это не станет проблемой - закон Мура все еще действует, и если ваш трафик не растет быстрее, чем закон Мура, обычно дешевле просто купить коробку большего размера (по 2 или 3 тысячи долларов за штуку). поп), чем платить разработчикам.

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

Если вы считаете, что существует высокая вероятность того, что вашему приложению потребуется масштабирование, возможно, будет разумным изучить такие системы, как memcached или map reduce, на сравнительно раннем этапе разработки.

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

RickNZ 29.12.2009 11:34

«Преждевременная оптимизация - корень всех зол».

Tim Howland 29.12.2009 21:25

Другие вопросы по теме