SQL Serverデータベースシャーディング-一般的なデータ/シャーディングされていないデータをどうするか


10

非常に大規模なエンタープライズレベルのデータベースがあります。私たちのビジネスモデルの一部として、すべてのWebユーザーが毎月同時にWebサーバーにアクセスし、それがSQLボックスに影響を与えています。トラフィックは非常に重く、会社が大きくなるほど大きくなります。sql proc最適化が実行され、ハードウェアはすでに非常に高いレベルに拡張されています。

現在、データベースを分割して、会社の成長と将来の負荷に対応できるようにしています。

どの特定のデータをシャーディングするかを決定しました。これは、高度に利用されているデータベースのサブセットです。

しかし、私の質問は、一般的/普遍的な非分割データに関するものです。このようなデータの例としては、たとえばInventoryテーブルや、おそらくEmployeeテーブル、userテーブルなどがあります。

この共通/普遍的なデータを処理する2つのオプションが表示されます。

1)設計1-共通/汎用データを外部データベースに配置します。すべての書き込みはここで行われます。その後、このデータは各シャードに複製され、各シャードがこのデータを読み取り、t-sql procでこのデータに内部結合することができます。

2)デザイン2-各シャードに、すべての共通/ユニバーサルデータの独自のコピーを提供します。各シャードがこれらのテーブルにローカルに書き込み、SQLマージレプリケーションを利用して、他のすべてのシャードでこのデータを更新/同期します。

設計に関する懸念#1

1)トランザクションの問題:シャードでデータを書き込んだり更新したりしてから、たとえば1つのストアドプロシージャで共通/ユニバーサルテーブルを書き込んだり更新したりする必要がある場合、これを簡単に行うことはできなくなります。現在、データは別個のSQLインスタンスとデータベースに存在しています。これらの書き込みは別のデータベースにあるため、トランザクションにラップできるかどうかを確認するために、MS DTSを使用する必要がある場合があります。ここではパフォーマンスが問題であり、シャーディングされた一般的なデータに書き込むプロシージャの場合、書き換えが発生する可能性があります。

2)参照整合性の喪失。データベース間の参照整合性を行うことはできません。

3)システムの広い領域を再コード化して、共通データを新しいユニバーサルデータベースに書き込み、共通データをシャードから読み取るようにします。

4)。データベーストリップの増加。上記の#1のように、シャーディングされたデータと共通データを更新する必要がある状況に遭遇した場合、データが別のデータベースにあるため、これを達成するために複数のラウンドトリップを実行することになります。ここでは多少のネットワーク遅延が発生しますが、この問題については上記3ほど心配していません。

設計に関する懸念#2

デザイン#2では、各シャードがすべての共通/ユニバーサルデータの独自のインスタンスを取得します。これは、一般的なデータに参加または更新するすべてのコードが、今日と同じように引き続き機能/実行されることを意味します。開発チームが必要とする再コーディング/書き換えはほとんどありません。ただし、この設計はすべてのシャード間でデータの同期を維持するためにマージレプリケーションに完全に依存しています。dbasは非常に熟練しており、マージレプリケーションがこれを処理できない可能性があり、マージレプリケーションが失敗した場合に非常に懸念しています。

デザインオプション#2を使用した人がいるかどうか知りたいです。また、表示されていない3番目または4番目のデザインオプションを見落としているかどうかも知りたいです。

前もって感謝します。


10
この場合、「非常に大規模なエンタープライズデータベース」と「すでに非常に高いレベルにスケールアップされている」ハードウェアとは何ですか。10のうち10回はシャーディングが解決策ではないので、あなたが解決している問題は何か疑問に思っています。
Mark Storey-Smith、

5
真面目に言うと、WebサーバーはSQLボックスを「ハンマーで打つ」と言っています。読み取りと書き込みの比率は?データを実際にどの程度最新にする必要があるかに応じて、パフォーマンス、コスト、または複雑さのトレードオフで、シャーディングなしで読み取りをスケールアウトする方法は数多くあります。そしてもちろん、書き込みデータをキューに入れる方法もあります。これも、保存されているデータのナノ秒までの必要性に応じて異なります。
アーロンバートランド

3
この特定の発言は、「ハードウェアはすでに非常に高いレベルに拡大されている」と私の注意を引いた。このハードウェアのスケールアップには何が入っていますか?
swasheck

2
64個の論理プロセッサがあり、CPUがボトルネックになっていますか?CPUを正確に駆動しているのは何ですか、再コンパイルしますか?あなたは知っていますか?
Aaron Bertrand

1
シャーディングが終わったらズボンをチェックします。
swasheck 2013年

回答:


5

あなたの質問はこれに焦点を合わせました:

しかし、私の質問は、一般的/普遍的な非分割データに関するものです。このようなデータの例としては、たとえばInventoryテーブルや、おそらくEmployeeテーブル、userテーブルなどがあります。

シャーディングを実行していて、すべてのシャードで表示する必要があるデータがある場合、そのデータをいくつかの属性で分類する必要があります。

頻繁に変化しますか?例では、在庫、従業員、ユーザーをリストしました。通常、在庫は非常に速く変化しますが、従業員の記録は定期的にしか変化しません(たとえば、1日に数百回の更新)。

