8

私は今、いくつかのデータ分析テストを行っていますが、最初は非常に単純で、非常に奇妙な結果が得られました。

アイデアは次のとおりです。インターネットアクセスログ(アクセスごとのドキュメントを含むコレクション、9千万のドキュメントのテスト用)から。ドメインごとのアクセス数(MySQLではGROUP BYになります)を取得し、最もアクセスされた10個のドメインを取得したい

私がJavaScriptで作成したスクリプトは本当に単純です:

/* Counts each domain url */
m = function () {
    emit(this.domain, 1 );
}

r = function (key, values)    {
    total = 0;
    for (var i in values)    {
        total += Number(i);
    }

    return total;
}

/* Store of visits per domain statistics on NonFTP_Access_log_domain_visits collection */
res = db.NonFTP_Access_log.mapReduce(m, r, { out: { replace : "NonFTP_Access_log_domain_visits" } } );
db.NonFTP_Access_log_domain_visits.ensureIndex({ "value": 1});
db.NonFTP_Access_log_domain_visits.find({}).sort({ "value":-1 }).limit(10).forEach(printjson);

MySQLでの同等のものは次のとおりです。

drop table if exists NonFTP_Access_log_domain_visits;
create table NonFTP_Access_log_domain_visits (
    `domain` varchar(255) NOT NULL,
    `value` int unsigned not null,
    PRIMARY KEY  (`domain`),
    KEY `value_index` (`value`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8
    select domain, count(*) as value from NonFTP_Access_log group by domain;
select * from NonFTP_Access_log_domain_visits order by value desc limit 10;

そうですね、MongoDBは結果を取得するのに30時間かかり、MySQLは20分かかります!少し読んだ後、MongoDBは非常に遅いため、データ分析にはHadoopを使用する必要があるという結論に達しました。このような質問への回答は次のように述べています。

  • MongoDBはスレッドのみを使用します
  • Javascriptが遅すぎる

私は何が間違っているのですか?この結果は正常ですか?Hadoopを使用する必要がありますか?

このテストは、次の環境で行っています。

  • オペレーティングシステム:Suse Linux Enterprise Server 10(Xen上の仮想サーバー)
  • RAM:10 Gb
  • コア:32(AMD Opteronプロセッサ6128)
4

3 に答える 3

12

私は実際に以前にこの非常によく似た質問に答えました。MongoDB での Map Reduce の制限は以前に概説されています。おっしゃったように、それはシングル スレッドであり、Java Script (spidermonkey) に変換して元に戻す必要があります。

そのため、他のオプションがあります。

  1. MongoDB Hadoop コネクタ(公式にサポート)
  2. 集約フレームワーク( 2.1 以降が必要)

これを書いている時点では、2.2.0 の安定版リリースはまだ出ていませんが、RC2 までだったので、リリースは差し迫っているはずです。このタイプのテストのより有意義な比較として、試してみることをお勧めします。

于 2012-08-27T10:04:44.370 に答える
5

どうやらAggregation Frameworkでグループ機能を使用するとうまくいくようです! :-)

次の Javascript コードは、 17 分 17 秒で最も訪問された 10 のドメインを取得します。

db.NonFTP_Access_log.aggregate(
    { $group: {
        _id: "$domain",
        visits: { $sum: 1 }
        }},
    { $sort: { visits: -1 } },
    { $limit: 10 }
    ).result.forEach(printjson);

とにかく、MapReduce の代替案が非常に遅い理由はまだわかりません。MongoDB JIRA で次の質問を開きました。

于 2012-08-28T08:50:34.840 に答える
0

結果はごく普通だと思います。それらを正当化しようとします<.br>1.MySQLは、MongoDBがJSONを処理している間、処理用に最適化されたバイナリ形式を使用しています。そのため、解析の時間が処理に追加されます。私はそれを少なくとも10倍に見積もるでしょう。
2.JSは確かにCよりもはるかに遅いです。少なくとも10倍は想定できると思います。一緒に私たちは約x100を手に入れます-あなたが見るものと同様です。20分×1000は2000分または約33時間です。
3. Hadoopはデータ処理にも効率的ではありませんが、お持ちのすべてのコアを使用することができ、違いが生じます。Javaはまた、10年以上にわたってJITを開発し、最適化してきました。
4. MySQLではなく、純粋な集計であるTPC-HベンチマークQ1-を検討することをお勧めします。VectorWiseのようなシステムは、コアごとに可能な最大のスループットを示すと思います。

于 2012-08-27T19:55:08.307 に答える