Skalowalność/wydajność Ruby on Rails? [zamknięte]

zamknięte . To pytanie jest oparte na opinii . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Zaktualizuj pytanie, aby mogło być odpowiedź z faktami i cytatami przez edytując ten post .

Zamknięte 5 lat temu .

Popraw to pytanie

Używam PHP przez jakiś czas i używam go dobrze z CodeIgniter, który jest świetnym frameworkiem. Zaczynam nowy osobisty projekt i ostatnio zastanawiałam się, co zrobić użycie (PHP vs ROR) używałem PHP ze względu na problemy ze skalowalnością, które słyszałem, że ROR miał, zwłaszcza po przeczytaniu tego, co twórcy Twittera mieli do powiedzenia na ten temat. Czy skalowalność nadal jest problemem w ROR, czy też wprowadzono w niej ulepszenia?

Chciałbym nauczyć się nowego języka, a ROR wydaje się interesujący. PHP robi zadanie, ale jak wszyscy wiedzą jego składnia i organizacja są fugly i czuje się jak jeden wielki hack.
Author: ryeguy, 2009-02-02

9 answers

Żeby rozwinąć odpowiedź Ryana Doherty ' ego...

Pracuję w statycznie wpisanym języku do mojej codziennej pracy (. Net/C#), a także Ruby jako rzecz poboczna. Przed moją obecną pracą byłem głównym programistą w firmie programistycznej ruby wykonującej pracę dla usługi Syndykacyjnej New York Times. Wcześniej pracowałem również w PHP (choć dawno, dawno temu).

Powiem tak: doświadczyłem problemów z wydajnością rails (a bardziej ogólnie ruby) z pierwszej ręki, a także kilka innych alternatyw. Jak mówi Ryan, nie będzie to automatycznie skalowane dla Ciebie. Znalezienie wąskich gardeł wymaga pracy i ogromnej cierpliwości.

Znaczna większość problemów z wydajnością, które widzieliśmy od innych, a nawet my sami, miała do czynienia z powolnymi zapytaniami wykonywanymi w warstwie ORM. Przeszliśmy od Rails / ActiveRecord do Rails / DataMapper i wreszcie do Merb / DM, każda iteracja zyskiwała większą prędkość tylko dzięki podstawowym frameworkom.

Buforowanie robi niesamowite cuda dla wydajności. Niestety, nie mogliśmy buforować naszych danych. Nasza pamięć podręczna byłaby unieważniana co najwyżej pięć minut. Prawie każdy kawałek naszej strony był dynamiczny. Więc jeśli/kiedy nie możesz tego zrobić, być może możesz nauczyć się z naszego doświadczenia.

Musieliśmy skończyć poważnie dostrajając nasze indeksy baz danych, upewniając się, że nasze zapytania nie robią bardzo głupich rzeczy, upewniając się, że nie wykonujemy więcej zapytań niż było to absolutnie konieczne, itp. Kiedy mówię " bardzo głupie rzeczy", mam na myśli problem z zapytaniem 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 jest doskonałym sposobem radzenia sobie z powyższym problemem (nie ma nie ma z nim problemów 1 + N), ale jeszcze lepszym sposobem jest użycie mózgu i zaprzestanie wykonywania takich zapytań :d kiedy potrzebujesz surowej wydajności, większość warstw ORM nie poradzi sobie z ekstremalnie niestandardowymi zapytaniami, więc równie dobrze możesz je napisać ręcznie.

Robiliśmy też rzeczy zdroworozsądkowe. Kupiliśmy rozbudowany serwer dla naszej rosnącej bazy danych i przeniosłem go na własne dedykowane pudełko. Musieliśmy również nieustannie przetwarzać i importować dane. Przenieśliśmy nasze przetwarzanie na jego własne pudełko. Przestaliśmy też ładować cały nasz cholerny stos tylko dla naszych narzędzi do importu danych. Mamy gustownie załadowane tylko to, co absolutnie potrzebne (zmniejszając w ten sposób napowietrznej pamięci!). Jeśli już nie wiesz... ogólnie rzecz biorąc, jeśli chodzi o ruby / rails / merb, musisz skalować out, rzucając sprzęt w problem. Ale w końcu sprzęt jest tani; choć to nie jest usprawiedliwienie dla tandetnego kodu! : D

I nawet z tymi trudnościami, osobiście nigdy nie rozpocząłbym projektów w innych ramach, gdybym mógł im pomóc. Uwielbiam ten język i codziennie dowiaduję się o nim więcej. Tego nie rozumiem z C#, choć C# jest szybsze.

Lubię również narzędzia open source, niski koszt rozpoczęcia pracy w języku, niski koszt, aby po prostu coś tam i spróbuj sprawdzić, czy jest to marketingowe, cały czas pracując w języku, który często może być elegancki i piękny...

W końcu, to wszystko o tym, co chcesz żyć, oddychać, jeść i spać w dzień w dzień, jeśli chodzi o wybór ram. Jeśli podoba Ci się sposób myślenia Microsoftu, przejdź do .NET. jeśli chcesz open source, ale nadal chcesz struktury, spróbuj Java. Jeśli chcesz mieć dynamiczny język i nadal mieć nieco większą strukturę niż ruby, wypróbuj python. A jeśli chcesz elegancji, try Ruby (i kid, I kid... istnieje wiele innych eleganckich języków, które pasują do rachunku. Nie próbuję rozpętać płomiennej wojny: D)

Do diabła, wypróbuj je wszystkie! Zazwyczaj zgadzam się z powyższymi odpowiedziami, że martwiąc się o optymalizacje wcześnie nie jest powodem, dla którego powinieneś lub nie powinieneś wybierać frameworka, ale nie zgadzam się, że jest to ich jedyna odpowiedź. Krótko mówiąc, tak, są trudności, które musisz pokonać, ale elegancja języka, imho, znacznie przewyższa te niedociągnięcia. Przepraszam za powieść, ale byłem tam i z powrotem z problemami z wydajnością. To Może być przezwyciężone. Więc nie pozwól, żeby cię to wystraszyło.
 161
Author: Keith Hanson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 20:14:08

RoR jest używany z wieloma ogromnymi witrynami, ale tak jak w przypadku dowolnego języka lub frameworka, potrzeba dobrej architektury (skalowanie db, buforowanie, strojenie itp.), aby skalować do dużej liczby użytkowników.

Wprowadzono kilka drobnych zmian w RoR, aby ułatwić skalowanie, ale nie oczekuj, że będzie skalowany magicznie dla Ciebie. Każda witryna ma inne problemy ze skalowaniem, więc musisz włożyć trochę pracy, aby ją skalować.

 27
Author: Ryan Doherty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 16:07:39

Rozwijaj się w technologii, która da Twojemu projektowi największe szanse na sukces - szybki rozwój, łatwe debugowanie, łatwe wdrażanie, dobre narzędzia, znasz to na wylot (chyba że chodzi o naukę nowego języka) itp.

Jeśli masz dziesiątki milionów uników miesięcznie, zawsze możesz zatrudnić kilka osób i przepisać w innej technologii, jeśli potrzebujesz as ...

... będziesz rake - ing w cache (sorry-couldn ' t opieraj się!!)

 16
Author: RichH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 16:17:37

Po pierwsze, być może bardziej sensowne byłoby porównywanie Railsów z Symfony, CodeIgniter lub CakePHP, ponieważ Ruby on Rails jest kompletną aplikacją webową ramy. W porównaniu do PHP czy frameworków PHP, Aplikacje Rails oferują zalety, że są małe, czyste i czytelne. PHP is perfect dla małych, osobistych stron (pierwotnie oznaczało to " Personal Home Page"), podczas gdy Rails jest pełnym FRAMWORKIEM MVC, który może być użyty do budowania dużych miejsca.

Ruby on Rails nie ma a większy problem ze skalowalnością niż porównywalne frameworki PHP. Zarówno Rails, jak i PHP będą dobrze skalowane, jeśli masz tylko umiarkowaną liczbę użytkowników (10 000-100 000), którzy działają na podobnej liczbie obiektów. Dla kilku tysięcy użytkowników klasyczna monolityczna architektura będzie wystarczy. Z odrobiną M & M (Memcached i MySQL) możesz także obsługiwać miliony obiektów. Architektura M&M wykorzystuje serwer MySQL do obsługa zapisów i Memcached w celu obsługi dużych obciążeń odczytu. Tradycyjna storage pattern, a pojedynczy serwer SQL z wykorzystaniem znormalizowanych tabel relacyjnych (lub w najlepszym wypadku Konfiguracja SQL Master/Multiple Read Slave), już nie działa dla bardzo dużych witryn.

Jeśli masz miliardy użytkowników takich jak Google, Twitter i Facebook, to prawdopodobnie Architektura rozproszona będzie lepsza. Jeśli naprawdę chcesz skaluj swoją aplikację bez ograniczeń, użyj jakiegoś taniego sprzętu towarowego jako fundament, podziel swoją aplikację na zestaw usług, zachowaj każdy komponent lub usługa skalowalna sama (Zaprojektuj każdy element jako skalowalną usługę) i dostosować architekturę do aplikacji. Następnie będziesz potrzebował odpowiednich skalowalnych magazynów danych, takich jak bazy danych NoSQL i rozproszonych tabel hashowych (DHTs), będziesz potrzebował rozbudowanej mapy-zmniejsz algorytmów do pracy z nimi, będziesz musiał poradzić sobie z SOA, zewnętrzne usługi i wiadomości. Ani PHP, ani Rails nie oferują tutaj magicznej kuli.

 14
Author: 0x4a6f4672,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-18 09:54:20

Co jest załamuje się z RoR jest to, że jeśli nie jesteś w top 100 Alexa, nie będziesz miał żadnych problemów ze skalowalnością. Będziesz miał więcej problemów ze stabilnością hostingu współdzielonego, chyba że możesz wycisnąć Phusion, Passenger lub Kundel.

 6
Author: phresus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 16:01:20

Poświęć trochę czasu, aby przyjrzeć się problemom, z którymi musieli sobie poradzić użytkownicy Twittera, a następnie zadaj sobie pytanie, czy Twoja aplikacja będzie musiała skalować się do tego poziomu.

To i tak zbuduj go w Rails, bo wiesz, że to ma sens. Jeśli dojdziesz do woluminów na poziomie Twittera, będziesz w szczęśliwej sytuacji, rozważając opcje optymalizacji wydajności. Przynajmniej będziesz je stosować w ładnym języku!

 5
Author: Mike Woodhouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-02 20:02:56

Nie można porównywać PHP i ROR, PHP jest językiem skryptowym jak Ruby, a Rails jest frameworkiem jak CakePHP.
Stwierdziłem, że zdecydowanie sugeruję Ci Rails, ponieważ będziesz miał aplikację ściśle zorganizowaną we wzorze MVC , a to jest musi dla Twoich wymagań skalowalności. (Używając PHP trzeba było zadbać o organizację projektu na własną rękę).
Ale jeśli chodzi o skalowalność, Rails to nie tylko MVC: na przykład, możesz zacząć rozwijać swoje aplikacja z bazą danych, zmieniając ją na drodze bez żadnego wysiłku (w większości przypadków), więc możemy stwierdzić, że aplikacja Rails jest (prawie) niezależna od bazy danych ponieważ jest to ORM (które pozwalają uniknąć zapytań do bazy danych), możesz zrobić wiele innych rzeczy.
(Spójrz na ten film http://www.youtube.com/watch?v=p5EIrSM8dCA )

 2
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-17 14:20:28

Chciałem tylko dodać trochę więcej informacji do inteligentnego punktu Keitha Hansona o problemie 1 + N, gdzie stwierdza:

DataMapper jest doskonałym sposobem radzenia sobie z powyższym problemem( nie ma z nim problemów 1 + N), ale jeszcze lepszym sposobem jest użycie mózgu i zaprzestanie wykonywania takich zapytań :d kiedy potrzebujesz surowej wydajności, większość warstw ORM nie poradzi sobie z ekstremalnie niestandardowymi zapytaniami, więc równie dobrze możesz je napisać ręcznie.

Doktryna jest jednym z najpopularniejszych ORM dla PHP. Rozwiązuje ten problem złożoności 1 + N nieodłącznie związany z ORMs, dostarczając język o nazwie Doctrine Query Language (DQL). Pozwala to na pisanie wyrażeń podobnych do SQL, które wykorzystują istniejące relacje modelu. e. g

$q = Doctrine_Query:: Create() - >wybierz(*) - >z (Model m) - >leftJoin (m. ModelB) - >execute ()

 2
Author: Aree Cohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 10:52:18

Odnoszę wrażenie z tego wątku, że problemy ze skalowalnością ROR sprowadzają się przede wszystkim do bałaganu, w którym orms jest w odniesieniu do ładowania obiektów potomnych - tj. W powyższym przykładzie Ryan dał z psami i właścicielami:

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
Możesz napisać pojedyncze polecenie sql, aby uzyskać wszystkie te dane, a także "zszyć" te dane do psa.Właściciel.Rodzeństwo.Zwierzęta obiekt dziedziczenie przedmiotów pisanych na zamówienie. Ale może ktoś napisał ORM, który zrobił to automatycznie, aby powyższy przykład ponosił pojedynczą podróż w obie strony do DB i pojedyncze polecenie SQL, zamiast potencjalnie setki? Całkowicie. Po prostu połącz te tabele w jeden zestaw danych, a następnie wykonaj logikę, aby je zszyć. Jest to trochę trudne, aby ta logika ogólna, więc może obsługiwać każdy zestaw obiektów, ale nie koniec świata. Ostatecznie tabele i Obiekty odnoszą się do siebie tylko w jednej z trzech kategorii(1:1, 1:many, many: many). On tylko, że nikt nigdy nie zbudował tego ORM.

Potrzebujesz składni, która z góry informuje system, jakie Dzieci chcesz załadować dla tego konkretnego zapytania. Możesz to zrobić poprzez "chętne" Ładowanie LinqToSql (C#), które nie jest częścią ROR, ale mimo że skutkuje to jedną podróżą w obie strony do DB, to nadal są to setki oddzielnych instrukcji SQL w sposób, w jaki został on obecnie skonfigurowany. Chodzi bardziej o historię ORM. Po prostu ruszyli złą drogą z to i nigdy tak naprawdę nie odzyskałem w moim opnion. "Leniwe ładowanie" jest domyślnym zachowaniem większości ORM, tj. ponawianie kolejnej podróży w obie strony za każdą wzmiankę o obiekcie dziecka, co jest szalone. Następnie z "eager" loading-Ładowanie dzieci z góry, które jest ustawione statycznie we wszystkim, co wiem poza LinqToSql - tj. które dzieci zawsze ładują z pewnymi obiektami - tak jakbyś zawsze potrzebował tych samych dzieci załadowanych podczas ładowania kolekcji psów.

You need some kind of mocno wpisana składnia mówiąca, że tym razem chcę załadować te dzieci i wnuki. Czyli coś w stylu:

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

Wtedy możesz wydać polecenie:

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

SYSTEM ORM będzie wiedział, jakie tabele musi połączyć, a następnie zszyć wynikowe dane do heirarchii OM. To prawda, że można rzucić sprzętem na obecny problem, który generalnie jestem za, ale nie jest to powód, dla którego ORM (tj. Hibernate, Entity Framework, Ruby ActiveRecord) nie powinien być po prostu lepszy napisane. Sprzęt naprawdę nie wyciąga cię z zapytania 8 w obie strony, 100-SQL, które powinno być jedną w obie strony i jedną instrukcją SQL.

 1
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 21:58:58