300万件のレコードをキー値形式で格納する方法


10

300万点の商品の基本情報を保管しています。現在の情報は、四半期ごとに更新される1つの180 mb CSVです。

1日に約30,000のクエリがありますが、クエリは非常に単純なキー値ストアです。製品IDを検索して、残りの情報(すべて1つのレコードに含まれる)を表示するだけです。

これはウェブ用なので、高速なパフォーマンスが重要です。

リレーショナルデータベースが本当に必要ない場合でも、MySQLを使用する必要がありますか?四半期ごとに300万の静的htmlファイルを生成するだけでよいのでしょうか。各製品の1行のCSVをAmazon S3やRackspace Cloud Filesなどに保存する必要がありますか?これを行う最良の方法は何ですか?

回答:


16

MySQLは非常に広くサポートされており、これは本当に簡単なことなので、私はそれを使用することをお勧めします。サーバーに少なくとも数GBのメモリがない限り、インメモリシステムを使用するのではなく、MySQLを使用することをお勧めします。

MySQLであるかどうかに関係なく、データをデータベースに格納し始めると、データの用途が増えることに気付くでしょう。現時点ではキーと値のペアについてのみ説明していますが、製品に関連する残りのデータはどこかに保存する必要があります。それがデータベースにない場合、データストレージが非常に効率的であるとは思えません。

何をする場合でも、300万個のファイルを作成しないください。多くのファイルが作成する問題からすでにここにいくつかの質問が出てきました。


13

この種のタスク用に最適化された専用のKey-ValueタイプのNoSQLデータベースを使用できます。見て:

  • Redis -Redisはオープンソースの高度なKey-Valueストアです。キーには文字列、ハッシュ、リスト、セット、ソート済みセットを含めることができるため、データ構造サーバーと呼ばれることがよくあります。
  • MemcacheDB -MemcacheDBは、永続化のために設計された分散キー値ストレージシステムです。
  • その他(そのようなリストの1つはここにあります:http : //nosql-database.org/

もちろん、あなたは、MySQLやその他のリレーショナルデータベースを使用することができるが、解決策特別に優れていることが想定されるデータのキーと値のタイプのために設計されたが(最初の場所でそれらを設計のポイントがあるそうでないものを除き、おそらくそれははるかに小さいだろうという事実を(RAMとHDDに関して)ソリューション)。


Redisを使用することもできますが、これは2 GBのRAMを搭載したP4で機能すると思いますか?
Phil

@Phil CSVファイルが約180MBであることを考慮すると、問題ありません。約20万件のレコードがあるプロジェクト(これまでに1回だけ)で使用しましたが、サーバーには8 GBのRAMがあったため、比較するのは困難です。
LazyOne 2011

6

そして今、完全に異なる何かのために:

与えられた:

  • 180MB / 3M製品=平均62バイト/製品。
  • 1日あたり30,000クエリ= 1秒あたり0.34クエリ
  • 四半期ごとに更新=本質的に静的なデータ

箱から出して解決策:

各製品をTXTリソースレコードとしてダンプし、DNSに保存します。例:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

利点:

  • 非常に信頼性が高く、信頼されている(あなたはすでに毎日それに依存しています)
  • ほぼすべてのプラットフォームで構築可能
  • ほとんどすべての言語が何らかの形でDNSクエリをサポートしています
  • オープンソースおよび商用サーバーは、さまざまな種類のバックエンドデータベースをサポートします
  • 簡単に複製できる(複数のネームサーバーを指定するだけ)
  • 12のサーバー間で複製された場合でも、アトミック更新を処理します
  • データの整合性を確保するために暗号で署名できます
  • 1秒あたりの桁数が高いクエリレートを処理できます(1 あたり10,000クエリは、市販のハードウェアで簡単に処理できます)

これが悪い考えかもしれない理由:

  • データを検索する必要があります(DNSは純粋にキー/値のルックアップです)
  • データを非表示にする必要があります(DNSには機密性はありません)

1
独創性のためにボーナスポイントを与えることができれば、これは私の投票を獲得します。典型的なホームネットワークでは、DNSが機能するかどうかは魔法のようであり、機能しない場合は呪いのようです。
Martin Vilcans、2011

1
興味をそそられる。私は実際にこのアイデアが本当に好きですが、私にとっては、CouchDBのようなもう少し試された/テストされたものを使います
Tom O'Connor

いくつかのモンティパイソンを見ていますか?
マークヘンダーソン、

おそらくこれは企業ネットワーク内にあるでしょう。パケットがインターネットの荒野に立ち向かう必要がある場合、DNSの信頼性が問題になります。DNSはデフォルトでUDPを使用するため、パケットがドロップされた場合はDNSリゾルバーの再送信ポリシーに依存する必要があります。エンタープライズネットワーク内では、かなりのパケット損失が発生する可能性は(おそらく)無視できます。また、DNSにTCPを使用するように強制することもできます(ただし、パフォーマンスに影響がある場合は、この場合は重要ではないと考えられます)。DNSは、すべてのCouchDBインストールを組み合わせた場合よりも多くのルックアップを取得します:-)。
Theobroma Cacao

