-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Lazily initialize TransportActionStats in RequestHandlerRegistry #117435
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
Lazily initialize TransportActionStats in RequestHandlerRegistry #117435
Conversation
Same as #114107 but for the transport side. We consuming more than 0.5M for these stat instances and a large fraction if not the majority will go unused in many use-cases, given how expensive stats are in terms of volatile operations the overhead of an added `getAquire` is trivial in the absence of writes.
|
Pinging @elastic/es-core-infra (Team:Core/Infra) |
|
Pinging @elastic/es-data-management (Team:Data Management) |
| private final Writeable.Reader<Request> requestReader; | ||
| private final TransportActionStatsTracker statsTracker = new TransportActionStatsTracker(); | ||
| @SuppressWarnings("unused") // only accessed via #STATS_TRACKER_HANDLE, lazy initialized because instances consume non-trivial heap | ||
| private volatile TransportActionStatsTracker statsTracker; |
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.
If it's volatile we don't need to use STATS_TRACKER_HANDLE.getAcquire(this) to read it do we?
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.
Right but lets drop the volatile then :D I figured I'd be fun to experiment with weaker ordering a little here and there in obvious spots, might be helpful on ARM in some cases where there's only ever a single write to a variable. Who knows might help init performance either now or on some future ARM or similar hardware.
(admittedly there's more interesting spots for that stuff than this ... :))
|
|
||
| private static final VarHandle STATS_TRACKER_HANDLE; | ||
|
|
||
| static { |
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.
Can we add this to the classes passed to org.elasticsearch.bootstrap.Elasticsearch#ensureInitialized to ensure it's always initialized eagerly before the security manager comes along and causes problems?
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.
Sure thing, dded this one as well as MethodHandlers where I did the same thing now.
DaveCTurner
left a comment
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.
LGTM
| } | ||
|
|
||
| private TransportActionStatsTracker statsTracker() { | ||
| var tracker = existingStatsTracker(); |
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.
If you're looking for yet-weaker memory semantics, I think this one can be a regular (nonvolatile) read. If it's null then the compareAndExchange will establish the right guarantees, and if it's not null then it has to be the right value.
Risks perhaps creating a few more unused TransportActionStatsTracker instances tho I guess.
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.
Yea somehow a plain read in this kind of spot weirds me out a little :D but you are right, we could relax these spots further technically I guess I just don't feel adventurous enough for that this evening (I do realise though that we actually do this kind of thing ... sync write -> plain read ... in a couple spots like the CS + routing table computation already).
💚 Backport successful
|
…7435) (#118381) Same as #114107 but for the transport side. We are consuming more than 0.5M for these stat instances and a large fraction if not the majority will go unused in many use-cases, given how expensive stats are in terms of volatile operations the overhead of an added `getAcquire` is trivial in the absence of writes. Outside of reducing the prod footprint this is also kind of nice in x-pack internal cluster tests in particular where it saves quite a bit of heap. Co-authored-by: Dimitris Rempapis <[email protected]>
Same as #114107 but for the transport side.
We are consuming more than 0.5M for these stat instances and a large fraction if not the majority will go unused in many use-cases, given how expensive stats are in terms of volatile operations the overhead of an added
getAcquireis trivial in the absence of writes.Outside of reducing the prod footprint this is also kind of nice in x-pack internal cluster tests in particular where it saves quite a bit of heap.