0

制約と仕様がまだ設定されていない新しいプロジェクトの調査を行っています。必要なことの 1 つは、ルート ドメインの直下にある多数のパスです。これは、数百万のパスにまで増加する可能性があります。パスには共通の構造や独自の部分がないため、完全に一致するものを探す必要があります。

これらのパスを分割する方が効率的であることがわかりました。これは、パスの検索にも役立ちます。ただし、ここで可能性を調査しているので、ご容赦ください。

優れたパフォーマンスを維持しながら、これを達成する方法を評価しています。以下の方法を考えました。

  • パスを SQL データベースに保存し、リクエストごとにルックアップを実行します。これは最悪のオプションのように思われ、絶対に使用されません。
  • Redis などのキー値ストアにパスを格納します。これははるかに優れており、非常にうまく機能すると思います(ただし、ベンチマークする必要があります)。
  • 文字列/正規表現のマッチングを行う - 多くのフレームワークがすぐに使用できるように - この量の可能な一致はナッツであり、実際にはオプションではありません。しかし、スマートな最適化と組み合わせて、文字ごとに比較するある種のアルゴリズムを実行すると、どのように機能するかを見ることができました。

しかし、この種の問題により適した、私が知らないツール/方法があるかもしれません。ただし、これを達成する方法についてのヒントを使用できます。

ああ、誰かが疑問に思っている場合に備えて、いいえ、これは宿題ではありません.


アップデート

Redis アプローチをテストしました。2 セットのキーワードに基づいて、1 億 5000 万のパスが得られました。コマンドを使用してそれぞれを追加しましsetた。値は、リクエスト内の実際のキーワードを識別するために使用できる ID のシリアル化された文字列です。( SET 'keyword1-keyword2' '<serialized_string>')

100 万レコードのデータ セットを使用したローカル VM でのクイック テストでは、有望な結果が返されました。そして、これは他の多くのものを実行する私のラップトップにありました。

次に、4 コアと 8 GB の RAM を備えた VPS で、1 億 5000 万のレコードの完全なセットで完全なテストを行いました。これにより、ファイル サイズが 3.1G、メモリが約 9GB のデータベースが生成されました。データベースを完全にメモリにロードできなかったため、Redis はスワッピングを開始し、平均で約 100 ミリ秒というひどい結果を引き起こしました。

明らかに、これは機能せず、適切にスケーリングされます。これには、各 Web サーバーに膨大な量の RAM が必要になるか、専用の Redis ルーティング サーバーを使用する必要があります。データベースのサイズを劇的に縮小する方法を考案した Instagram のエンジニアの記事を読んだことがありますが、まだ試していません。いずれにせよ、これはこれを行う正しい方法ではないようです。ふりだしに戻る。

4

3 に答える 3

1

パスを SQL データベースに保存し、リクエストごとにルックアップを実行します。これは最悪のオプションのように思われ、絶対に使用されません。

データベースの機能を過小評価している可能性があります。そこでのあなたの立場を再考するようにあなたを招待できますか?

Postgres (または InnoDB を備えた MySQL) の場合、100 万のエントリは非常に小さいです。パス全体をフィールドに保存し、それにインデックスを追加し、バキュームし、分析します。キー オブジェクトの ID を特定するまでは、面倒な結合を行わないでください。ルックアップ速度に関しては問題ありません。psql からクエリを実行するときは、数ミリ秒と言います。

大量のトラフィックが発生した場合、実際の問題はディスク IO に関連するボトルネックになります。ここでの運用上のモットーは、「少ないほど良い」です。PHP サーバーに APC をインストールする、Ruby を使用している場合は Passenger を使用するなどの基本事項に加えて、次のことを行います。

  1. そのインデックスに適合する十分な RAM がサーバーにあることを確認してください。

  2. 各パスに関連するオブジェクトへの参照を memcached にキャッシュします。

  3. すべてのルートを 12 程度の正規表現で分類できれば、メモリに保持しやすい、より小さく、よりターゲットを絞ったインデックスを使用できるようになるため、役立つ可能性があります。そうでない場合は、パス全体 (おそらく末尾のスラッシュ) の保存に固執して、先に進みます。

  4. ミスが心配。正規の URL にリダイレクトする非正規の URL がある場合は、リダイレクトを有効期限なしで memcached に保存し、そのまま使用してください。

  5. 大量の RAM と memcached について言及しましたか?

  6. ああ、使用している ORM を過大評価しないでください。データ ストアが結果を解析、取得、返すのにかかる時間よりも、クエリの作成に時間がかかる可能性があります。

  7. RAM... Memcached...

正直なところ、Reddis は SQL + memcached オプションとそれほど違いはありませんが、メモリ管理 (ご存じのとおり)、シャーディング、レプリケーション、および構文に関しては例外です。もちろん親しみやすさも。

あなたの重要な決定ポイント(いくつかの正規表現を反復することを除いて)は、データがどのように構造化されているかでなければなりません。高度に構造化されていて原子性が重要な必要がある場合は、SQL + memcached を優先する必要があります。いたるところにカスタム フィールドがあり、EAV テーブルが肥大している場合は、Reddis、CouchDB、または別の NoSQL ストアで遊んでみることをお勧めします。

どちらの場合でも、これらのインデックスをメモリに保持するために大量の RAM を用意しておくと役立ちます。スケーリングが必要な場合でも、全体の前に memcached クラスターを配置しても問題はありません。

于 2013-04-24T17:10:56.843 に答える
1

Redisが最善の策だと思います。SQLは遅くなり、私の経験からの正規表現は常にクエリで非常に遅くなります。

Redis をテストするには、次の手順を実行します。

  1. ローカル VM または EC2 などのクラウドで Redis インスタンスを起動します。
  2. 辞書を 1 つまたは 2 つダウンロードして、このデータを Redis に送り込みます。たとえば、次のようなものがあります: http://wordlist.sourceforge.net/データを正規化してください。たとえば、常に文字列を小文字にし、文字列の先頭/末尾の空白を削除するなどです。
  3. ハッシュは無視します。URL をハッシュする必要がある理由がわかりません。何かをデバッグしたい場合、後で読むことは不可能であり、何も「購入」していないようです。http://www.sha1-online.com/にアクセスし、入力してハッシュとしてryan取得しました。ea3cd978650417470535f3a4725b6b5042a6ab59元のテキストは、Redis に役立つ RAM に入れるにははるかに小さくなります。明らかに、より長いパスの場合、ハッシュの方が優れていますが、例は非常に小さかったです。=)
  4. Redis から読み取るツールを作成し、そのパフォーマンスを確認します。
  5. 利益!

Redis はデータセット全体を RAM に保持する必要があるため、それに応じて計画してください。

于 2013-04-23T23:36:21.217 に答える
0

ある種のキーと値のストア (つまり、ハッシング ストア) を使用することをお勧めします。おそらく、キーをハッシュして短くすることもできます (SHA-1 のようなもので問題ありません)。

于 2013-04-19T19:58:59.700 に答える