web-dev-qa-db-ja.com

何十億/何兆ものレコードのストレージを処理できるデータベースはどれですか?

現在、膨大な量を収集しているnetflowデータをキャプチャして分析するツールの開発を検討しています。毎日約14億のフローレコードをキャプチャしており、json形式では次のようになります。

{
   "tcp_flags": "0",
   "src_as": "54321",
   "nexthop": "1.2.3.4",
   "unix_secs": "1352234521",
   "src_mask": "23",
   "tos": "0",
   "prot": "6",
   "input": "105",
   "doctets": "186",
   "engine_type": "0",
   "exaddr": "2.3.4.5",
   "engine_id": "2",
   "srcaddr": "9.8.7.6",
   "dst_as": "12345",
   "unix_nsecs": "752265174",
   "sysuptime": "2943529544",
   "dst_mask": "24",
   "dstport": "80",
   "last": "2943523241",
   "srcport": "52672",
   "dpkts": "4",
   "output": "111",
   "dstaddr": "6.5.4.3",
   "first": "2943517993"
}

データセットに対して高速検索(10秒未満)を実行できるようにしたいと考えています。おそらく、時間の狭いスライス(10〜30分の間隔)を使用します。また、大部分のデータポイントにインデックスを付けて、それぞれのデータポイントをすばやく検索できるようにしたいと考えています。また、検索が実行されたときにデータを最新の状態で表示したいと考えています。オープンソースの世界に留まることは素晴らしいことですが、このプロジェクトのために独自のソリューションを検討することに反対するわけではありません。

約1か月のデータ(約432億レコード)を保持するという考えです。各レコードには約480バイトのデータが含まれ、1か月で約18.7テラバイトのデータに相当し、インデックスの場合はその3倍になるとおおよその見積もりです。最終的には、何兆ものレコードを保存できるこのシステムの容量を増やしたいと考えています。

私たちは(非常に基本的に)couchbase、cassandra、mongodbをこのプロジェクトの候補として評価しましたが、それぞれ独自の課題を提案しています。 couchbaseを使用すると、データの挿入中にではなく間隔でインデックス作成が行われるため、ビューは最新ではありません。cassandraのセカンダリインデックスは、通常、クラスター全体をスキャンして結果を探す必要があるため、結果を返すのにあまり効率的ではなく、mongodbは有望に見えますが、マスター/スレーブ/シャーディングされているため、スケーリングがはるかに難しいようです。評価する予定のその他の候補には、elasticsearch、mysql(これが適用できるかどうかは不明)、およびいくつかの列指向のリレーショナルデータベースがあります。任意の提案や実世界での経験をいただければ幸いです。

77
somecallmemike

私が働いている会社では、同様の量のデータ(約10 TBのリアルタイム検索可能データ)を扱っています。これをCassandraで解決します。マルチTBデータベースでO(1)検索を実行できるようにするいくつかのアイデアを挙げます。これはCassandra dbに固有ではありませんが、他のdbでも使用できます。

理論

  • データをシャーディングします。単一のサーバーがそのような量のデータを確実かつ現実的に保持する方法はありません。
  • ハードウェア障害やノード全体の障害に備えて、データを複製します。
  • 最初から多くのバックエンドサーバーの使用を開始します。
  • トップエンドの高性能サーバーと比較して、安価なコモディティサーバーを多数使用してください。
  • データがシャード全体に均等に分散されていることを確認してください。
  • クエリの計画に多くの時間を費やしてください。クエリからAPIを導出し、慎重にテーブルを設計します。これは最も重要で長期にわたる作業です。
  • Cassandraでは、複合列キーを設計し、O(1)でそのキーにアクセスできます。それらの作業に時間を費やしてください。これは、セカンダリインデックスの代わりに検索可能なレコードにアクセスするために使用されます。
  • 幅の広い行を使用してください。タイムスタンプ付きのイベントを保存するのに役立ちます。
  • そのようなボリュームでは、フルスキャンや実際にはO(Log N)を超える操作を実行しないでください。 O(Log N)以上が必要な場合は、そのような操作をMap-Reduceアルゴリズムにオフロードしてください。

