专家
我有以下代码在我的抓取工具上添加访问过的链接。 提取链接后,我有一个 for循环,循环遍历每个 href标记。
在我访问了一个链接后,打开它,我会将URL添加到上面定义的访问链接集合变量中。
private final Collection<String> urlForntier = Collections.synchronizedSet(new HashSet<String>());
抓取器实现是mulithread并假设我已经访问了100,000个URL,如果我没有终止爬虫,它将逐日增长。它会产生内存问题吗?请问,我有什么选择刷新变量而不会在线程间产生不一致?
提前致谢!
答案 0 :(得分:1)
现代抓取系统最常用的方法是使用NoSQL数据库。
此解决方案明显慢于HashSet
。这就是为什么你可以利用不同的缓存策略,如Redis,甚至是Bloom filter s
但是包含网址的特定性质,我想推荐Trie数据结构,它为您提供了很多操作和按url字符串搜索的选项。 (关于java实现的讨论可以在这个Stackoevrflow topic)
上找到答案 1 :(得分:0)
根据问题,我建议使用Redis来替换Collection的使用。它是数据结构存储的内存数据库,并且支持所有标准数据结构,可以超快速地插入和检索数据。在您的情况Set中,您可以使用SISMEMBER命令检查集合中是否存在密钥
Apache Nutch也很适合探索。