web-dev-qa-db-ja.com

数十億行に最適なデータストア

数十億のレコード(1年間で約30億/月)の小さなデータ(約50〜75バイト)を保存できる必要があります。

唯一の要件は、同じGUID=と、.netからデータストアにアクセスする機能を持つすべてのレコードの高速挿入と高速ルックアップです。

私はSQLサーバーの男で、SQL Server canを実行すると思いますが、BigTable、CouchDB、およびその他のnosqlソリューションに関するすべての話を聞くと、従来のRDBSに代わるもののように聞こえます分散クエリとスケーリングの最適化により最適な場合があります。 cassandra=を試してみましたが、.netライブラリは現在コンパイルされていないか、すべてが変更される可能性があります(cassandra自体と一緒に) 。

使用可能な多くのnosqlデータストアを調べましたが、堅牢な実稼働対応プラットフォームとしてのニーズを満たすものは見つかりません。

.netからアクセスできるように、360億の小さなフラットレコードを保存する必要がある場合、何を選択しますか?

81
Jody Powlette

〜3.5TBのデータを保存し、約1K /秒24x7を挿入し、指定されていないレートでクエリを実行することは、SQL Serverでは可能ですが、さらに質問があります。

  • これにはどのような可用性要件がありますか? 99.999%の稼働率、または95%で十分ですか?
  • 信頼性の要件は何ですか?挿入がないと100万ドルかかりますか?
  • どのような回復可能性の要件がありますか? 1日分のデータを失った場合、それは重要ですか?
  • 一貫性の要件は何ですか?書き込みは、次の読み取りで表示されることを保証する必要がありますか?

私が強調したこれらすべての要件が必要な場合、提案する負荷は、どのような仕掛け(シャーディング、パーティショニングなど)に関係なく、リレーショナルシステム、任意のシステムのハードウェアとライセンスに数百万の費用がかかります。 nosqlシステムは、その定義により、これらの要件をall満たさないでしょう。

したがって、明らかにこれらの要件のいくつかはすでに緩和されています。 Visual Guide to NoSQL Systems :の「pick 2 out of 3」パラダイムに基づいたnosql製品を比較する素敵なビジュアルガイドがあります。

nosql comparisson

OPコメント更新後

SQL Serverでは、これは簡単な実装です。

  • クラスター化された1つのテーブル(GUID、時間)キー。はい、 fragmented を取得しますが、フラグメンテーションは先読みに影響し、先読みは重要な範囲スキャンにのみ必要です。特定のGUIDおよび日付範囲のみをクエリするため、断片化はそれほど重要ではありません。はい、幅の広いキーであるため、非リーフページのキー密度は低くなります。これらの問題にもかかわらず、要件を考えると、依然として最適なクラスター化キーの選択です。
  • 自動スライディングウィンドウ を使用して、有効期限が切れたレコードの効率的な削除を実装できるように、時間ごとにテーブルをパーティション分割します。先月のオンラインインデックスパーティションの再構築でこれを強化し、GUIDクラスタリングによって導入された貧弱なフィルファクターと断片化を排除します。
  • ページ圧縮を有効にします。 GUID=によってクラスター化されたキーグループが最初にあるため、a GUID=のすべてのレコードは、 ページ圧縮 a辞書圧縮を展開する良い機会です。
  • ログファイルの高速なIOパスが必要です。ログが1K挿入/秒に対応するための低レイテンシではなく、高スループットに関心があるため、 ストリッピング は必須です。

パーティション化とページ圧縮にはそれぞれEnterprise Edition SQL Serverが必要です。これらはStandard Editionでは機能せず、両方とも要件を満たすために非常に重要です。

サイドノートとして、レコードがフロントエンドWebサーバーファームからのものである場合、各WebサーバーにExpressを配置し、バックエンドにINSERTではなく、 SEND を配置しますバックエンドへの情報。Webサーバーと同じ場所にあるExpressのローカル接続/トランザクションを使用します。これにより、ソリューションの可用性が大幅に向上します。

これが、SQL Serverでの方法です。良いニュースは、あなたが直面する問題がよく理解され、解決策が知られているということです。だからといって、これがCassandra、BigTable、またはDynamoで達成できるものよりも優れているとは限りません。私は、誰かが自分の主張を議論するために、非SQLっぽいことにもっと知識を持たせるようにします。

プログラミングモデル、.Netサポートなどについては言及していません。正直に言って、大規模な展開には関係ないと思います。それらは開発プロセスに大きな違いをもたらしますが、一度デプロイすると、ORMオーバーヘッドがパフォーマンスを低下させる場合でも、開発がどれほど速くても問題ありません。

99
Remus Rusanu