ここでHindsight船長。一言:ブロックチェーン。
datashaman

4

MyISAMといくつかの優れたインデックスを備えたMySQLは、これにぴったりです。もちろん、他にもたくさんのオプションがありますが、MySQLは(普遍的ではないとしても)非常に広く、あらゆる商用Webホストでサポートされています。必要な速度によっては、memcachedも一見の価値があるかもしれませんが、各キー/値ペアのサイズがわからない場合、それらの300万をメモリに保存することは、180Mb CSVファイルよりもさらに悪い考えかもしれません(まあ、それは180MbのCSVファイルなので、その大きさがわかります。それらはかなり小さいペアでなければならないため、memcachedの方が優れている可能性があります)。

あなたはないではない、それはひどくあなたのファイルシステムを傷つけるだろう、300万静的なHTMLファイルをしたいです。S3でも、1行のCSVで同じ問題が発生します。フォルダーに300万個のファイルが必要な人は誰もいません。


それらはかなり小さなペアです...価格、製造日、倉庫番号などの非常に基本的なデータです。10列未満です。MySQLが実際に行くべき道だと思いますか?それが実行されるサーバーは、2 GBのRAMを搭載したP4です。
Phil

@Phil-- So you think MySQL is the way to go, really?いいえ、実際にはそうではありませんが、非常に柔軟性があり、前述したように、ほぼ普遍的にサポートされています。ただし、LazyOneは上記の良い代替案をいくつか投稿しています。私はNoSQLという言葉を思い出せませんでしたが、脳のどこかに浮かんでいました
マークヘンダーソン

4

Perl5の誕生以来流行っていなかったとしても、まさにこの種のことを行うBerkeley Databaseを使用することができます。Berkeleyはキーと値のペアのみをサポートし、db全体をハッシュに結び付けて、それにアクセスします。

Berkeleyの使用については、シェルフにある古いPerlリファレンスの多くで詳しく説明されています。または、BerkeleyDB CPAN ModuleのPerldocを試しください。私は一般にBerkeley DBの使用を避けます(私の雇用者はそれが目立つように機能する非常に古いコードを持っていますが、一部のDBはあなたと同じくらい大きいです)。なぜなら、データがより複雑になると面白くないからです。


2
BDBは古い方法ですが、この状況に非常に効果的で適切です。
ウォンブル

Berkely DB en.wikipedia.org/wiki/Sleepycat_licenseのライセンスに注意してください。DB部分だけでなく、すべてのソースコードを利用可能にする必要があります。
WolfmanJM 2011

4

質問にAmazon S3のフラグを付けました。

