2010-07-23 102 views
4

我正在研究一个网络爬虫(请不要建议现有的,它不是一个选项)。 我的工作方式是预期的。我唯一的问题是,目前我正在使用一种服务器/客户端模式,服务器执行爬取并处理数据,然后将其放置在中央位置。基于java光盘的哈希映射

此位置是从我写的类创建的对象。在内部,类维护定义一个HashMap为HashMap<String, HashMap<String, String>>

我存储的数据在地图制作的URL键(我把这些独特的)和hasmap价值储存该URL对应的数据字段,如标题,价值等

我偶尔会序列化使用的内部对象,但蜘蛛是多线程的,只要我说5个线程爬取内存需求呈指数级增长。

到目前为止,散列表的表现非常出色,在2.r分钟内抓取15K urls,大约30秒CPU时间,所以我真的不需要像大多数论坛那样指向现有蜘蛛的方向用户建议。

任何人都可以提出一个基于快盘解决方案,可能会支持并发读取&写?数据结构不必须是相同的,只是需要能够提前

感谢

+0

为什么会呈指数形式? – 2010-07-23 09:30:42

+0

因为我对它进行了彻底测试,并且只在线程爬行量增加时记录了内存使用情况和CPU时间。有一些奇怪的测试在外面,并没有真正符合其他测试显示的相关性,但他们只是被视为极端值,并忽略了当我绘制,可能不是一些专业测试,但它足够我的目的。 – zcourts 2010-07-24 13:32:47

回答

3

我建议使用EhCache对于这一点,即使你正在构建的ISN存储器相关的元标记值等一起真的不是缓存。 EhCache允许您配置缓存实例,使其溢出到光盘存储,同时将最新的项目保存在内存中。它也可以配置为光盘持久化,即在关机时将数据刷新到光盘上,并在启动时读回到内存。最重要的是,它基于键值,所以它已经适合您的模型。它支持并发访问,并且由于磁盘存储是作为单独的线程进行管理的,因此您不必担心磁盘访问并发性。

或者,你可以考虑适当的嵌入式数据库,如Hypersonic(或类似风格的无数人),但是这可能会是更多的工作。

+0

即时通讯调查,ehcache我的意思。让我想起Oracle Berkeley DB的一种方式... – zcourts 2010-07-24 13:48:22

+0

我去了一个嵌入式数据库,使用hsqldb 感谢大家的建议,非常感谢 – zcourts 2010-07-24 18:19:31

+1

以供将来参考寻找类似这样的东西的人。我实现了hsqldb和hypersonic,但都导致严重高CPU使用率。测试一个sqlite的实现,从http://www.zentus.com/sqlitejdbc/到目前为止有更好的结果 – zcourts 2010-07-25 11:31:33

0

有关数据库在你的类使用JPA,并持续数据 http://en.wikipedia.org/wiki/Java_Persistence_API

+1

我已经序列化了,但是无论如何,这些对象都会重新加载到堆上,而它们的原始大小却击败了整个点 – zcourts 2010-07-24 13:50:04

+0

否JPA不是关于序列化,而是关于将对象持久化到数据库。你的对象被持久化到数据库并且不被加载回来(好的java对象不被破坏,当它们被解引用时它们被垃圾收集) – fixitagain 2010-10-02 08:41:57

1

Tokyo Cabinet(等基于SQLite的,可以是文字),这是一种快速实现基于磁盘的哈希表的内容。

在你的情况,我认为存储在这样的设置值的最佳方法是用前缀的URL的元数据键:

[url]_[name] => [value] 
[url]_[name2] => [value2] 

不幸的是,我不知道,你可以枚举元对于给定的URL,使用此解决方案。

如果你想使用更多结构化的数据存储,还有MongoDB和SQLite,我会推荐它。

+0

和上面一样我正在研究东京内阁谢谢你的建议,我会得到bk在我看到它发生之后给大家 – zcourts 2010-07-24 13:52:28

1

JDBM2库提供持续的地图为Java。它的快速和线程安全。

UPDATE: 演变成MapDB项目

0

Chronicle Map是一个嵌入式,基于散列的Java数据存储,数据到磁盘持续(单个文件),它的目标是一个简易替换ConcurrentHashMap(提供相同的ConcurrentMap接口)。 Chronicle Map是the fastest store among similar solutions,具有出色的读/写并发性,几乎线性地缩放到机器中可用内核的数量。

声明:我是Chronicle Map的开发者。