如何解决Lucene Indexing在大约100万个文件nrm文件越来越大…之后卡住了
| 有人知道为什么会这样吗?我正在对XML文件进行基本索引+ SAX解析,并将每个路径添加为文档中的新字段。我必须喜欢150万个文件,并将其卡在该文件上30分钟,然后.nrm(规范化文件?)变得越来越大。 我不知道为什么会这样,我的IndexWriter的格式为:writer = new IndexWriter(dir,new StandardAnalyzer(Version.LUCENE_30),IndexWriter.MaxFieldLength.UNLIMITED)
这不是用于大型索引的最佳选择吗?为什么将其冻结在此一个文件上?我已经使用超过100万个XML文件对其进行了多次运行,并且不断地卡在不同的XML文件中(不仅是这个文件-结构还不错)。
编辑:
因此,假设我一次使用单独的Java命令为文件2000编制索引。索引完成后,我调用了indexwriter close方法,如果要重写到该索引,是否会丢失任何内容?我应该优化索引吗?我想我记得《 Lucene in Action》曾说过要优化,如果您有一段时间不会写它。
实际上,此方法可处理180万个文件,但是在我尝试分批添加2000个文件后,此NRM文件和另一个文件写入了约70GB!如果仅以2000个批次调用java Lucene索引函数,为什么内存会从JVM用尽?除非您在关闭索引编写器之前需要向Lucene代码中添加一些内容,否则这似乎不是垃圾拼凑的问题。
编辑2:
我大约有400万个XML文件,如下所示:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<person>
<name>Candice Archie
</name>
<filmography>
<direct>
<movie>
<title>Lucid (2006) (V)
</title>
<year>2006
</year>
</movie>
</direct>
<write>
<movie>
<title>Lucid (2006) (V)
</title>
<year>2006
</year>
</movie>
</write>
<edit>
<movie>
<title>Lucid (2006) (V)
</title>
<year>2006
</year>
</movie>
</edit>
<produce>
<movie>
<title>Lucid (2006) (V)
</title>
<year>2006
</year>
</movie>
</produce>
</filmography>
</person>
我解析这些XML文件并将内容添加到路径的字段中,例如/ person / produce / filmography / movie / title,Lucid(2006)(V)
问题是,我正在寻找针对索引中的每个文档(然后是所有文档中该值的总和)的文档的字段实例中给定术语的频率统计信息...因此,如果有两个实例/ person / produce / filmography / movie / title,它们都包含“ Lucid”,我想要两个。如果存在其他路径(例如:/ person / name:Lucid),Lucene给出的tf(t in d)将给出3,但是对于文档中相似字段内的术语则不这样做。
Lucene Indexing的核心是这样做的:
public void endElement( String namespaceURI,String localName,String qName ) throws SAXException {
if(this.ignoreTags.contains(localName)){
ignoredArea = false;
return;
}
String newContent = content.toString().trim();
if(!empty.equals(newContent) && newContent.length()>1)
{
StringBuffer stb = new StringBuffer();
for(int i=0; i<currpathname.size();i++){
//System.out.println(i + \"th iteration of loop. value:\" + currpathname.get(i).toString() + k + \"th call.\");
stb.append(\"/\");
stb.append(currpathname.get(i));
}
//stb.append(\"0\");
if(big.get(stb.toString())==null){
big.put(stb.toString(),1);
}
else{
big.put(stb.toString(),big.get(stb.toString())+1);
}
if(map.get(stb.toString())==null){
map.put(stb.toString(),0);
stb.append(map.get(stb.toString())); //ADDED THIS FOR ZERO
}
else
{
map.put(stb.toString(),map.get(stb.toString())+1);
stb.append(map.get(stb.toString()));
}
doc.add(new Field(stb.toString(),newContent,Field.Store.YES,Field.Index.ANALYZED));
seenPaths.add(stb);
//System.out.println(stb.toString());// This will print all fields indexed for each document (separating nonunique [e.x.: /person/name0 /person/name1]
//System.out.println(newContent);
}
currpathname.pop();
content.delete(0,content.length()); //clear content
//This method adds to the Lucene index the field of the unfolded Stack variable currpathname and the value in content (whitespace trimmed).
}
Map和BigMap是哈希图(不必担心bigmap,它用于其他用途。每当实例化一个新的XML文件(Document对象)时,map就会实例化。有一个endDocument()方法可在添加后所有的startElement,endElement和character方法都被调用(这些是Xerces Parser方法)
public void endDocument( ) throws SAXException {
try {
numIndexed++;
writer.addDocument(doc);
} catch (CorruptIndexException e) {
e.printstacktrace();
} catch (IOException e) {
e.printstacktrace();
}
}
抱歉,很长的帖子-感谢您的帮助!
另外,我不认为服务器是问题所在。我一次在400万个文件上运行该代码,即使我使用Xmx12000M xms12000M,它也耗尽了堆内存
这是一台功能强大的服务器,因此它绝对可以处理此问题...
编辑3:
再一次问好!谢谢,你是对的。 Lucene可能不是这样做的。实际上,我们将进行其他实验,但是我认为我已经在您的想法和其他想法的帮助下解决了该问题。首先,我停止对字段进行规范化,这使索引的大小缩小了很多倍。另外,我使用了mergedocs和rambuffer方法并对其进行了升级。索引大大改善。我会在您的帮助下标记问题的答案:)谢谢。
解决方法
尝试分批编制索引。下面的代码应为您提供一个方法。我也建议您查看《 Lucene in Action》的最新版本。
最有可能是您使垃圾收集器超载(假设没有很难发现的内存泄漏),这最终将导致您的内存不足错误。
private static final int FETCH_SIZE = 100;
private static final int BATCH_SIZE = 1000;
//Scrollable results will avoid loading too many objects in memory
ScrollableResults scroll = query.scroll(ScrollMode.FORWARD_ONLY);
int batch = 0;
scroll.beforeFirst();
while (scroll.next()) {
batch++;
index(scroll.get(0)); //index each element
if (batch % BATCH_SIZE == 0) {
//flushToIndexes(); //apply changes to indexes
//optimize();
//clear(); //free memory since the queue is processed
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。