練習

  • OSイメージの構築や物理マシンへのサーバーのインストールに時間を費やさないでください。クラウドベースのプロバイダーを使用してプロトタイピングを迅速に行います。私はAmazon EC2を使用しましたが、プロトタイピングのシンプルさ、信頼性、および速度のため、これを強くお勧めします。
  • Windowsマシンは、起動時に遅くなる傾向があり、アイドル状態のリソースをかなり多く使用します。 UnixベースのOSの使用を検討してください。個人的には、Ubuntuサーバーが信頼できるOSであることがわかりましたが、さらに askubunt にはかなり良いコミュニティがあります。
  • ネットワーキングについて考えてみましょう。ノードは、理想的には、高速なうわさ話とメタデータ交換を可能にするために互いに近接している必要があります。
  • 極端なケースには入れないでください。本当に幅の広い列行または非常に長い列ファミリー(テーブル)です。最高のパフォーマンスは正気な境界で達成されます-dbが設計により多くの[〜#〜] n [〜#〜]行をサポートする場合、それはサポートしませんtパフォーマンスが高いことを意味します。
  • 検索には3〜5秒かかりますが、その多くはUIとデータベースの間の中間ノードによるものです。リクエストをデータベースに近づける方法を検討してください。
  • ネットワークロードバランサーを使用します。確立されたものを選択してください。シンプルですが非常に高速なHAProxyを使用しています。それで問題がなかった。
  • 複雑なソリューションよりも単純さを優先します。
  • あなたが企業の規模の予算でバックアップされていない限り、無料のオープンソースソリューションを探してください。複数のサーバーを超えると、インフラストラクチャのコストが非常に高くなる可能性があります。

私はAmazonで働いていません。HAProxyやUbuntuのチームとは関係がありません。これは、あらゆる種類の宣伝ではなく、個人的な意見です。

59
oleksii

これをSQL Serverに入れる場合は、次のようなテーブルをお勧めします。

CREATE TABLE tcp_traffic
(
    tcp_traffic_id bigint constraint PK_tcp_traffic primary key clustered IDENTITY(1,1)
    , tcp_flags smallint    /* at most 9 bits in TCP, so use SMALLINT */
    , src_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , netxhop bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , unix_secs bigint  
    , src_mask int      /* an assumption */
    , tos tinyint       /* values are 0-255, see RFC 791 */
    , prot tinyint      /* values are 0-255, see RFC 790 */
    , input int         /* an assumption */
    , doctets int       /* an assumption */
    , engine_type int   /* an assumption */
    , exaddr bigint     /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , engine_id int     /* an assumption */
    , srcaddr bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , dst_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , unix_nsecs bigint /* an assumption */
    , sysuptime bigint  /* an assumption */
    , dst_mask int      /* an assumption */
    , dstport smallint  /* ports can be in the range of 0 - 32767 */
    , [last] bigint     /* an assumption */
    , srcport smallint  /* ports can be in the range of 0 - 32767 */
    , dpkts int         /* an assumption */
    , output int        /* an assumption */
    , dstaddr bigint    /* use a big integer for the IP address instead of storing
                            it as dotted-decimal */
    , [first] bigint    /* an assumption */
);

これにより、単一のテーブルの推定合計ストレージ要件が得られ、5.5 TB)のインデックスはなくなります(これは、指定した要件です。これは、データ自体の130バイトとして計算されます。オーバーヘッドの行あたり7バイト、オーバーヘッドのページあたり96バイトに加え、SQL Serverはデータを8KBページに保存し、ページあたり59行を許可します。これは、1か月のデータで732,203,390ページに相当します。

SQL Serverは、8ページのチャンク(64KB)でディスクに書き込むことを好みます。これは、物理I/Oあたり472行に相当します。毎秒16,203のフローレコードが生成されるため、毎秒保証される34 IOpsの最小I/Oレートが必要になります。これ自体は膨大な量ではありませんが、システム内の他のI/O(SQL Serverなど)がこの必要なIOpsの速度を決して侵害する必要はありません。したがって、少なくとも1桁以上のIOps、または340の持続IOpsが可能なシステムを設計する必要があります。スループットを保証するには、2桁のより持続可能なIOpsが必要であると私は推測する傾向があります。

IPアドレスを小数点付き10進数形式で保存していないことに気付くでしょう。これにより、ストレージ(アドレスあたり7バイト)が大幅に節約され、IPアドレスのインデックス作成、取得、並べ替え、比較がはるかに効率的になります。ここでの欠点は、ドット付き10進数のIPを格納する前に8バイト整数に変換し、表示のためにドット付き10進数のIPに戻す必要があることです。これを行うためのコードは簡単ですが、行レートを使用すると、処理中の各フロー行にかなりの処理オーバーヘッドが追加されます。SQLServerとは物理的に異なるマシンでこの変換プロセスを実行したい場合があります。

特定の要件をリストしていないため、必要なインデックスの議論は完全に別の問題です。このテーブルの設計は、SQL Serverが受信した物理的な順序でフロー行を格納します。tcp_traffic_idフィールドは各レコードに対して一意であり、記録された順序で行を並べ替えることができます(この場合、関連する可能性が最も高いです)フローイベントの時間に1対1)。

