你是不是也发现了在 useCompoundFile = false 情况下,还不要脸的出现了 .cfs、.cfe 呢?然后,你觉得十分莫名,为什么出现这种情况。进而思考如何让Solr听你的话,不再出现 .cfs、.cfe 是吗?如果有一个是,那请一定要看看本博文,看之后你一定会有结论的。
首先找到出现原由,从而从中得知解决方案。这是本文总体的框架。
偶然的机会,在Solr的索引目录看到一堆 .cfs/cfe 文件,而且有些文件还比较大。因为你郁闷了,这影响可大可小。如果IO负载很高,那么这无疑是雪上加霜了,造成N多点伤害。
出现这个的好坏,我们就先不讨论吧。先看一下,他的来源,source:merge。再看一眼,发现所有的cfs都由Merge造成的。好啦,好啦,这个可好了啦。原来是Merge造成的,那就定位到IndexWriter#forceMerge() 和 MergePolicy 了。看一眼 IndexWriter 好乱,好复杂。再看一下 MergePolicy,嗯哼,useCompoundFile() 这么直接和干脆?没错!就是这么直接和干脆的。
条件:
/**
* Default ratio for compound file system usage. Set to <tt>1.0</tt>, always use
* compound file system.
*/
protected static final double DEFAULT_NO_CFS_RATIO = 1.0;
/**
* Default max segment size in order to use compound file system. Set to {@link Long#MAX_VALUE}.
*/
protected static final long DEFAULT_MAX_CFS_SEGMENT_SIZE = Long.MAX_VALUE;
/** If the size of the merge segment exceeds this ratio of
* the total index size then it will remain in
* non-compound format */
protected double noCFSRatio = DEFAULT_NO_CFS_RATIO;
/**
* Returns true if a new segment (regardless of its origin) should use the
* compound file format. The default implementation returns <code>true</code>
* iff the size of the given mergedInfo is less or equal to
* {@link #getMaxCFSSegmentSizeMB()} and the size is less or equal to the
* TotalIndexSize * {@link #getNoCFSRatio()} otherwise <code>false</code>.
*/
public boolean useCompoundFile(SegmentInfos infos, SegmentCommitInfo mergedInfo, IndexWriter writer) throws IOException {
if (getNoCFSRatio() == 0.0) {
return false;
}
long mergedInfoSize = size(mergedInfo, writer);
if (mergedInfoSize > maxCFSSegmentSize) {
return false;
}
if (getNoCFSRatio() >= 1.0) {
return true;
}
long totalSize = 0;
for (SegmentCommitInfo info : infos) {
totalSize += size(info, writer);
}
return mergedInfoSize <= getNoCFSRatio() * totalSize;
}
条件1. CompoundFile使用率,默认10% (注:MergePolicy=100%, TieredMergePolicy=10%)
条件2. 提交的合并索引小于Integer.MAX_VALUE
当两个条件同时成立,则使用CompoundFile。
好啦好啦,原因有了。
不想要 compoundFile 直接改配置就好了。我猜你们都是用默认的 MergePolicy 即是 TieredMergePolicy 原因是 Mike 说它效率最高,长得最帅,所以它是默认的 MergePolicy。(纯扯蛋,不过默认的MergePolicy真的是TieredMergePolicy),不管是不是TieredMergePolicy,只要不是自己实现的话,那么应该就能这种方式解决。
把默认 CFSRactio 使用率改 0% 完美解决。
<useCompoundFile>false</useCompoundFile>
<!-- Merging Index Segments -->
<mergePolicy class="org.apache.lucene.index.TieredMergePolicy">
<float name="noCFSRatio">0.0</float>
</mergePolicy>