我正在使用网络抓取工具(请不要建议现有的,不是一个选项)。 我按照预期的方式工作。我唯一的问题是,目前我正在使用一种服务器/客户端模型,服务器在这种模式下进行爬行并处理数据,然后将其放在一个中心位置。
这个位置是我写的一个类创建的对象。在内部,类维护一个定义为HashMap<String, HashMap<String, String>>
我将数据存储在地图中,使url成为键(我保持这些唯一),并且hasmap值存储该URL的相应数据字段,如标题,值等
我偶尔会对所使用的内部对象进行序列化,但蜘蛛是多线程的,只要我说5个线程爬行内存需求就会呈指数级增长。
到目前为止,使用hashmap的性能非常出色,在2.r分钟内以大约30秒的CPU时间爬行15K url所以我真的不需要像大多数论坛用户那样指向现有蜘蛛的方向建议。
任何人都可以建议一个快速的基于光盘的解决方案,它可能支持并发阅读&amp;写作?数据结构不必相同,只需要能够将相关的元标记值存储在一起等等。
提前致谢
答案 0 :(得分:3)
我建议使用EhCache,即使你正在构建的内容并不是真正的缓存。 EhCache允许您配置缓存实例,使其溢出到磁盘存储,同时将最新的项目保留在内存中。它还可以配置为光盘持久性,即数据在关机时刷新到光盘,并在启动时读回内存。最重要的是,它是基于键值的,因此它已经适合您的模型。它支持并发访问,并且由于磁盘存储作为单独的线程进行管理,因此您不必担心磁盘访问并发。
或者,您可以考虑使用适当的嵌入式数据库,例如Hypersonic(或许多类似风格的其他数据库),但这可能会更有效。
答案 1 :(得分:1)
有Tokyo Cabinet,它是基于磁盘的哈希表的快速实现。
在您的情况下,我认为在这样的设置中存储值的最佳方法是在元数据键前加上url:
[url]_[name] => [value]
[url]_[name2] => [value2]
不幸的是,我不确定您是否可以使用此解决方案枚举给定网址的元数据。
如果你想使用更结构化的数据存储,我也会推荐MongoDB和SQLite。
答案 2 :(得分:1)
答案 3 :(得分:0)
如何在您的类中使用JPA,并将数据保存在数据库中(可以像sqlite一样基于文本) http://en.wikipedia.org/wiki/Java_Persistence_API
答案 4 :(得分:0)
Chronicle Map是一个可嵌入的,基于散列的Java数据存储,将数据保存到磁盘(到单个文件),其目标是替换ConcurrentHashMap
(提供相同的) ConcurrentMap
接口)。 Chronicle Map是the fastest store among similar solutions,具有出色的读/写并发性,几乎可以线性扩展到机器中可用内核的数量。
免责声明:我是Chronicle Map的开发者。