41
Max Vernon

HBase をお勧めします。クエリする必要に応じて、すべての生データを1つ以上のHBaseテーブルに保存できます。 HBaseは大きなデータセットを処理でき、領域分割を通じて自動シャーディングを実行します。

さらに、行キーを適切に設計すると、O(1)クエリでも非常に高速になります。大きなデータセットを取得する場合でも、速度が遅くなることに注意してください。データの取得はO(n)オペレーションであるためです。

各フィールドに対してクエリを実行する必要があるので、フィールドごとに一意のテーブルを作成することをお勧めします。 src_addressデータの例には、次のようなテーブルがあります。

1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }

したがって、3月27日12:00 AMから3月27日12:01 AMまでの1.2.3.4のすべてのデータをクエリする場合は、開始行と終了行を指定して範囲スキャンを実行できます。

IMHO、行キーの設計はHBaseを使用する上で最も重要な部分です。適切に設計すると、高速なクエリを実行し、大量のデータを格納できるようになります。

5
Suman

これは言った:

...このプロジェクトの独自のソリューションを検討することに反対していません

IBM Informixデータベース + TimeSeries データブレードを検討することをお勧めします。一部の人々の言うこととは反対に、Informixは健在で非常に順調に進んでいます。最後のバージョンは先月リリースされました(2013年3月、バージョン12.10)。

TimeSeriesは、あなたのような状況に対処できる「プラグイン」(無料)のようなものです。
無料のバージョンのInformixデータベース( エディションInnovator-C )を使用して、本番環境で使用できます。 (もちろん、無料版には限られたリソースがたくさんあるので、技術的な部分を評価するだけです)

ここでは、PDF 参照として使用できるものを確認できます。ここでは、より技術的な例を含む2つのプレゼンテーション: ダミーガイド および- その他のヒント

私はTimeSeriesでの個人的な経験がないので、それが「解決策」であることに同意できません。評価するための提案です。

3
ceinmart

Informix TimeSeriesを確認することをお勧めします。 IBMの文献によると、TimeSeriesはこの種の情報を1/5のスペースに格納でき、従来のリレーショナルテーブルの5倍の速度で実行できます。

追加の利点は、TimeSeriesデータを従来のリレーショナルテーブルのようにエンドユーザーに見せることができる仮想テーブルインターフェイス(アプリケーション開発を簡素化しながらTimeSeriesの利点を享受できる)、HDRノードを備えたシンプルなHA、バージョン12.1のTimeSeriesデータをサポートすること、およびTimeSeriesデータをInformix Warehouse Acceleratorに統合して、複雑なデータウェアハウスレポートを高速化し、Informixで無料のInformix DeveloperまたはInnovator-Cエディションを使用してTimeSeriesソリューションのプロトタイプを作成することができます。

2
Andrew