一般的な信念に反して、NoSQLはパフォーマンスやスケーラビリティに関するものではありません。これは、主にいわゆるオブジェクトリレーショナルインピーダンスの不一致を最小限に抑えることですが、RDBMSのより一般的な水平スケーラビリティと、より典型的な垂直スケーラビリティについても同じです。

高速挿入と高速検索の単純な要件については、ほとんどすべてのデータベース製品が対応します。リレーショナルデータを追加したり、結合したり、複雑なトランザクションロジックや制約を適用する必要がある場合は、リレーショナルデータベースが必要です。 NoSQL製品は比較できません。

スキーマレスデータが必要な場合は、MongoDBやCouchDBなどのドキュメント指向のデータベースを使用する必要があります。ルーズスキーマは、これらの主な目的です。私は個人的にMongoDBが好きで、いくつかのカスタムレポートシステムで使用しています。データ要件が絶えず変化しているときに非常に便利だと思います。

もう1つの主なNoSQLオプションは、BigTableやCassandraなどの分散Key-Valueストアです。これらは、コモディティハードウェアを実行している多くのマシンでデータベースを拡張する場合に特に役立ちます。明らかにサーバーでも正常に動作しますが、ハイエンドハードウェアや、SQL ServerやOracle、またはverticalスケーリング用に設計された他のデータベースを活用しないでください。明らかに、リレーショナルではありません。また、正規化や制約を実施するのには適していません。また、お気づきのように、.NETサポートはせいぜいむらになりがちです。

すべてのリレーショナルデータベース製品は、限られた種類のパーティション分割をサポートしています。 BigTableや他のDKVSシステムほど柔軟ではないため、サーバー間で簡単にパーティション分割できませんhundredsですが、実際に探しているようには聞こえません。インデックスを作成してデータを適切に正規化し、強力なハードウェア(特に余裕がある場合は特にSSD)でデータベースを実行し、2つまたは3つまたは5つの物理ディスクに分割する限り、数十億のレコード数の処理に非常に優れています必要。

上記の基準を満たしている場合、企業環境で作業していて、まともなハードウェアとデータベースの最適化に費やすお金があるなら、今のところSQL Serverを使い続けます。少額をつまんでいて、これをローエンドのAmazon EC2クラウドコンピューティングハードウェアで実行する必要がある場合は、おそらくCassandraまたはVoldemortを選択することをお勧めします(どちらかが機能する場合) .NETで)。

16
Aaronaught

数十億行セットのサイズで作業する人は非常に少なく、ほとんどの場合、スタックオーバーフローでこのようなリクエストが表示され、データは報告されているサイズに近づきません。

360億、1か月あたり30億、1日あたり約1億、1時間あたり416万、1分あたり7万行、1秒あたり1万1千行が、ダウンタイムを想定せずに12か月間持続的にシステムに入力されます。

これらの数字は長いマージンで不可能ではありません、私はより大きなシステムを実行しましたが、それは本当にあなたが意味する量である二重チェックしたいです-非常に少数のアプリは本当にこの量を持っています。

保存/取得の面で、あなたが言及していない非常に重要な側面は、古いデータのエージングです-削除は無料ではありません。

通常の技術ではパーティション分割が見られますが、12か月間すべての一致する値を取得する必要があると仮定すると、GUIDベースのルックアップ/取得はパフォーマンスが低下します。 GUID列にクラスター化インデックスを配置すると、関連付けられたデータが読み取り/書き込み用にクラスター化されますが、これらの量と挿入速度では、断片化が非常に高くなり、サポートできなくなります。床に落ちる。

また、これがOLTPタイプの応答速度を伴う深刻なアプリケーションである場合、非常にまともなハードウェア予算が必要になることをお勧めします。約2.7TBのデータ。

SQL Serverのキャンプで見たいのは、新しい並列データウェアハウスエディション(マディソン)だけです。これは、データを分割し、それに対して並列クエリを実行して大規模なデータマートに対して高速を提供するように設計されています。

12
Andrew

「数十億件のレコード(1年で約30億件)の小さなデータ(約50〜75バイト)を保存できる必要があります。

唯一の要件は、同じGUIDおよび.netからデータストアにアクセスする機能)を持つすべてのレコードの高速挿入と高速ルックアップです。

経験から、SQL Serverでこれが可能であることを伝えることができます。なぜなら、2009年の初めにそれを行ったからです。

テーブルは256パーティションに分割されました。これは2005 SQLバージョンであることに注意してください...そして、あなたが言っていることを正確に行いました。つまり、GUID by GUID=すぐに。

