-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make HybridDirectory MMAP Extensions Configurable #3837
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,6 +148,18 @@ public final class IndexModule { | |
Property.NodeScope | ||
); | ||
|
||
/** Which lucene file extensions to load with the mmap directory when using hybridfs store. | ||
* This is an expert setting. | ||
* @see <a href="https://lucene.apache.org/core/9_2_0/core/org/apache/lucene/codecs/lucene92/package-summary.html#file-names">Lucene File Extensions</a>. | ||
*/ | ||
public static final Setting<List<String>> INDEX_STORE_HYBRID_MMAP_EXTENSIONS = Setting.listSetting( | ||
"index.store.hybrid.mmap.extensions", | ||
List.of("nvd", "dvd", "tim", "tip", "dim", "kdd", "kdi", "cfs", "doc"), | ||
Function.identity(), | ||
Property.IndexScope, | ||
Property.NodeScope | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we also want to set this as a final setting ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nknize I don't think so, I would want to be able to change this by closing index, updating setting, then reopening. I thought final would prevent that scenario, but I could be wrong since I am not super familiar with that setting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would prevent that scenario. +1 to go w/o final. |
||
); | ||
|
||
public static final String SIMILARITY_SETTINGS_PREFIX = "index.similarity"; | ||
|
||
// whether to use the query cache | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,9 +97,10 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index | |
case HYBRIDFS: | ||
// Use Lucene defaults | ||
final FSDirectory primaryDirectory = FSDirectory.open(location, lockFactory); | ||
final Set<String> mmapExtensions = new HashSet<>(indexSettings.getValue(IndexModule.INDEX_STORE_HYBRID_MMAP_EXTENSIONS)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mattweber I am trying to wrap my head around these two properties There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @reta |
||
if (primaryDirectory instanceof MMapDirectory) { | ||
MMapDirectory mMapDirectory = (MMapDirectory) primaryDirectory; | ||
return new HybridDirectory(lockFactory, setPreload(mMapDirectory, lockFactory, preLoadExtensions)); | ||
return new HybridDirectory(lockFactory, setPreload(mMapDirectory, lockFactory, preLoadExtensions), mmapExtensions); | ||
} else { | ||
return primaryDirectory; | ||
} | ||
|
@@ -142,10 +143,12 @@ public static boolean isHybridFs(Directory directory) { | |
*/ | ||
static final class HybridDirectory extends NIOFSDirectory { | ||
private final MMapDirectory delegate; | ||
private final Set<String> mmapExtensions; | ||
|
||
HybridDirectory(LockFactory lockFactory, MMapDirectory delegate) throws IOException { | ||
HybridDirectory(LockFactory lockFactory, MMapDirectory delegate, Set<String> mmapExtensions) throws IOException { | ||
super(delegate.getDirectory(), lockFactory); | ||
this.delegate = delegate; | ||
this.mmapExtensions = mmapExtensions; | ||
} | ||
|
||
@Override | ||
|
@@ -164,43 +167,16 @@ public IndexInput openInput(String name, IOContext context) throws IOException { | |
} | ||
} | ||
|
||
boolean useDelegate(String name) { | ||
final String extension = FileSwitchDirectory.getExtension(name); | ||
return mmapExtensions.contains(extension); | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
IOUtils.close(super::close, delegate); | ||
} | ||
|
||
boolean useDelegate(String name) { | ||
String extension = FileSwitchDirectory.getExtension(name); | ||
switch (extension) { | ||
// Norms, doc values and term dictionaries are typically performance-sensitive and hot in the page | ||
// cache, so we use mmap, which provides better performance. | ||
case "nvd": | ||
case "dvd": | ||
case "tim": | ||
// We want to open the terms index and KD-tree index off-heap to save memory, but this only performs | ||
// well if using mmap. | ||
case "tip": | ||
// dim files only apply up to lucene 8.x indices. It can be removed once we are in lucene 10 | ||
case "dim": | ||
case "kdd": | ||
case "kdi": | ||
// Compound files are tricky because they store all the information for the segment. Benchmarks | ||
// suggested that not mapping them hurts performance. | ||
case "cfs": | ||
// MMapDirectory has special logic to read long[] arrays in little-endian order that helps speed | ||
// up the decoding of postings. The same logic applies to positions (.pos) of offsets (.pay) but we | ||
// are not mmaping them as queries that leverage positions are more costly and the decoding of postings | ||
// tends to be less a bottleneck. | ||
case "doc": | ||
return true; | ||
// Other files are either less performance-sensitive (e.g. stored field index, norms metadata) | ||
// or are large and have a random access pattern and mmap leads to page cache trashing | ||
// (e.g. stored fields and term vectors). | ||
default: | ||
return false; | ||
} | ||
} | ||
|
||
MMapDirectory getDelegate() { | ||
return delegate; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an expert parameter which, I suspect, few are going to touch. Can we javadoc this as
expert
with a description similar to above?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nknize sure can