-
Notifications
You must be signed in to change notification settings - Fork 24.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
Reduce heap-memory usage of ingest-geoip plugin #28963
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 |
---|---|---|
|
@@ -21,28 +21,28 @@ | |
|
||
import com.maxmind.db.NoCache; | ||
import com.maxmind.db.NodeCache; | ||
import com.maxmind.db.Reader; | ||
import com.maxmind.geoip2.DatabaseReader; | ||
import org.apache.lucene.util.IOUtils; | ||
import org.elasticsearch.common.Booleans; | ||
import org.elasticsearch.common.SuppressForbidden; | ||
import org.elasticsearch.common.settings.Setting; | ||
import org.elasticsearch.ingest.Processor; | ||
import org.elasticsearch.plugins.IngestPlugin; | ||
import org.elasticsearch.plugins.Plugin; | ||
|
||
import java.io.Closeable; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.PathMatcher; | ||
import java.nio.file.StandardOpenOption; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Stream; | ||
import java.util.zip.GZIPInputStream; | ||
|
||
public class IngestGeoIpPlugin extends Plugin implements IngestPlugin, Closeable { | ||
public static final Setting<Long> CACHE_SIZE = | ||
|
@@ -80,28 +80,38 @@ static Map<String, DatabaseReaderLazyLoader> loadDatabaseReaders(Path geoIpConfi | |
if (Files.exists(geoIpConfigDirectory) == false && Files.isDirectory(geoIpConfigDirectory)) { | ||
throw new IllegalStateException("the geoip directory [" + geoIpConfigDirectory + "] containing databases doesn't exist"); | ||
} | ||
|
||
boolean loadDatabaseOnHeap = Booleans.parseBoolean(System.getProperty("es.geoip.load_db_on_heap", "false")); | ||
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. 👍 to this escape hatch 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 really need this escape hatch? If this is to remain undocumented (which is should if it is kept as a sysprop), what would eventually allow us to remove this untested behavior? 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. This is needed until we have a better understanding of the implications on nodes with small amounts of native memory. |
||
Map<String, DatabaseReaderLazyLoader> databaseReaders = new HashMap<>(); | ||
try (Stream<Path> databaseFiles = Files.list(geoIpConfigDirectory)) { | ||
PathMatcher pathMatcher = geoIpConfigDirectory.getFileSystem().getPathMatcher("glob:**.mmdb.gz"); | ||
PathMatcher pathMatcher = geoIpConfigDirectory.getFileSystem().getPathMatcher("glob:**.mmdb"); | ||
// Use iterator instead of forEach otherwise IOException needs to be caught twice... | ||
Iterator<Path> iterator = databaseFiles.iterator(); | ||
while (iterator.hasNext()) { | ||
Path databasePath = iterator.next(); | ||
if (Files.isRegularFile(databasePath) && pathMatcher.matches(databasePath)) { | ||
String databaseFileName = databasePath.getFileName().toString(); | ||
DatabaseReaderLazyLoader holder = new DatabaseReaderLazyLoader(databaseFileName, () -> { | ||
try (InputStream inputStream = new GZIPInputStream(Files.newInputStream(databasePath, StandardOpenOption.READ))) { | ||
return new DatabaseReader.Builder(inputStream).withCache(cache).build(); | ||
} | ||
}); | ||
DatabaseReaderLazyLoader holder = new DatabaseReaderLazyLoader(databaseFileName, | ||
() -> { | ||
DatabaseReader.Builder builder = createDatabaseBuilder(databasePath).withCache(cache); | ||
if (loadDatabaseOnHeap) { | ||
builder.fileMode(Reader.FileMode.MEMORY); | ||
} else { | ||
builder.fileMode(Reader.FileMode.MEMORY_MAPPED); | ||
} | ||
return builder.build(); | ||
}); | ||
databaseReaders.put(databaseFileName, holder); | ||
} | ||
} | ||
} | ||
return Collections.unmodifiableMap(databaseReaders); | ||
} | ||
|
||
@SuppressForbidden(reason = "Maxmind API requires java.io.File") | ||
private static DatabaseReader.Builder createDatabaseBuilder(Path databasePath) { | ||
return new DatabaseReader.Builder(databasePath.toFile()); | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
if (databaseReaders != null) { | ||
|
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.
Thanks for removing unused exception.