software rails official ruby-on-rails ruby scalability

ruby-on-rails - official - ruby on rails website



Escalabilidad/rendimiento de Ruby on Rails (9)

Antes que nada, quizás tenga más sentido comparar Rails con Symfony, CodeIgniter o CakePHP, ya que Ruby on Rails es un framework de aplicaciones web completo. En comparación con los marcos PHP o PHP, las aplicaciones de Rails ofrecen las ventajas de que son pequeñas, limpias y legibles. PHP es perfecto para páginas personales pequeñas (originalmente significaba "Página de inicio personal"), mientras que Rails es una estructura de MVC completa que se puede usar para construir sitios grandes.

Ruby on Rails no tiene un problema de escalabilidad mayor que los marcos PHP comparables. Tanto Rails como PHP se escalarán bien si solo tiene un número moderado de usuarios (10,000-100,000) que operan en una cantidad similar de objetos. Para unos pocos miles de usuarios, una arquitectura monolítica clásica será suficiente. Con un poco de M & M (Memcached y MySQL) también puedes manejar millones de objetos. La arquitectura de M & M usa un servidor MySQL para manejar escrituras y Memcached para manejar cargas de alta lectura. El patrón de almacenamiento tradicional, un único servidor SQL que utiliza tablas relacionales normalizadas (o, en el mejor de los casos, una configuración SQL Master / Multiple Read Slave), ya no funciona para sitios muy grandes.

Si tiene miles de millones de usuarios como Google, Twitter y Facebook, entonces probablemente una arquitectura distribuida será mejor. Si realmente desea escalar su aplicación sin límite, utilice algún tipo de hardware básico barato como base, divida su aplicación en un conjunto de servicios, mantenga cada componente o servicio escalable (diseñe cada componente como un servicio escalable) y adáptese la arquitectura de tu aplicación. Entonces necesitará almacenes de datos escalables adecuados como bases de datos NoSQL y tablas hash distribuidas (DHT), necesitará sofisticados algoritmos de reducción de mapas para trabajar con ellos, tendrá que lidiar con SOA, servicios externos y mensajería. Ni PHP ni Rails ofrecen una bala mágica aquí.

He usado PHP por un tiempo y lo he usado bien con CodeIgniter, que es un gran marco. Estoy comenzando un nuevo proyecto personal y la última vez que consideré qué usar (PHP vs ROR) utilicé PHP debido a los problemas de escalabilidad que escuché que ROR tuvo, especialmente después de leer lo que los desarrolladores de Twitter tuvieron que decir al respecto. ¿La escalabilidad sigue siendo un problema en ROR o ha habido mejoras en ella?

Me gustaría aprender un nuevo idioma, y ​​ROR parece interesante. PHP hace el trabajo pero, como todos saben, su sintaxis y organización son fútiles y se siente como un gran truco.


Desarrolle la tecnología que le dará a su proyecto las mejores posibilidades de éxito: rápido desarrollo, depuración fácil, fácil implementación, buenas herramientas, lo sabe de adentro hacia afuera (a menos que el punto sea aprender un nuevo idioma), etc.

Si obtienes decenas de millones de ejemplares únicos al mes, siempre puedes contratar a un par de personas y reescribir en una tecnología diferente si lo necesitas como ...

... estarás rake -ing en el caché (lo siento, no pude resistir !!)


Lo que se descompone con RoR es que a menos que estés en los 100 mejores de Alexa, no tendrás ningún problema de escalabilidad. Tendrás más problemas con la estabilidad en el alojamiento compartido a menos que puedas exprimir Phusion, Passenger o Mongrel.


Me está dando la impresión de este hilo que los problemas de escalabilidad de ROR se deben principalmente al desorden en que se encuentran los ORM con respecto a la carga de objetos secundarios, es decir, el problema ''1 + N'' mencionado anteriormente. En el ejemplo anterior que Ryan dio con perros y dueños:

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

En realidad, podría escribir una única instrucción sql para obtener todos esos datos, y también podría ''coser'' esos datos en la jerarquía del objeto Dog.Owner.Siblings.Pets de sus objetos escritos a medida. Pero, ¿podría alguien escribir un ORM que hiciera eso automáticamente, de modo que el ejemplo anterior incurriría en un solo ida y vuelta al DB y una sola instrucción SQL, en lugar de potencialmente cientos? Totalmente. Simplemente une esas tablas en un solo conjunto de datos, luego haz algo de lógica para coserlo. Es un poco complicado hacer que la lógica sea genérica para que pueda manejar cualquier conjunto de objetos pero no el fin del mundo. Al final, las tablas y los objetos solo se relacionan entre sí en una de tres categorías (1: 1, 1: muchos, muchos: muchos). Es solo que nadie alguna vez construyó ese ORM.