私が去ったとき、私たちは約20億から30億のレコードを持っていて、データ保持ポリシーがインスタンス化されようとしていたにもかかわらず、データ取得はまだかなり良かったです(UIを介して1〜2秒、またはRDBMS上で1秒未満)。

つまり、長い話を短くすると、GUID=文字列から8番目の文字(つまり、中程度の場所)を取得し、SHA1はそれをハッシュし、小さなint(0-255)としてキャストし、データを取得するときに適切なパーティションと同じ関数呼び出しを使用します。

さらに情報が必要な場合は、pingを送信してください...

2
Goran B.

次の記事では、Microsoft SQLの16billion行テーブルのインポートと使用について説明します。 http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table

記事から:

私の経験から得たいくつかのヒントを以下に示します。

  • 定義されたクラスター化インデックスを持つテーブルにあるデータが多いほど、ソートされていないレコードをインポートするのが遅くなります。ある時点で、実用的になるには遅すぎます。
  • テーブルをできるだけ小さいファイルにエクスポートする場合は、ネイティブ形式にします。これは、文字データよりもバイナリフィールドでよりコンパクトに表現されるため、主に数値列を含むテーブルに最適です。すべてのデータが英数字の場合、ネイティブ形式でエクスポートしてもそれほど利益はありません。数値フィールドにヌルを許可しないと、データがさらに圧縮されます。フィールドをヌル可能にすると、フィールドのバイナリ表現には、続くデータのバイト数を示す1バイトのプレフィックスが含まれます。
  • BCPカウンター変数は4バイト整数であるため、2,147,483,647レコードを超えるBCPを使用できません。 MSDNやインターネットでこれに関する参照を見つけることができませんでした。テーブルが
    2,147,483,647を超えるレコード、チャンクでエクスポートする必要があります
    または独自のエクスポートルーチンを記述します。
  • 事前設定されたテーブルでクラスター化インデックスを定義するには、多くのディスク容量が必要です。私のテストでは、ログが元の10倍に爆発しました
    完成前のテーブルサイズ。
  • BULK INSERTステートメントを使用して多数のレコードをインポートする場合、BATCHSIZEパラメーターを含めて、数を指定します
    一度にコミットするレコード。このパラメーターを含めない場合、
    ファイル全体が単一のトランザクションとしてインポートされ、
    多くのログ領域が必要です。
  • クラスタ化インデックスを使用してテーブルにデータを取得する最速の方法は、最初にデータを事前ソートすることです。その後、BULKを使用してインポートできます
    ORDERパラメーターを指定したINSERTステートメント。
2
Charles Burns

Amazon Redshiftは素晴らしいサービスです。質問が最初に2010年に投稿されたときは利用できませんでしたが、現在は2017年の主要なプレーヤーです。Postgresから分岐した列ベースのデータベースであるため、標準SQLおよびPostgresコネクターライブラリで動作します。

レポート目的、特に集約に最適です。単一のテーブルからのデータは、Amazonのクラウド内の異なるサーバーに保存され、定義されたテーブルdistkeysによって分散されるため、分散CPUパワーに依存します。

したがって、SELECT、特に集約されたSELECTは非常に高速です。大きなデータのロードは、Amazon S3 csvファイルからのCOPYコマンドを使用して実行することをお勧めします。欠点は、DELETEとUPDATEが通常より遅いことですが、それがRedshiftが主に多国籍データベースではなく、より多くのデータウェアハウスプラットフォームにある理由です。

1
Martin Taleski

見過ごされているように見える異常な事実があります。

"基本的に1日に3000万行を挿入した後、同じGUID(おそらく20行)ですべての行をフェッチし、それらをすべて取り戻すことを合理的に確認する必要があります。 "

20列のみが必要な場合、GUIDの非クラスター化インデックスは正常に機能します。パーティション全体のデータ分散のために別の列にクラスター化できます。

データの挿入に関して質問があります:どのように挿入されますか?

  • これは特定のスケジュール(1分あたり、1時間あたりなど)での一括挿入ですか?
  • このデータはどのソースから取得されていますか(フラットファイル、OLTPなど)?

方程式の片側を理解するには、これらに答える必要があると思います。

1
Josef Richberg

CassandraまたはHBaseを使用してみてください。ただし、ユースケースごとに列ファミリを設計する方法を読む必要があります。Cassandra独自のクエリ言語ですが、Java HBaseのAPIを使用してデータに直接アクセスする必要があります。Hbaseを使用する必要がある場合は、オープンソースであるMap-RのApache Drillでデータをクエリすることをお勧めしますプロジェクトドリルのクエリ言語はSQL準拠です(ドリルのキーワードはSQLで使用するのと同じ意味を持ちます)。

0
Yayati Sule