71

私はしばらくの間 PHP を使用しており、優れたフレームワークである CodeIgniter とうまく組み合わせて使用​​しています。私は新しい個人的なプロジェクトを開始していますが、前回、何を使用するか (PHP と ROR) を検討していたとき、特に Twitter 開発者がそれについて言わなければならなかったことを読んだ後、ROR にはスケーラビリティの問題があると聞いたので、PHP を使用しました。スケーラビリティは ROR でまだ問題になっていますか、それとも改善されていますか?

新しい言語を学びたいのですが、ROR は面白そうです。PHP は仕事を成し遂げますが、誰もが知っているように、その構文と構成はお粗末で、1 つの大きなハックのように感じます。

4

9 に答える 9

161

ライアン・ドハティの答えを少し拡張するために...

私は日常業務(.NET / C#)で静的に型付けされた言語で作業し、副次的なものとしてRubyで作業しています。現在の仕事の前は、ニューヨークタイムズシンジケーションサービスの仕事をしているルビー開発会社のリードプログラマーでした。その前は、PHPでも働いていました(ずっと昔ですが)。

簡単に言うと、レール(およびより一般的にはルビー)のパフォーマンスの問題や、その他のいくつかの問題を直接経験しました。ライアンが言うように、自動的にスケーリングすることはありません。ボトルネックを見つけるには、作業と膨大な忍耐が必要です。

他の人や私たち自身から見たパフォーマンスの問題の大部分は、ORMレイヤーでパフォーマンスの遅いクエリを処理していました。Rails/ActiveRecordからRails/DataMapper、そして最後にMerb / DMに移行しましたが、基盤となるフレームワークのおかげで、各反復の速度が向上しました。

キャッシングは、パフォーマンスに驚くべき驚異をもたらします。残念ながら、データをキャッシュできませんでした。キャッシュは最大で5分ごとに事実上無効になります。私たちのサイトのほぼすべてのビットが動的でした。ですから、それができない場合は、おそらく私たちの経験から学ぶことができます。

データベースインデックスを真剣に微調整し、クエリが非常に愚かなことをしていないことを確認し、絶対に必要な数よりも多くのクエリを実行していないことを確認する必要がありました。 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レイヤーは非常にカスタムなクエリを簡単に処理できないため、手書きで作成することをお勧めします。

常識的なこともしました。拡大するデータベース用に強力なサーバーを購入し、専用のボックスに移動しました。また、大量の処理とデータのインポートを絶えず行わなければなりませんでした。処理を独自のボックスに移しました。また、データインポートユーティリティのためだけに、おかしなスタック全体の読み込みを停止しました。絶対に必要なものだけを上品にロードしました(したがって、メモリのオーバーヘッドが削減されます!)。

まだわからない場合は...一般的に、ruby / rails / merbに関しては、スケールアウトして、問題にハードウェアを投入する必要があります。しかし、結局のところ、ハードウェアは安価です。それは見苦しいコードの言い訳にはなりませんが!:D

そして、これらの困難があっても、私がそれを助けることができれば、私は個人的に別のフレームワークでプロジェクトを開始することは決してありません。私はその言語が大好きで、毎日それについてもっと学び続けています。これは私がC#から得られないものですが、C#の方が高速です。

私はまた、オープンソースツール、その言語での作業を開始するための低コスト、何かを手に入れてそれが市場性があるかどうかを確認するための低コストを楽しんでいます。 ..。。

結局のところ、フレームワークの選択に関しては、毎日何を生き、呼吸し、食べ、そして眠りたいかがすべてです。Microsoftの考え方が気に入った場合は、.NETにアクセスしてください。オープンソースが必要であるが構造が必要な場合は、Javaを試してください。動的言語を使用し、それでもrubyよりも構造を少し増やしたい場合は、pythonを試してください。そして、優雅さが必要な場合は、Rubyを試してみてください(私は子供です、私は子供です...法案に合う他の多くのエレガントな言語があります。炎上戦争を始めようとはしていません:D)

地獄、それらすべてを試してみてください!私は上記の答えに同意する傾向があります。最適化を早期に心配することは、フレームワークを選択する必要がある、または選択すべきでない理由ではありませんが、これが唯一の答えであることに同意しません。

つまり、はい、克服しなければならない困難がありますが、言語の優雅さ、imhoは、それらの欠点をはるかに上回っています。

小説で申し訳ありませんが、私はそこに行って、パフォーマンスの問題で戻ってきました。それは克服することができます。だから、それがあなたを怖がらせないでください。

于 2009-02-02T20:14:08.460 に答える
27

RoR は多くの巨大な Web サイトで使用されていますが、他の言語やフレームワークと同様に、多数のユーザーに対応するには適切なアーキテクチャ (データベースのスケーリング、キャッシュ、チューニングなど) が必要です。

スケーリングを容易にするために RoR にいくつかのマイナーな変更が加えられていますが、魔法のようにスケーリングするとは思わないでください。すべての Web サイトにはさまざまなスケーリングの問題があるため、スケーリングするためにいくつかの作業を行う必要があります。

于 2009-02-02T16:07:39.770 に答える
16

あなたのプロジェクトが成功する可能性を最大限に高めるテクノロジーで開発してください - 迅速な開発、簡単なデバッグ、簡単な展開、優れたツール、すべてを知っている (新しい言語を学ぶことが目的でない限り) などです。

1 か月に数千万のユニーク数を獲得する場合は、常に数人を雇用し、必要に応じて別のテクノロジで書き直すことができます...

...キャッシュをかき集めます(申し訳ありませんが、抵抗できませんでした!!)

于 2009-02-02T16:17:37.627 に答える
14

まず第一に、Ruby on Rails は完全な Web アプリケーション フレームワークであるため、Rails を Symfony、CodeIgniter、または CakePHP と比較することはおそらくより理にかなっています。PHP または PHP フレームワークと比較して、Rails アプリケーションには、小さく、クリーンで、読みやすいという利点があります。PHP は小規模な個人用ページ (元々は "Personal Home Page" の略) に最適ですが、Rails は大規模なサイトの構築に使用できる完全な MVC フレームワークです。

Ruby on Railsには、同等の PHP フレームワークよりも大きなスケーラビリティの問題はありません。同様の数のオブジェクトを操作する適度な数のユーザー (10,000 ~ 100,000) しかない場合、Rails と PHP はどちらも適切にスケーリングします。数千人のユーザーの場合、従来のモノリシック アーキテクチャで十分です。少しの M&M (Memcached と MySQL) を使用すると、何百万ものオブジェクトを処理することもできます。M&M アーキテクチャは、MySQL サーバーを使用して書き込みを処理し、Memcached を使用して高い読み取り負荷を処理します。正規化されたリレーショナル テーブルを使用する単一の SQL サーバー (またはせいぜい SQL マスター/複数の読み取りスレーブのセットアップ) である従来のストレージ パターンは、非常に大規模なサイトでは機能しなくなりました。

Google、Twitter、Facebook などのユーザーが何十億人もいる場合は、おそらく分散アーキテクチャの方が適しています。本当にアプリケーションを無制限にスケーリングしたい場合は、ある種の安価なコモディティ ハードウェアを基盤として使用し、アプリケーションを一連のサービスに分割し、各コンポーネントまたはサービス自体をスケーラブルに保ち (すべてのコンポーネントをスケーラブルなサービスとして設計する)、適応させます。アプリケーションへのアーキテクチャ。次に、NoSQL データベースや分散ハッシュ テーブル (DHT) などの適切なスケーラブルなデータストアが必要になり、それらを操作するための洗練された map-reduce アルゴリズムが必要になり、SOA、外部サービス、およびメッセージングに対処する必要があります。ここでは、PHP も Rails も特効薬を提供しません。

于 2011-07-18T09:05:31.797 に答える
6

RoR を分解すると、Alexa のトップ 100 に入らない限り、スケーラビリティの問題は発生しないということです。Phusion、Passenger、または Mongrel を絞り出さない限り、共有ホスティングの安定性にさらに問題が生じるでしょう。

于 2009-02-02T16:01:20.077 に答える
5

Twitterの人々が対処しなければならなかった問題を少し見てから、アプリをそのレベルに拡張する必要があるかどうかを自問してください。

それから、それが理にかなっていることを知っているので、とにかくそれをRailsでビルドします。Twitterレベルのボリュームに到達すると、パフォーマンスの最適化オプションを検討できるようになります。少なくとも、あなたはそれらを素敵な言語で適用するでしょう!

于 2009-02-02T20:02:56.953 に答える
2

PHP と ROR を比較することはできません。PHP は Ruby としてのスクリプト言語であり、Rails は CakePHP としてのフレームワークです。Rails を強くお勧めします。MVC パターン
で 厳密に編成されたアプリケーションが必要になるためですこれは、スケーラビリティ要件の必須要件です。(PHP を使用する場合は、プロジェクトの構成を自分で管理する必要がありました)。 しかし、スケーラビリティについては、Rails は MVC だけではありません。たとえば、データベースを使用してアプリケーションの開発を開始し、(ほとんどの場合) 何の努力もせずに (ほとんどの場合) 途中で変更することができるため、Rails アプリケーションはORM(データベースクエリを回避できる)であるため、(ほとんど)データベースに依存しません。他の多くのことを実行できます。

(このビデオをご覧ください http://www.youtube.com/watch?v=p5EIrSM8dCA )

于 2011-06-17T14:20:28.717 に答える
2

1 + N 問題に関する Keith Hanson のスマート ポイントにさらに情報を追加したかっただけで、次のように述べています。

DataMapper は、上記の問題を処理するための優れた方法です (1 + N の問題はありません) が、さらに良い方法は、頭脳を使ってそのようなクエリをやめることです:D 生のパフォーマンスが必要な場合、ORM のほとんどはレイヤーは、非常にカスタムなクエリを簡単に処理できないため、手動で作成することもできます。

Doctrine は、PHP で最も人気のある ORM の 1 つです。Doctrine Query Language (DQL) と呼ばれる言語を提供することで、ORM に固有のこの 1 + N の複雑さの問題に対処します。これにより、既存のモデル関係を使用する SQL のようなステートメントを作成できます。例えば

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

于 2012-02-16T10:45:41.500 に答える
1

このスレッドから、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

実際に 1 つの sql ステートメントを記述してすべてのデータを取得することも、そのデータをカスタム作成オブジェクトの Dog.Owner.Siblings.Pets オブジェクト階層に「ステッチ」することもできます。しかし、誰かがそれを自動的に行う ORM を作成して、上記の例で DB への 1 回のラウンドトリップと 1 回の SQL ステートメントが発生する可能性があるのではなく、何百回も発生する可能性があるでしょうか? 完全に。これらのテーブルを 1 つのデータセットに結合し、いくつかのロジックを実行してそれをつなぎ合わせます。そのロジックを一般的なものにして、あらゆるオブジェクトのセットを処理できるようにするのは少し難しいですが、世界の終わりは処理できません。最終的に、テーブルとオブジェクトは、3 つのカテゴリ (1:1、1:多、多:多) のいずれかでのみ相互に関連付けられます。誰もそのORMを構築したことがないというだけです。

この特定のためにどの子をロードするかを事前にシステムに伝える構文が必要ですクエリ。これは、ROR の一部ではない LinqToSql (C#) の「イーガー」ロードを使用して行うことができますが、DB への 1 回のラウンド トリップが発生しても、依然として何百もの個別の SQL ステートメントです。現在設定中です。それは、ORM の歴史に関するものです。彼らはそれで間違った道を歩み始めたばかりで、私の意見では本当に回復することはありませんでした. 「遅延読み込み」は、ほとんどの 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) をより適切に作成する必要がない理由にはなりません。ハードウェアは実際には、1 回の往復と 1 つの SQL ステートメントであるはずの 8 回の往復、100 の SQL ステートメントのクエリからあなたを救い出しません。

于 2014-06-24T21:39:48.220 に答える