Подтвердить что ты не робот

Масштабируемость/производительность Ruby on Rails?

Я использовал PHP еще некоторое время и хорошо использовал его с CodeIgniter, что является отличной основой. Я начинаю новый личный проект, и в последний раз я рассматривал, что использовать (PHP vs ROR). Я использовал PHP из-за проблем с масштабируемостью, которые, как я слышал, у ROR, особенно после прочтения того, что разработчики Twitter должны были сказать об этом. Является ли масштабируемость еще проблемой в ROR или есть улучшения в ней?

Я хотел бы изучить новый язык, и ROR кажется интересным. PHP выполняет свою работу, но, как всем известно, его синтаксис и организация неуклюжие, и это похоже на большой взлом.

4b9b3361

Ответ 1

Развернуть на Ryan Doherty немного ответьте...

Я работаю на статически типизированном языке для моей дневной работы (.NET/С#), а также Ruby как побочная вещь. До моей нынешней работы я был ведущим программистом для фирмы, занимающейся разработкой рубинов, которая работает над службой Syndication в Нью-Йорке. До этого я тоже работал на PHP (хотя давно, давно).

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

Большая часть проблем с производительностью, которые мы видели у других и даже у нас, касались медленных запросов на нашем уровне ORM. Мы перешли от Rails/ActiveRecord к Rails/DataMapper и, наконец, к Merb/DM, каждая итерация получает большую скорость просто из-за базовых фреймворков.

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

Нам пришлось серьезно подгонять наши индексы базы данных, следя за тем, чтобы наши запросы не делали очень глупые вещи, убедившись, что мы не выполняем больше запросов, чем это было абсолютно необходимо, и т.д. Когда я говорю "очень глупые вещи" ", Я имею в виду проблему с запросом 1 + N...

#1 query
Dog.find(:all).each do |dog|
   #N queries
   dog.owner.siblings.each do |sibling|
      #N queries per above N query!!
      sibling.pets.each do |pet|
         #Do something here
      end
   end
end

DataMapper - отличный способ справиться с вышеуказанной проблемой (нет проблем с 1 + N), но еще лучше - использовать свой мозг и прекратить делать такие запросы: D Когда вам нужна сырая производительность, большинство из слоев ORM не будет легко обрабатывать чрезвычайно пользовательские запросы, поэтому вы могли бы также написать их.

Мы также делали здравый смысл. Мы купили многообещающий сервер для нашей растущей базы данных и перенесли его на свой собственный выделенный ящик. Нам также приходилось постоянно делать TONS обработки и импорта данных. Мы переместили нашу обработку на свою собственную коробку. Мы также перестали загружать весь наш freack stack только для наших утилит импорта данных. Мы со вкусом загрузили только то, что нам абсолютно необходимо (таким образом, уменьшая объем памяти!).

Если вы не можете сказать уже... вообще, когда дело доходит до ruby ​​/rails/merb, вам нужно масштабировать, бросая аппаратное обеспечение в проблему. Но, в конце концов, оборудование дешево; хотя это не повод для дрянного кода!: D

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

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

В конце концов, это все о том, что вы хотите жить, дышать, есть и спать изо дня в день, когда дело доходит до выбора вашего фреймворка. Если вам нравится образ мышления Microsoft, перейдите на .NET. Если вы хотите открыть исходный код, но хотите структуру, попробуйте Java. Если вы хотите иметь динамический язык и по-прежнему иметь немного больше структуры, чем ruby, попробуйте python. И если вы хотите элегантности, попробуйте Ruby (я, парень, я ребенок... Есть много других элегантных языков, которые соответствуют законопроекту. Не пытайтесь начать пламенную войну: D)

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

Итак, короче, да, есть трудности, которые вам нужно преодолеть, но элегантность языка, имхо, намного превосходит эти недостатки.

Извините за роман, но я был там и вернулся с проблемами производительности. Его можно преодолеть. Поэтому не позволяйте этому отпугивать вас.

Ответ 2

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

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

Ответ 3

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

Если вы получаете десятки миллионов уникальных предметов в месяц, вы можете всегда нанимать пару человек и переписывать их по другой технологии, если вам нужно...

... вы будете входить в кеш (извините - не смогли удержаться!!)

Ответ 4

Прежде всего, было бы разумнее сравнить Rails с Symfony, CodeIgniter или CakePHP, поскольку Ruby on Rails - это полное веб-приложение фреймворк. По сравнению с PHP или фреймворками PHP, приложения Rails предлагают преимущества в том, что они маленькие, чистые и читаемые. PHP отлично для небольших персональных страниц (первоначально это означало "Персональную домашнюю страницу" ), в то время как Rails - полная фреймворк MVC, который может использоваться для создания больших сайты.

Ruby on Rails не имеет более крупной проблемы масштабируемости, чем сопоставимые фреймворки PHP. Как Rails, так и PHP будут хорошо масштабироваться, если у вас есть только умеренное число пользователей (10 000-100 000), которые работают с таким же количеством объектов. Для нескольких тысяч пользователей классическая монолитная архитектура будет быть достаточным. С небольшим количеством M & M (Memcached и MySQL) вы также можете обрабатывать миллионы объектов. Архитектура M & M использует сервер MySQL для запись дескрипторов и Memcached для обработки загрузок с высокой степенью чтения. Традиционный шаблон хранилища, один SQL-сервер с использованием нормализованных реляционных таблиц (или, в лучшем случае, SQL Master/Multiple Read Slave setup), больше не работает для очень больших сайтов.

Если у вас есть миллиарды пользователей, таких как Google, Twitter и Facebook, вероятно, распределенная архитектура будет лучше. Если вы действительно хотите масштабируйте свое приложение без ограничений, используйте какое-то дешевое товарное оборудование в качестве основы, разделить ваше приложение на набор услуг, сохранить каждый компонент или услуга масштабируется (проектирует каждый компонент как масштабируемый сервис) и адаптировать архитектуру к вашему приложению. Тогда вам понадобятся подходящие масштабируемые хранилища данных, такие как базы данных NoSQL и распределенные хеш-таблицы (DHT), вам понадобится сложная карта-сокращение алгоритмы для работы с ними, вам придется иметь дело с SOA, внешними услуг и обмена сообщениями. Здесь ни PHP, ни Rails не предлагают волшебную пулю.

Ответ 5

Что происходит с RoR, так это то, что если вы не в Alexa 100, у вас не будет проблем с масштабируемостью. У вас будет больше проблем со стабильностью на общедоступном хостинге, если вы не сможете сжать Phusion, Passenger или Mongrel.

Ответ 6

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

Тогда все равно создайте его в Rails, потому что вы знаете, что это имеет смысл. Если вы дойдете до томов на уровне Твиттера, то вы будете в счастливой позиции по рассмотрению вариантов оптимизации производительности. По крайней мере, вы будете применять их на хорошем языке!

Ответ 7

Вы не можете сравнивать PHP и ROR, PHP - это язык сценариев как Ruby, а Rails - это среда как CakePHP.
Заявив, что я настоятельно рекомендую вам Rails, потому что у вас будет приложение строго , организованное в шаблоне MVC, и это ДОЛЖНО для вашего требования к масштабируемости. (Используя PHP, вам нужно было позаботиться о организации проекта самостоятельно).
Но что касается масштабируемости, Rails это не просто MVC: например, вы можете приступить к разработке своего приложения с помощью базы данных, без каких-либо усилий изменить его на дороге (в большинстве случаев), поэтому мы можем заявить, что приложение Rails (почти) базы данных indipendent, потому что это ORM (что позволяет избежать запроса к базе данных), вы можете делать много других вещей.
(посмотрите на это видео http://www.youtube.com/watch?v=p5EIrSM8dCA)

Ответ 8

Просто хотел добавить дополнительную информацию в адрес Кейта Хэнсона о проблеме с 1 + N, где он заявляет:

DataMapper - отличный способ справиться с вышеуказанной проблемой (нет проблем с 1 + N), но еще лучше - использовать свой мозг и прекратить делать такие запросы: D Когда вам нужна сырая производительность, большинство из слоев ORM не будет легко обрабатывать чрезвычайно пользовательские запросы, поэтому вы могли бы также написать их.

Doctrine является одним из самых популярных ORM для PHP. Он решает эту проблему сложности 1 + N, присущую ORM, предоставляя язык под названием Doctrine Query Language (DQL). Это позволяет вам писать SQL-выражения, которые используют существующие отношения модели. например

$q = Doctrine_Query:: Create() → выберите (*) → от (ModelA m) → LeftJoin (m.ModelB) → Execute()

Ответ 9

Я получаю впечатление от этого потока, что проблемы масштабируемости ROR сводятся прежде всего к беспорядку, который существуют в ORM для загрузки дочерних объектов, то есть к проблеме "1 + N", упомянутой выше. В приведенном выше примере Райан дал собакам и владельцам:

Dog.find(:all).each do |dog|
   #N queries
   dog.owner.siblings.each do |sibling|
      #N queries per above N query!!
      sibling.pets.each do |pet|
         #Do something here
      end
   end
end

На самом деле вы можете написать один SQL-запрос, чтобы получить все эти данные, и вы также можете "сшить" эти данные в иерархию объектов Dog.Owner.Siblings.Pets для ваших созданных пользователем объектов. Но может ли кто-нибудь написать ORM, который сделал это автоматически, так что в приведенном выше примере может произойти однократное путешествие в БД и одно выражение SQL вместо потенциальных сотен? Полностью. Просто присоедините эти таблицы к одному набору данных, затем выполните некоторую логику, чтобы сшить его. Немного сложно сделать эту логику общим, чтобы она могла обрабатывать любой набор объектов, но не конец света. В конце концов, таблицы и объекты относятся только друг к другу в одной из трех категорий (1:1, 1: многие, многие: многие). Это просто, что никто никогда не строил этот ORM.

Вам нужен синтаксис, который сообщает системе заранее, какие дети вы хотите загрузить для этого конкретного запроса. Вы можете сделать это с помощью "нетерпеливой" загрузки LinqToSql (С#), которая не является частью ROR, но даже при том, что это приводит к одному обращению в DB, ​​это все еще сотни отдельных SQL-заявлений, в настоящее время настроен. Это действительно больше об истории ОРМ. Они просто начали с неправильного пути с этим и никогда не оправились в моем взгляде. "Lazy loading" - это поведение большинства ORM по умолчанию, то есть передача другой поездки в оба конца для каждого упоминания дочернего объекта, что является сумасшедшим. Затем с "нетерпеливой" загрузкой - загрузка детей вперед, которая статически ставится во всем, что я знаю вне LinqToSql - то есть, какие дети всегда загружаются с определенными объектами, - как если бы вам всегда нужны те же дети, которые загружались при загрузке коллекции собак.

Вам нужен какой-то строго типизированный синтаксис, говорящий, что на этот раз я хочу загрузить этих детей и внуков. Т.е. что-то вроде:

Dog.Owners.Include()
Dog.Owners.Siblings.Include()
Dog.Owners.Siblings.Pets.Include()

то вы можете выполнить эту команду:

Dog.find(:all).each do |dog|

Система ORM должна знать, какие таблицы нужно объединить, затем сшивать полученные данные в иерархию OM. Это правда, что вы можете бросать аппаратное обеспечение в текущую проблему, к которой я вообще отношусь, но это не причина, по которой ORM (то есть Hibernate, Entity Framework, Ruby ActiveRecord) не следует просто лучше писать. Аппаратное обеспечение на самом деле не освобождает вас от 8 запросов туда и обратно, 100-SQL запросов, которые должны были быть в одну поездку туда и обратно.