Amazon SimpleDBと呼ばれる他の関連製品の1つに注意を向けたいと思います。
SimpleDBデータモデルは、ご使用のアプリケーションのタイプに適しているようです。

これはプラグインではありませんが、Amazonクラウドサービスの使用を計画している場合は特に検討する価値があります。

SDBデータモデルはスプレッドシートに似ています。

詳細については、こちらをご覧ください:http : //aws.amazon.com/simpledb/ そして、データモデル:http : //docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/


SimpleDBは高価です。痛いほど、多くの場合。
トムO'Connor

1

180 MBのデータはどのリレーショナルデータベースでも簡単に処理できますが、MongoDB(http://www.mongodb.org/)MySQL、Redis、MemcacheDB、およびその他のより単純なKey-Valueストアまたはリレーショナルデータベースの上。その理由は、この種の問題では、MongoDBが最も高速で表現力のあるシステムであり、スキーマの制限なしで超高速の動的更新が可能であるため、必要に応じてドキュメントの形式が異なる可能性があるためです。私は先日、guardian.co.ukからのプレゼンテーションに参加していましたが、すべてのリレーショナルデータベースを禁止し、MongoDBを排他的に使用してニュースを提供するという方針決定を下しました。あなたは彼らのウェブサイトがどれほど速く、1995年以来オンラインになっているのか(英国で最も古いオンライン新聞)の感触を得ることができます。また、リレーショナルデータベースが原因で、過去にあらゆる種類のボトルネックが発生しています。180mbの場合、MongoDBはメモリ内のすべてを提供するため、サブmsの読み込み時間がかかる可能性があります。


0

1日に約30,000のクエリがありますが、クエリは非常に単純なキー値ストアです。製品IDを検索して、残りの情報(すべて1つのレコードに含まれる)を表示するだけです。

クエリは単純なキールックアップであり、バイナリ検索では最悪の場合21回の反復が必要であり、ハッシュキーを使用するとクエリがさらに高速になると述べました。結合(または他のデカルト積タイプの演算)と線形検索を回避する限り、300万レコードは小さいです。

だいたい何でもうまくいくと思います。負荷が30000クエリ/日であることは、(負荷が1日を通して一定であると仮定すると)20秒ごとに1つのクエリがあることを意味します。それは悪くないです。

まず、最もよく知っているテクノロジに実装してから、これが本当にシステムのボトルネックかどうかを測定することをお勧めします。


0

これを行う最良の方法は、実際にはデータとクエリの品質と性質に依存します。まず、製品の単一のテーブルにある180MBのデータは、どのように見ても問題ありません。また、1日あたり3万回のクエリでも問題は少なくなります。データベースが適切に構成されていれば、古いデスクトップはこの負荷を処理できます。

MySQLまたはnoSQLデータベースという2つの主要なオプションをすでに指摘している人もいます。

すべての単一の製品に存在する特定の数の属性(製造元、価格、倉庫番号など)がある場合、これらの属性の列を用意し、キーと値のペアをフラットテーブル形式に変換することをお勧めします。そのテーブルの主キーとして製品IDを使用します。一部の列が行の半分でのみ使用されている場合でも、これは非常にうまく機能します。ほとんどの製品では、1つのクエリを実行するだけですべての属性を取得する必要があるためです。これは製品に関するデータですが、これはあなたのデータの構造である可能性が非常に高いと思います。

属性の存在とデータ型が大きく異なる場合は、このシナリオを従来のSQLデータベースよりも効率的に処理するnoSQLデータベースを使用することをお勧めします。

パフォーマンスについて:私は以前、eコマース企業で働いていました。長い間、WebサイトにはMySQLサーバーからのデータが提供されていました。このサーバーには2GBのRAMがあり、データベースの合計は約でした。サイズが5GBで負荷が高い状態で、サーバーは1秒あたり数千のクエリを処理しました。はい、多くのクエリ最適化を行いましたが、これは間違いなく実行可能です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.