39

私は、電子メール サービスとソーシャル ネットワークの間のどこかにある Web アプリに取り組んでいます。今後かなり大きくなる可能性を感じているので、スケーラビリティが気になります。

集中化された 1 つの MySQL/InnoDB データベースを使用し、その時が来たらそれを分割する代わりに、アクティブなユーザーごとに個別の SQLite データベースを作成することにしました。つまり、「シャード」ごとに 1 つのアクティブなユーザーです。

そうすれば、データベースのバックアップは、各ユーザーの小さなデータベース ファイルをリモートの場所に 1 日に 1 回コピーするのと同じくらい簡単になります。

スケールアップは、新しいファイルを保存するためにハードディスクを追加するのと同じくらい簡単です。

アプリが単一のサーバーを超えて成長した場合、GlusterFS を使用してファイルシステム レベルでサーバーをリンクし、アプリを変更せずに実行するか、各サーバーが隣接するサーバーの sqlite ファイルを操作できるようにする単純な SQLite プロキシ システムを装備できます。

各 HTTP リクエストは一度に 1 つまたは 2 つのデータベース ファイルにしかアクセスせず、SQLite は読み取り時にのみブロックするため、同時実行の問題は最小限に抑えられます。

このアプローチにより、アプリを適切にスケーリングし、多くのクールでユニークな機能をサポートできると確信しています。私は間違った賭けですか?何か不足していますか?

更新これまでのところ問題なく機能している、それほど極端ではないソリューションを使用することにしました。私は一定数のシャードを使用しています - 正確には256個のsqliteデータベースです。各ユーザーは、単純なハッシュ関数によってランダムなシャードに割り当てられ、バインドされます。

私のアプリのほとんどの機能では、1 回のリクエストで 1 つまたは 2 つのシャードにアクセスする必要がありますが、ユーザーによっては、256 個の異なるシャードのうち 10 ~ 100 個の異なるシャードに対して単純なクエリを実行する必要があるものがあります。テストでは、すべてのデータが RAM にキャッシュされている場合、約 0.02 秒以下かかることが示されています。私はそれで生きていけると思います!

UPDATE 2.0アプリを MySQL/InnoDB に移植し、通常のリクエストではほぼ同じパフォーマンスを得ることができましたが、シャード ウォーキングを必要とするその 1 つのリクエストでは、innodb が 4 ~ 5 倍高速です。この理由とその他の理由で、私はこのアーキテクチャを削除しますが、どこかで誰かがその用途を見つけてくれることを願っています...ありがとう。

4

8 に答える 8

31

これが失敗するのは、「シャード ウォーキング」と呼ばれるものを実行する必要がある場合です。これは、多数の異なるユーザーからすべてのデータを見つけることです。その特定の種類の「クエリ」は、プログラムで実行し、各 SQLite データベースに順番に問い合わせる必要があり、サイトの最も遅い側面になる可能性が非常に高くなります。これは、データが個別のデータベースに「分割」されているシステムでは一般的な問題です。

すべてのデータがユーザーにとって自己完結型である場合、これはかなりうまくスケーリングする必要があります。これを効果的な設計にするための鍵は、データがどのように使用される可能性が高いか、および 1 人のデータが相互作用するかどうかを知ることです。 (あなたのコンテキストで)別のデータを使用して。

また、ファイル システム リソースに注意する必要がある場合もあります。SQLite は優れている、素晴らしい、高速などです。設計されています。提案されたデザインでは、そのいくつかを見逃しています。

于 2008-09-24T18:35:01.747 に答える
8

メンテナンスの悪夢のように思えます。これらすべての DB でスキーマが変更されるとどうなりますか?

于 2008-09-24T18:33:55.650 に答える
5

http://freshmeat.net/projects/sphivedb

SPHiveDB は sqlite データベースのサーバーです。JSON-RPC over HTTP を使用してネットワーク インターフェイスを公開し、SQLite データベースを使用します。複数の SQLite データベースを 1 つのファイルに結合することをサポートしています。また、複数のファイルの使用もサポートしています。これは、極端なシャーディング スキーマ (ユーザーごとに 1 つの SQLite データベース) 向けに設計されています。

于 2009-05-24T12:00:51.677 に答える
4

考えられる問題の1つは、ユーザーごとに1つのデータベースを使用すると、ディスク領域とRAMが非常に非効率的に使用され、ユーザーベースが拡大するにつれて、軽量で高速なデータベースエンジンを使用するメリットが完全に失われることです。

この問題の考えられる解決策は、それぞれ最大100人のユーザーを収容する1024個のSQLiteデータベースで構成される「ミニシャード」を作成することです。これは、データがより効率的にパックされるため、ユーザーごとのDBアプローチよりも効率的です。また、Sqliteを使用しているため、Innodbデータベースサーバーのアプローチよりも軽量です。

並行性もかなり良いでしょうが、クエリはあまりエレガントではありません(shard_id yuckiness)。どう思いますか?

于 2008-09-25T12:15:06.800 に答える
3

ユーザーごとに個別のデータベースを作成している場合、関係を設定していないように思えます...では、なぜリレーショナルデータベースを使用するのでしょうか?

于 2008-09-24T18:37:51.910 に答える
2

サーバー側のSQLLIteデータベースをクライアントのバックアップおよび同期コピーとして基本的に使用したかったので、これと同じアーキテクチャを検討しています。すべてのデータに対してクエリを実行するための私の考えは、全文検索に Sphinx を使用し、すべてのデータのフラット ダンプから Scribe への Hadoop ジョブを実行し、結果を Web サービスとして公開することです。しかし、この投稿は私に少し考えさせてくれるので、人々が引き続き意見を述べてくれることを願っています.

于 2008-10-30T04:00:14.817 に答える
2

データのシャーディングがこれほど簡単な場合は、標準のデータベース エンジンを使用するだけでなく、DB がボトルネックになるほど大規模にスケーリングする場合は、データベースをシャーディングして、異なるインスタンスの異なるユーザーを使用してください。効果は同じですが、多数の小さな小さなデータベースを使用しているわけではありません。

実際には、1 人のユーザーに属さない共有データが少なくともいくつかあり、複数のユーザーのデータに頻繁にアクセスする必要がある場合があります。ただし、これはどちらのシステムでも問題を引き起こします。

于 2008-09-24T18:39:43.763 に答える
1

もちろん、ユーザーごとに1つのデータベースを持つことで、個々のユーザーのデータを簡単に復元できますが、@Johnが言ったように、スキーマの変更にはいくつかの作業が必要になります.

難しくするのに十分ではありませんが、自明ではありません。

于 2008-09-28T17:05:13.947 に答える