- Notifications
You must be signed in to change notification settings - Fork 25.5k
Optimize some per-document hot paths in the geoip processor #120824
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
Changes from all commits
005ac8a
9509b1f
a219a39
596d3ff
faf0b5f
a6a4135
eb47572
b04e3a7
a44e3b4
03489a5
56108af
2895ae4
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 120824 | ||
summary: Optimize some per-document hot paths in the geoip processor | ||
area: Ingest Node | ||
type: enhancement | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
| @@ -206,12 +206,32 @@ public static Metadata fromXContent(XContentParser parser) { | |
} | ||
| ||
public boolean isCloseToExpiration() { | ||
return Instant.ofEpochMilli(lastCheck).isBefore(Instant.now().minus(25, ChronoUnit.DAYS)); | ||
final Instant now = Instant.ofEpochMilli(System.currentTimeMillis()); // millisecond precision is sufficient (and faster) | ||
return Instant.ofEpochMilli(lastCheck).isBefore(now.minus(25, ChronoUnit.DAYS)); | ||
} | ||
| ||
// these constants support the micro optimization below, see that note | ||
private static final TimeValue THIRTY_DAYS = TimeValue.timeValueDays(30); | ||
private static final long THIRTY_DAYS_MILLIS = THIRTY_DAYS.millis(); | ||
| ||
public boolean isNewEnough(Settings settings) { | ||
TimeValue valid = settings.getAsTime("ingest.geoip.database_validity", TimeValue.timeValueDays(30)); | ||
return Instant.ofEpochMilli(lastCheck).isAfter(Instant.now().minus(valid.getMillis(), ChronoUnit.MILLIS)); | ||
// micro optimization: this looks a little silly, but the expected case is that database_validity is only used in tests. | ||
// we run this code on every document, though, so the argument checking and other bits that getAsTime does is enough | ||
// to show up in a flame graph. | ||
| ||
// if you grep for "ingest.geoip.database_validity" and you'll see that it's not a 'real' setting -- it's only defined in | ||
// AbstractGeoIpIT, that's why it's an inline string constant here and no some static final, and also why it cannot | ||
// be the case that this setting exists in a real running cluster | ||
| ||
final long valid; | ||
if (settings.hasValue("ingest.geoip.database_validity")) { | ||
valid = settings.getAsTime("ingest.geoip.database_validity", THIRTY_DAYS).millis(); | ||
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. Is this slow only when there is no value (b/c we generate an exception or something)? Or is it always slow? If the latter, should we calculate this outside of this method, and have a settings listener listening for updates to the 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. I added another comment here in the code -- the setting itself is kindof a hack to get around the situation where we want to be able to test this code but we can't make it possible to actually change the value of the setting in 'the real world'. I'm not at all opposed to continuing to grind on this, but I'd love to do that in a different PR. 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.
I took a closer look at the idea of the settings listener, and I think the reason we're not doing any of that right now is specifically because the setting in question isn't a 'real setting' -- AFAICT all the settings update listener type methods require a proper Somebody could probably get pretty far by extracting our current code and manually watching for settings changes like this:
| ||
} else { | ||
valid = THIRTY_DAYS_MILLIS; | ||
} | ||
| ||
final Instant now = Instant.ofEpochMilli(System.currentTimeMillis()); // millisecond precision is sufficient (and faster) | ||
return Instant.ofEpochMilli(lastCheck).isAfter(now.minus(valid, ChronoUnit.MILLIS)); | ||
} | ||
| ||
@Override | ||
|
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.
I think we could pass in a ThreadPool, and use ThreadPool::absoluteTimeInMillis, which would be significantly faster since it's cached. Same goes in the other place below.
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.
That makes sense. I'll see if I can make that happen.
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.
I can't make it pass tests! I'm going to open a new ticket to track it.