Necesita una sintaxis que le indique al sistema por adelantado qué hijos desea cargar para esta consulta en particular . Puede hacer esto con la carga ''ansiosa'' de LinqToSql (C #), que no forma parte de ROR, pero a pesar de que eso da como resultado un viaje de ida y vuelta a la base de datos, todavía hay cientos de sentencias de SQL separadas de la forma en que lo hizo actualmente ha sido configurado. Realmente se trata más de la historia de los ORM. Empezaron por el camino equivocado con eso y nunca se recuperaron realmente en mi opnion. La "carga diferida" es el comportamiento predeterminado de la mayoría de los ORM, es decir, incurrir en otro viaje de ida y vuelta por cada mención de un objeto secundario, lo cual es una locura. Luego, con la carga ''ansiosa'' - cargando a los niños por adelantado, eso está configurado estáticamente en todo lo que sé fuera de LinqToSql - es decir, qué niños siempre cargan con ciertos objetos - como si siempre necesitaras cargar los mismos niños cuando cargaste una colección de perros

Necesitas algún tipo de sintaxis fuertemente tipada que diga que esta vez quiero cargar estos hijos y nietos. Es decir, algo así como:

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

entonces podrías emitir este comando:

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

El sistema ORM sabría a qué tablas debe unir, luego sutura los datos resultantes en la jerarquía de OM. Es cierto que puede lanzar hardware en el problema actual, que generalmente estoy a favor, pero no hay razón para que el ORM (es decir, Hibernate, Entity Framework, Ruby ActiveRecord) no se escriba mejor. El hardware realmente no lo rescata de una consulta de declaración de 100 viajes de ida y vuelta, que debería haber sido de ida y vuelta y una declaración de SQL.


No se puede comparar PHP y ROR, PHP es un lenguaje de scripts como Ruby, y Rails es un framework como CakePHP.
Dicho eso, le sugiero encarecidamente Rails, porque tendrá una aplicación estrictamente organizada en patrón MVC , y esto es IMPRESCINDIBLE para su requisito de escalabilidad. (Usando PHP, usted tuvo que preocuparse por la organización del proyecto por su cuenta).
Pero, ¿qué pasa con la escalabilidad, Rails no es solo MVC: por ejemplo, puede comenzar a desarrollar su aplicación con una base de datos, cambiándola en la carretera sin ningún esfuerzo (en la mayoría de los casos), para que podamos afirmar que una aplicación Rails es (casi) base de datos independiente porque es ORM (que le permite evitar la consulta de la base de datos), puede hacer muchas otras cosas.
(Mire este video http://www.youtube.com/watch?v=p5EIrSM8dCA )


Para ampliar la respuesta de Ryan Doherty un poco ...

Trabajo en un lenguaje estáticamente tipado para mi trabajo diario (.NET / C #), y también como Ruby. Antes de mi trabajo actual, era el programador principal de una firma de desarrollo de Ruby que trabajaba para el servicio de sindicación del New York Times. Antes de eso, también trabajé en PHP (aunque hace mucho, mucho tiempo).

Digo eso simplemente para decir esto: he experimentado los problemas de rendimiento de los rieles (y en general ruby) de primera mano, así como algunas otras alternativas. Como dice Ryan, no vas a tener que escalar automáticamente para ti. Se necesita trabajo y una inmensa cantidad de paciencia para encontrar los cuellos de botella.

Una gran mayoría de los problemas de rendimiento que vimos de los demás e incluso de nosotros mismos trataban con consultas de ejecución lenta en nuestra capa ORM. Pasamos de Rails / ActiveRecord a Rails / DataMapper y finalmente a Merb / DM, cada iteración obtiene más velocidad simplemente debido a los frameworks subyacentes.

El almacenamiento en caché hace maravillas increíbles para el rendimiento. Lamentablemente, no pudimos almacenar nuestros datos en caché. Nuestro caché sería efectivamente invalidado cada cinco minutos como máximo. Casi cada bit de nuestro sitio era dinámico. Entonces, si / cuando no puedes hacer eso, tal vez puedas aprender de nuestra experiencia.

Tuvimos que terminar ajustando seriamente nuestros índices de base de datos, asegurándonos de que nuestras consultas no estuvieran haciendo cosas estúpidas, asegurándonos de que no estuviéramos ejecutando más consultas de las absolutamente necesarias, etc. Cuando digo "cosas muy estúpidas", significa el problema de consulta 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 es una excelente manera de manejar el problema anterior (no hay problemas de 1 + N con él ), pero una forma aún mejor es usar su cerebro y dejar de hacer consultas como esa: D Cuando necesita rendimiento sin procesar, la mayoría de los ORM las capas no manejarán fácilmente las consultas extremadamente personalizadas, por lo que también podría escribirlas a mano.

También hicimos cosas de sentido común. Compramos un servidor fornido para nuestra creciente base de datos y lo trasladamos a su propia caja dedicada. También tuvimos que hacer TONELADAS de procesamiento e importación de datos constantemente. También trasladamos nuestro procesamiento a su propia caja. También dejamos de cargar toda nuestra pila maldita solo para nuestras utilidades de importación de datos. Cargamos con buen gusto solo lo que necesitábamos absolutamente (¡reduciendo así la memoria por encima!).

Si no puede decir ya ... en general, cuando se trata de ruby ​​/ rails / merb, tiene que escalar, lanzando hardware al problema. Pero al final, el hardware es barato; ¡aunque eso no es excusa para el código de mala calidad! :RE

E incluso con estas dificultades, personalmente nunca comenzaría proyectos en otro marco si puedo evitarlo. Estoy enamorado del idioma y continuamente aprendo más sobre él todos los días. Eso es algo que no obtengo de C #, aunque C # es más rápido.

También disfruto las herramientas de código abierto, el bajo costo para empezar a trabajar en el idioma, el bajo costo de simplemente obtener algo y tratar de ver si es comercializable, mientras trabajo en un lenguaje que muchas veces puede ser elegante y hermoso. ...

Al final, se trata de lo que desea vivir, respirar, comer y dormir día a día cuando se trata de elegir su marco. Si le gusta la forma de pensar de Microsoft, vaya a .NET. Si quieres código abierto pero aún quieres estructura, prueba con Java. Si quieres tener un lenguaje dinámico y aún tienes un poco más de estructura que ruby, prueba con python. Y si quieres elegancia, intenta con Ruby (lo hago, chico ... hay muchos otros idiomas elegantes que se ajustan a tus necesidades. No estoy tratando de iniciar una guerra de llama: D)

¡Demonios, pruébalos! Tiendo a estar de acuerdo con las respuestas anteriores de que preocuparse por las optimizaciones anticipadamente no es la razón por la que debería o no debería elegir un marco, pero no estoy de acuerdo en que esta sea su única respuesta.

En resumen, sí, hay dificultades que tiene que superar, pero la elegancia del lenguaje, en verdad, supera con creces esas deficiencias.

Perdón por la novela, pero he estado allí y volví con problemas de rendimiento. Puede ser superado Así que no dejes que eso te asuste.


RoR se está utilizando con muchos sitios web grandes, pero como con cualquier lenguaje o marco, se necesita una buena arquitectura (escalado db, almacenamiento en caché, ajuste, etc.) para escalar a un gran número de usuarios.

Ha habido algunos cambios menores en RoR para que sea más fácil escalar, pero no esperes que escale mágicamente para ti. Cada sitio web tiene diferentes problemas de escala, por lo que tendrá que poner algo de trabajo para que sea escalable.


Solo quería agregar algo más de información al punto inteligente de Keith Hanson sobre el problema 1 + N donde dice:

DataMapper es una excelente manera de manejar el problema anterior (no hay problemas de 1 + N con él), pero una forma aún mejor es usar su cerebro y dejar de hacer consultas como esa: D Cuando necesita rendimiento sin procesar, la mayoría de los ORM las capas no manejarán fácilmente las consultas extremadamente personalizadas, por lo que también podría escribirlas a mano.

Doctrine es uno de los ORM''s más populares para PHP. Aborda este problema de complejidad 1 + N intrínseco a los ORM al proporcionar un lenguaje llamado Doctrine Query Language (DQL). Esto le permite escribir declaraciones similares a SQL que usan sus relaciones de modelo existentes. p.ej

$ q = Doctrine_Query :: Create () -> select (*) -> from (ModelA m) -> leftJoin (m.ModelB) -> execute ()


Tómese un momento para analizar los problemas con los que tuvo que lidiar la gente de Twitter, luego pregúntese si su aplicación va a tener que escalar a ese nivel.

Luego compártela en Rails de todos modos, porque sabes que tiene sentido. Si llegas a los volúmenes de Twitter, estarás en la feliz posición de considerar las opciones de optimización del rendimiento. ¡Al menos los aplicará en un lenguaje agradable!