java – 如何分析〜13GB的数据?

我有〜300个文本文件,包含跟踪器,种子和对等体的数据。每个文件的组织方式如下:

tracker.txt

time torrent
    time peer
    time peer
    ...
time torrent
...

我每个跟踪器都有几个文件,大部分信息被重复(相同的信息,不同的时间)。

我想分析一下我有什么,并报告统计数据

>每个追踪器有多少种子
>上传了多少个跟踪器
>多少个同伴做了种子
>同龄人有多少个洪流

数据量很大,这让我很难。这是我试过的

MySQL的

我将所有内容都放入数据库中每个实体类型一个表和用于保存关系的表(例如,此torrent在此跟踪器上)。

将信息添加到数据库是缓慢的(当我尝试这个时我没有13GB的),但分析后的关系是一个没有进行。每个温和复杂的查询都花了24小时才能完成(如果有的话)。

示例查询将是:

SELECT COUNT(DISTINCT torrent) 
    FROM TorrentAtPeer, Peer 
    WHERE TorrentAtPeer.peer = Peer.id 
    GROUP BY Peer.ip;

我尝试碰到我的my.cnf文件中的内存分配,但似乎没有帮助。我使用了我的innodb-heavy-4G.cnf设置文件。

编辑:添加表的详细信息

这是我正在使用的:

Peer         Torrent                  Tracker        
-----------  -----------------------  ------------------  
id (bigint)  id (bigint)              id (bigint)
ip* (int)    infohash* (varchar(40))  url (varchar(255))
port (int)

TorrentAtPeer      TorrentAtTracker
-----------------  ----------------
id (bigint)        id (bigint)
torrent* (bigint)  torrent* (bigint)
peer* (bigint)     tracker* (bigint)
time (int)         time (int)

*indexed field. Navicat reports them as being of normal type and Btree method.
id - Always the primary key

没有外键。我有信心只能使用与现有实体相对应的ID,添加外键检查似乎是不必要的延迟。这是天真吗?

MATLAB

这似乎是一个应用程序,是为一些重的提升而设计的,但是我无法分配足够的内存来一次性保存所有的数据。

我没有数值数据,所以我正在使用单元格阵列,我从这些转移到尝试以减少占用空间。我不能让它上班

Java的

我迄今为止最成功的尝试。我发现Limewire人民提供的Patricia Tries的实现。使用这个我可以读取数据,并计数我有多少独特的实体:

> 13个跟踪器
> 1.7mil的洪流
> 32mil同行

我仍然觉得很难计算出同龄人数量的频率。我试图通过建立这样的尝试:

Trie<String, Trie<String, Object>> peers = new Trie<String, Trie<String, Object>>(...);
for (String line : file) {
    if (containsTorrent(line)) {
        infohash = getInfohash(line);
    }
    else if (containsPeer(line)) {
        Trie<String, Object> torrents = peers.get(getPeer(line));
        torrents.put(infohash, null);
    }
}

从目前为止,我可以做到这一点,如果我可以得到这个同行的trie,那么我可以很容易地找出每个对等体有多少种子。我昨天跑了,当我回来时,我注意到日志文件没有被写入,我^ Z的应用程序和时间报告如下:

real 565m41.479s
user 0m0.001s
sys  0m0.019s

这对我来说看起来不正确,用户和系统应该如此之低?我应该提到,我还将JVM的堆大小增加到了7GB(最大和最大),没有这个我很快得到内存不足的错误。

我不介意等待几个小时/天,但看起来像大概10个小时之后,事情就停止了。

我想我的问题是,我该如何分析这些数据?我尝试过的东西是正确的吗?有没有我失踪的东西?到目前为止,Java解决方案似乎是最好的,有什么可以做的,让它工作吗?

我会给MySQL另一个尝试,但是使用不同的模式:

>不要在这里使用id列
>在这里使用自然主键:

对等:ip,port
洪流:infohash
追踪器:网址
TorrentPeer:peer_ip,torrent_infohash,peer_port,time
TorrentTracker:tracker_url,torrent_infohash,time
>对所有表使用innoDB引擎

这有几个优点:

> InnoDB使用主键的聚簇索引。意味着当您只从主键列请求数据时,可以直接从索引检索所有数据,无需额外的查找。所以InnoDB表是一些索引组织的表。
>较小的尺寸,因为您不必存储替代键。 – >速度,因为较少的IO相同的结果。
>您可能无需使用(昂贵)连接即可进行某些查询,因为您使用自然主键和外键。例如,链接表TorrentAtPeer直接包含对等体ip作为对等体表的外键。如果您需要查询子网络中的对等体使用的种子,则可以在不使用连接的情况下执行此操作,因为所有相关数据都在链接表中。

如果你想要每个对等人的洪流计数,并且你希望对等体的ip在结果中,那么我们在这里使用自然的主键/外键再次有一个优势。

使用您的架构,您必须加入以检索ip:

SELECT Peer.ip, COUNT(DISTINCT torrent) 
    FROM TorrentAtPeer, Peer 
    WHERE TorrentAtPeer.peer = Peer.id 
    GROUP BY Peer.ip;

具有自然主键/外键:

SELECT peer_ip, COUNT(DISTINCT torrent) 
    FROM TorrentAtPeer 
    GROUP BY peer_ip;

编辑
那么原来的发布模式不是真正的模式。现在对等表有一个端口字段。我建议在这里使用主键(ip,port),然后删除id列。这也意味着链接表需要具有多列外键。调整答案…

http://stackoverflow.com/questions/11449965/how-can-i-analyse-13gb-of-data

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – 如何分析〜13GB的数据?