2

1 日あたり 5,000,000 回の INSERTSBigTableが発生する可能性のあるテーブル ( と呼びましょう) があるとします (おそらく同じ数の SELECT を使用)。挿入される各行は約 50kb です。

これらの毎日の INSERT は、5 つのクライアントに均等に分割されます (テーブルには と呼ばれる FK がありますClientID)。複数のクライアント間でデータを選択または結合する必要はありません。

このテーブルが大きくなるにつれてデータベースのパフォーマンスが心配になるので、2 つの解決策を考え出しました。

解決策 1:

  • パーティションBigTable分割ClientID
  • サーバー上の個別のハード ディスクに各パーティションを格納します (Azure ブログ ストレージを使用)。
  • 1 か月前のすべてのデータ (アーカイブ データですが、クエリ可能である必要があります) を別の READONLY パーティションのセットに分割します。

基本的に、これは独自のストレージ デバイス上の次のパーティションを意味します。

  • プライマリ ( を除くすべてのデータBigTable)
  • ClientA BigTable(1 日あたり 5,000,000 行 / 5 クライアント x 30 日 = 30,000,000 行)
  • ClientB BigTable(30,000,000 行)
  • ClientC BigTable(30,000,000 行)
  • ClientD BigTable(30,000,000 行)
  • ClientE BigTable(30,000,000 行)
  • ClientA のBigTableアーカイブ
  • ClientB のBigTableアーカイブ
  • ClientC のBigTableアーカイブ
  • ClientD のBigTableアーカイブ
  • ClientE のBigTableアーカイブ

アーカイブ テーブルの行数は、(5,000,000) x (DB の経過日数) - (30,000,000) になります。これはまだ巨大なテーブルですが、奇妙なレポートを作成するためにのみ使用されます。

SQL Server は、14 GB、8 コアの Azure VM でホストされます。

解決策 2:

もう 1 つのオプションは、クライアントごとに個別のデータベースをホストすることです。これは、それぞれが専用の SQL Server マシンを持つことを意味します。アーカイブ データのパーティショニングは引き続き行われます。

データが物理的に分離されているため、このオプションは最適ではありません。複数のデータベースの更新を管理しなければならないことは、非常に問題になる可能性があります。クライアントごとに個別のデータベース接続を使用することも、開発者にとって考慮事項になります。

誰かがこれらのオプションについてアドバイスできますか?

4

3 に答える 3

5

[azure] と [sql-server] でタグ付けされているので、Windows Azure でこれを実行しようとしていると思います。その場合、a) クライアントによるパーティション化は必ずしも良い考えではなく、b) SQL は問題に最適 (完全) ではない可能性があります。

スケーラブルなアーキテクチャを構築する場合、パーティショニング戦略は「クライアント」などの特定のものに基づくべきではなく、より恣意的なものに基づくべきです。その理由は単純です。クライアントに、データを他のデータと混合したくない、またはクライアントごとに異なる SLA を望まないなど、分離する理由がない限り、パーティションとして「クライアント」を選択しても最適な結果が得られない可能性があります。ビジネスの 80% が単一のクライアントによって生成されている場合、問題は解決されておらず、わずかな負荷のためにn 個の個別のデータベースを維持する必要があります。

1 日あたり 500 万回のデータベース挿入は大きな数字ではありませんが、Azure IaaS または Azure SQL データベースでホストされている SQL Server にとっては大きな数字になる可能性があります。これは、基盤となるコモディティ ハードウェアのパフォーマンスによるものです。SQL を分割する方法を決定する前に、2 つの質問を自問してください。まず、データからどのような用途とパフォーマンス特性が必要か? (すぐに一貫性を保つ必要がありますか? データを非同期に処理できますか?) 次に、それらの特性を他のデータ ストア テクノロジに対してマッピングしましたか? Table Storage (または Redis のような非 MS ソリューション) を検討しましたか?

いくつかのオプションを試してみると、次のことがわかる場合があります。

  • SQL は、場合によっては、一部のデータの保存に適しています。
  • 処理の多くは非同期で実行できるため、挿入のピーク パフォーマンスはほとんど問題になりません (24 時間で 5 ミルの挿入を実行しても問題ありません)。
  • SQL は長期保存に適していない場合があります。
  • 古いデータのクエリは、SQL クエリではなく map-reduce を使用して効果的に実行できます。

たとえば、1 秒間隔で車両を追跡するアプリがあります。100,000 台の車両をターゲットにしていますが、コードやデータベースを変更することなく数百万台までスケールアップできるように設計されています。しかし、中期的には、1 日あたり 7,200 万の挿入に対処する必要があります。これらはすべて、10 GB 未満の単一の Windows Azure SQL データベースと、多数のテーブル ストレージで実行されます。これが機能する理由は、すべてのデータ (7,200 万行) をアーカイブしたいのですが、複雑な SQL クエリ アクセスを必要としないため、テーブル ストレージに問題なく収まるためです。私が SQL に保存するのは、データの要約です。したがって、私の例では、車両の旅(開始位置と終了位置、移動距離など)にのみ関心があります。つまり、SQL で必要な 1 日あたり 1 台の車両につき 2 ~ 3 行しかないことになり、データベースの負荷が大幅に軽減されます。また、私のボトルネックはデータの収集にあるため、データをすぐに (Windows Azure) キューに追加し、別のワークロードでのデータの集計について心配しています。

この回答は少し長いかもしれませんが、SQL で問題を解決する方法を考えるだけでなく、データ モデルについてより注意深く考えることを目的としています。詳細については、CALMのデータ モデルを参照してください。

于 2013-02-18T16:33:16.560 に答える
3

いくつかのアイデア: 1) SQL の代わりに Azure Tables を使用します。PartitionKey = ClientID を持っています。各テーブルは 200 TB で、20k IOPS をサポートします。各パーティションは 2k IOPS です。クライアントは論理的に分離されているため、自然な負荷分散 (パーティションごとの Azure 負荷分散) が得られます。これにより、XL VM を 24 時間年中無休で実行/管理する必要がなくなります (つまり、はるかに安価になります)。いずれにせよ、VM のデータ ドライブは Azure ストレージによってバックアップされるため、ストレージ コストは同じになります。1 日あたり 500 万回の挿入は 1 秒あたりわずか 60 回程度なので、成長の余地は十分にあります。これは、かなり単純化された挿入/選択を行っており、クライアントの境界を越えていないため、特に当てはまります。

2) クライアントごとの DB を実行する場合は、SQL Azure を使用します。プロビジョニングははるかに高速で、各 DB は個別のスケール ユニットです (これにより、1 つのクライアントが他のクライアントに問題を引き起こすことを防ぐことができます)。クライアントの変更に基づいて DB を動的に変更することもできます。

3) 単一のモノリシック DB が必要な場合は、VM 上の SQL Server を使用します。複数のデータ ドライブを作成し、それらをストライプ セットとしてマウントします。XL VM の場合、最大 16 個のドライブをマップできます。これにより、DB の最大サイズが 16 TB に制限されるため、エージング アウト/アーカイブ/ガベージ コレクションのためのメカニズムが必要になります。

于 2013-02-18T18:52:39.783 に答える
1

アクセス性能だけでなく、ディザスタリカバリ性能も考慮する必要があります。アクティブな月だけでもクライアントごとに 6 TB になるため、クライアントを別々のデータベースに保持することを強くお勧めします。

まともな Continuos Integration と自動化された展開プロセスがある場合、データベース スキーマの同期を維持することはそれほど大きな問題にはなりません。

于 2013-02-18T14:47:50.867 に答える