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
Avoid humongous blocks #103340
Avoid humongous blocks #103340
Conversation
*/ | ||
public final class BooleanBigArrayBlock extends AbstractArrayBlock implements BooleanBlock { | ||
|
||
private static final long BASE_RAM_BYTES_USED = 0; // TODO: fix this |
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 will address this in a follow-up for both BigArrays Vectors and Blocks.
); | ||
int currentLength = array.length; | ||
// TODO: should be ANDed instead? | ||
if (currentLength - valueCount > 1024 || valueCount < (currentLength / 2)) { |
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 it should be ANDed instead of ORed. Let's discuss this, and I can make the change in a follow-up if we agree.
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.
++ happy to separate it.
@@ -344,7 +344,6 @@ public void testFetchMvLongs() throws IOException { | |||
assertMap(map, matchesMap().entry("columns", columns)); | |||
} | |||
|
|||
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/100528") |
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.
We can unmute this test now.
Hi @dnhatn, I've created a changelog YAML for you. |
Pinging @elastic/es-ql (Team:QL) |
Pinging @elastic/elasticsearch-esql (:Query Languages/ES|QL) |
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 that this is a good change. it would be interesting to see what impact it might have on performance, but we can check that post-merge in the nightly benchmarks, since the reliability is the higher-order bit here.
Thanks Chris! Yes, that's very possible. I will keep an eye on the benchmark. If there is a performance impact, then I think we switch to BigArrays blocks only in the |
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.
Maybe we should limit the number of elements in the block rather than move to big arrays? We don't have a good way to cut existing blocks but maybe that'd be better?
private double[] values; | ||
private interface DoubleValues extends Releasable { | ||
void setValue(int index, double value); | ||
} |
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 worry about these things slowing things down by making the write bimorphic instead of an array access.
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've pushed 5e5330d.
Thanks, Nik. I think we prefer not to fail the query in this case and we don't have a correct estimate upfront for multi-valued fields. I think we can avoid the write bimorphic. Since the number of concurrent builders is bounded by the number of execution pipepline, it's okay to always use primitive arrays for the block builders. And in the |
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 only got to take a short look at this PR, but I think the approach is fine. Left a minor remark only.
...esql/compute/src/main/generated-src/org/elasticsearch/compute/data/BooleanBigArrayBlock.java
Show resolved
Hide resolved
Hmm, but do we really need to fail the query? I guess, ideally we would want to emit multiple blocks once a certain total position count of the block is reached, no? (Currently, I think we do this based on position count only, which doesn't work with MVs.) With BigArray-backed blocks, isn't there a risk that some downstream operator makes wasteful use of memory because it expects a reasonably-sized block that it can process in one go? In any case, IMO this is fine as it avoids OOM in more cases, but maybe a longer-term solution would be to cut blocks after a certain size when working with MVs. |
Thanks, everyone! I am going to merge this PR and will keep an eye on the benchmark for the next several days. |
The HeapAttackIT#testFetchTooManyMvLongs was OOM, even though plenty of memory was available and all memory usage was accurately tracked. The issue lies in the wasteful space occupied by humongous objects, specifically blocks with large backing arrays. The space left in regions by these humongous objects remains unused. This PR addresses the problem by forcing blocks to use BigArrays once the memory used by their primitive backing array exceeds a specified threshold - 512KB in this PR.
The HeapAttackIT#testFetchTooManyMvLongs was OOM, even though plenty of memory was available and all memory usage was accurately tracked. The issue lies in the wasteful space occupied by humongous objects, specifically blocks with large backing arrays. The space left in regions by these humongous objects remains unused. This PR addresses the problem by forcing blocks to use BigArrays once the memory used by their primitive backing array exceeds a specified threshold - 512KB in this PR.
The HeapAttackIT#testFetchTooManyMvLongs was OOM, even though plenty of memory was available and all memory usage was accurately tracked. The issue lies in the wasteful space occupied by humongous objects, specifically blocks with large backing arrays. The space left in regions by these humongous objects remains unused. This PR addresses the problem by forcing blocks to use BigArrays once the memory used by their primitive backing array exceeds a specified threshold - 512KB in this PR.
The
HeapAttackIT#testFetchTooManyMvLongs
was OOM, even though plenty of memory was available and all memory usage was accurately tracked. The issue lies in the wasteful space occupied by humongous objects, specifically blocks with large backing arrays. The space left in regions by these humongous objects remains unused. This PR addresses the problem by forcing blocks to use BigArrays once the memory used by their primitive backing array exceeds a specified threshold - 512KB in this PR.