代码之家  ›  专栏  ›  技术社区  ›  ryeguy

Ruby on Rails的可扩展性/性能?[关闭]

  •  70
  • ryeguy  · 技术社区  · 16 年前

    我使用PHP已经有一段时间了,并且将它与codeigner一起使用得很好,这是一个很好的框架。我正在开始一个新的个人项目,上一次我考虑使用什么(php vs ror)时,我使用php是因为我听说ror存在可伸缩性问题,特别是在阅读了twitter开发者关于它的评论之后。可伸缩性仍然是RoR中的一个问题还是已经有了改进?

    我想学一门新的语言,罗似乎很有趣。PHP完成了这项工作,但众所周知,它的语法和组织非常简单,感觉就像一个大黑客。

    9 回复  |  直到 11 年前
        1
  •  159
  •   Keith Hanson    16 年前

    为了进一步阐述Ryan Doherty的答案…

    我在一个静态类型的语言中为我的日常工作(.net/c)工作,还有Ruby。在我今天的工作之前,我是一家Ruby开发公司的首席程序员,为纽约时报联合服务部工作。在那之前,我也用过PHP(尽管很久很久以前)。

    我这么说只是为了说明:我第一手就遇到了Rails(和更普遍的Ruby)性能问题,还有其他一些选择。正如Ryan所说,你不会让它自动为你量身。要找到你的瓶颈需要工作和极大的耐心。

    我们从其他人甚至我们自己身上看到的大部分性能问题都在处理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
    

    数据映射器是处理上述问题的一种很好的方法(这里 它不是1+N问题吗? ,但更好的方法是使用您的大脑并停止执行这样的查询:d当您需要原始性能时,大多数ORM层将不容易处理非常定制的查询,因此您也可以手工编写它们。

    我们也做了常识性的事情。我们为不断增长的数据库购买了一个强大的服务器,并将其移到了自己的专用箱中。我们还必须不断地进行大量的处理和数据导入。我们把处理转移到 它的 还有自己的盒子。我们也停止了加载整个异常的堆栈,只是为了数据导入实用程序。我们很有品味地只加载我们绝对需要的内容(从而减少内存开销!).

    如果你现在还不知道…一般来说,当涉及到ruby/rails/merb时,您必须扩展 外面的 ,向问题扔硬件。但最终,硬件是便宜的;尽管这不是伪劣代码的借口!D

    即使有这些困难,如果我能帮助的话,我个人也绝不会在另一个框架中启动项目。我热爱这门语言,每天都在不断地学习它。这是我从C处得不到的东西,尽管C处更快。

    我也很喜欢开源工具,开始使用该语言的成本很低,只需要花很低的成本就可以得到一些东西,并尝试看看它是否有市场,同时使用一种经常使用的语言也可以是优雅而漂亮的…

    最后,当涉及到选择你的框架时,你需要日复一日地生活、呼吸、吃饭和睡觉。如果你喜欢微软的思维方式,那就去.NET吧。如果您想要开源但仍然需要结构,尝试Java。如果您希望拥有一种动态语言,并且仍然比Ruby拥有更多的结构,那么可以尝试使用Python。如果你想要优雅,试试鲁比(我是孩子,我是孩子…有许多其他优雅的语言适合这个账单。不想发动火焰战争:d)

    见鬼,试试看!我倾向于同意上面的答案,早期担心优化不是您应该或不应该选择框架的原因,但我不同意这是他们唯一的答案。

    总之,是的,你必须克服一些困难,但是语言的优雅,imho,远远超过了这些缺点。

    对这部小说很抱歉,但我一直在那里,回来时遇到了性能问题。它 可以 被克服。所以不要让这吓到你。

        2
  •  27
  •   Ryan Doherty    16 年前

    RoR被用于许多大型网站,但是 任何 语言或框架,需要一个良好的体系结构(数据库伸缩、缓存、调优等)来扩展到大量用户。

    为了更容易缩放,对ror进行了一些小的更改,但不要期望它能神奇地为您缩放。每一个网站都有不同的缩放问题,所以你必须做一些工作才能使其缩放。

        3
  •  16
  •   RichH    16 年前

    开发一种能给你的项目带来最大成功机会的技术——快速开发、易于调试、易于部署、良好的工具,你完全了解它(除非重点是学习一种新语言),等等。

    如果你一个月能得到数千万个uniques,你可以雇佣几个人,如果你需要的话,可以用另一种技术重写…

    …你将会 隐藏物 (抱歉-无法抗拒!!)

        4
  •  14
  •   0x4a6f4672 pat    14 年前

    首先,将rails与 symfony、codeigner或cakephp,因为RubyonRails是一个完整的Web应用程序 框架。与PHP或PHP框架相比,Rails应用程序提供 它们的优点是体积小、干净、可读。PHP是完美的 对于小的个人页面(最初它代表“个人主页”), 而Rails是一个完整的MVC框架,可用于构建大型 地点。

    红宝石钢轨 没有 比类似的PHP框架更大的可伸缩性问题。 如果您只有一个中等的数字,那么Rails和PHP都可以很好地扩展。 在相同数量的对象上操作的用户(10000-100000)。 对于几千个用户来说,经典的单片架构 足够了。通过一点M&M(memcached和mysql),您还可以 处理数百万个对象。M&M架构使用MySQL服务器 处理写入和memcached以处理高读取负载。传统 存储模式,使用规范化关系表的单个SQL服务器 (或最多是SQL主/多读从设置)不再工作 对于非常大的站点。

    如果你有数以十亿计的用户,比如谷歌、Twitter和Facebook,那么 可能分布式架构会更好。如果你真的想 无限制地扩展应用程序,使用一些便宜的商品硬件 作为基础,将应用程序划分为一组服务,保持 每个组件或服务都可以自行扩展(将每个组件设计为 一个可扩展的服务),并使体系结构适应您的应用程序。 然后您将需要合适的可扩展数据存储,如NoSQL数据库。 以及分布式哈希表(DHT),您将需要复杂的map reduce 与之合作的算法,你必须处理SOA,外部 服务和消息传递。PHP和Rails都没有提供一个魔法子弹。

        5
  •  6
  •   phresus    16 年前

    RoR的缺点是,除非你在Alexa的前100强,否则你不会有任何可伸缩性问题。在共享主机上,您会遇到更多关于稳定性的问题,除非您能够挤出phulsion、passenger或mongrel。

        6
  •  5
  •   Mike Woodhouse    16 年前

    花点时间看看Twitter用户必须处理的问题,然后问问自己,你的应用是否需要扩展到这个水平。

    不管怎样,在Rails中构建它,因为您知道它是有意义的。如果你达到Twitter级别的流量,那么你将处于考虑性能优化选项的有利位置。至少你会用一种好的语言来应用它们!

        7
  •  2
  •   Joe    14 年前

    你不能比较php和ror,php是Ruby的脚本语言,Rails是Cakephp的框架。
    声明说,我强烈建议您Rails,因为您将有严格的应用程序 以MVC模式组织 这是一个 必须 满足您的可扩展性需求。(使用PHP时,您必须自己处理项目组织)。
    但是对于可伸缩性,Rails不仅仅是MVC:例如,您可以开始使用数据库开发应用程序,在路上不费任何努力地对其进行更改(在大多数情况下),因此我们可以声明Rails应用程序是(几乎是) 数据库独立 因为它是ORM(允许您避免数据库查询),所以您可以做很多其他的事情。
    (看看这个视频 http://www.youtube.com/watch?v=p5EIrSM8dCA )

        8
  •  2
  •   Aree Cohen    13 年前

    只是想在Keith Hanson关于1+N问题的聪明观点中添加更多信息,他说:

    数据映射器是处理上述问题的一种很好的方法(它没有1+N问题),但更好的方法是使用大脑停止执行这样的查询:d当需要原始性能时,大多数ORM层将不容易处理非常定制的查询,因此您也可以手工编写它们。

    条令是PHP最流行的ORM之一。它通过提供一种称为条令查询语言(DQL)的语言来解决ORMS固有的1+N复杂性问题。这允许您编写使用现有模型关系的类似SQL的语句。例如

    $Q=条令查询::创建() -选择(*) ->来自(M型) ->左联接(M.ModelB) & &执行()

        9
  •  1
  •   Jeff    11 年前

    我从这个线程中得到的印象是,ror的可伸缩性问题主要归结为ORM在加载子对象方面的混乱,即上面提到的“1+n”问题。在上面的例子中,Ryan与狗和主人一起给出:

    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,以便上面的示例将引发到DB和单个SQL语句的一次往返,而不是潜在的数百次往返?完全地。只需将这些表连接到一个数据集中,然后执行一些逻辑来缝合它。要使这种逻辑成为通用逻辑有点困难,这样它就可以处理任何一组对象,而不是世界末日。最后,表和对象只在三个类别(1:1、1:many、many:many)中的一个类别中相互关联。只是从来没有人建造过那个ORM。

    您需要一个预先告诉系统要为此加载哪些子项的语法。 特定的 查询。您可以通过“热切地”加载linqtosql(c)来实现这一点,linqtosql不是ror的一部分,但即使这会导致到db的一次往返,但它仍然是数百个独立的SQL语句,与当前设置的方式相同。更多的是关于ORMS的历史。他们刚刚开始走上错误的道路,在我的意见中从未真正恢复。懒惰加载”是大多数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语句查询,而这些查询应该是一个往返和一个SQL语句。