各シャードはどのくらいの遅延を許容できますか?在庫は常に変化しているかもしれませんが、通常、そのようなテーブルでは大量の遅延(数分または数時間)を許容できます。在庫が非常に限られているユニークなアイテムを販売している場合(元のアートワークを考えると)、そのデータをシャーディングすることはなく、元のデータベースにクエリを実行するだけです。ただし、ほとんどのオンラインストアでは、毎日すべての商品が完売するわけではなく、とにかく迅速に在庫を補充するため、実際には数ミリ秒の在庫数は必要ありません。実際、ほとんどの場合、必要なのは0または1の在庫フラグのみで、中央プロセスがそのフラグを更新します。このようにして、アイテム数の上下のバンプをすべてのシャードにプッシュする必要はありません。一方、従業員またはユーザーのデータ

分割されたテーブルから分割されていないテーブルに参加しますか?理想的には、ここでの答えはノーです-データを取得するために2つの個別のクエリを作成し、アプリ側でそれらを結合する必要があります。これはアプリの観点からはかなり難しくなりますが、各ソースから最新のデータを取得する機能を提供します。

これは元のデータですか、それともコピーされたものですか?この質問を考えるもう1つの方法は、何をバックアップする必要があり、どれくらいの頻度でバックアップする必要があるかです。通常、大量のシャーディング環境では、バックアップをできるだけ速く、できるだけ小さくします。(結局のところ、各ノードを保護する必要があり、すべてのシャードを同じ時点でDRにフェイルオーバーする必要があります。他のシャードよりも新しいデータを含むシャードはありません。)これは、シャードされたデータと非シャード同じサーバー上にある場合でも、分割されたデータは完全に別のデータベースにある必要があります。シャーディングされた(元の)データのトランザクションログを定期的にバックアップする必要がありますが、シャーディングされていないデータをバックアップする必要はまったくありません。すべてのシャードでバックアップするよりも、単一の信頼できるソースからEmployeesテーブルまたはUsersテーブルを更新する方がおそらく簡単です。ただし、すべてのデータが単一のデータベースにある場合、

今、あなたの懸念について:

「トランザクションの問題...これを簡単に行うことができなくなります。」正しい。シャーディングされたシナリオでは、トランザクションの概念を枠から外してください。さらに悪化します-シャーディングされたデータの場合、クラスターインスタンスのフェイルオーバーまたは再起動により、1つのシャードがオンラインになり、別のシャードが一時的にダウンする可能性があります。システムの任意の部分の障害について、いつでも計画する必要があります。

「データベース間の参照整合性を行うことはできません。」正しい。単一のテーブルを複数のサーバーに分割する場合、大きな男の子のパンツを履いて、ポイントインタイムバックアップ、テーブル間の関係、データの結合などの難しいタスクを引き継ぐことをデータベースサーバーに伝えます。複数のソース。それはあなたとあなたのコードに今あります。

「システムの広い領域を再コーディングして、共通データを新しいユニバーサルデータベースに書き込み、シャードから共通データを読み取ることができるようにします。」ここでも修正します。このための簡単なボタンはありませんが、これをアプリに組み込んだ後は、クレイジーなようにスケーリングできます。これを行う簡単な方法は、アプリの接続を読み取りで分割することです

「データベース旅行の増加」-はい、データを複数のサーバーに分割すると、アプリはさらにネットワークに到達する必要があります。重要なのは、このデータの一部を低コスト、高スループット、ロックフリーのシステムに保存できるように、キャッシュも実装することです。最速のクエリは、あなたが作ることのないものです。

また、ここでは、個々のシャードでのパフォーマンスチューニング、シャードごとの異なるバックアップ/リカバリ戦略、スキーマデプロイメントの課題など、マルチテナントデータベースを分割することについて、賛否両論を示しています。


0

高レベルでは、データをシャーディング(または水平分割)する一般的な方法は、トランザクションテーブルをシャーディングし、マスターレベルのテーブルを複製することです。ほとんどのテクノロジーソリューションと同様に、これはもちろん、1つのセットの問題を解決し、まったく新しいセットの問題を作成します...しかし、私たちは皆、今ではそれに慣れていますよね。;-)

ただし、SQLServerがこれに最適なソリューションであるかどうかは疑問です。ワークロードはOLTPに近いですか、それともDW / BIに近いですか?

乾杯、デイブ・シスク


-2

可能な3番目のオプション。(ブラックボックスシャーディングの代わりに)リレーショナルシャーディングを使用すると、データベース全体をシャーディングおよび分散できるはずです。データベースは従来のリレーショナルデータモデルに基づいて構築されているため、データベースはどのデータがどのサーバーに格納されているか、したがってどこにあるかを認識しているため、すべてのデータを「共通/ユニバーサル」と見なすことができます。シャーディングプロセス全体を簡単にするための可能性として、dbShardsをチェックしてください。


3
この回答は、リレーショナルシャーディング、ブラックボックスシャーディング、それらの機能、一方が他方よりも優れている理由、そしてできれば雇用者がdbShardsであることの承認がないと意味がありません。
エレミヤペシュカ2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.