Preventing Out of Memory Exceptions when Querying a Map
Query-based map methods such as entrySet()` may trigger an out of memory exception (OOME), depending on the size of your map and the available memory of each member. To prevent these exceptions, you can configure your cluster to limit query results.
For example, on a cluster with five members having 10 GB of data and 25 GB heap size per member, a single call of IMap.entrySet()
fetches 50 GB of data and crashes the calling instance.
To prevent this, you can configure a maximum result size limit for query based operations.
This is not a limit like SELECT * FROM map LIMIT 100
, which you can achieve by a
Paging Predicate. A maximum result size limit
for query based operations is meant to be a last line of defense to prevent your members
from retrieving more data than they can handle.
The Hazelcast component which calculates this limit is the QueryResultSizeLimiter
.
Setting Query Result Size Limit
If the QueryResultSizeLimiter
is activated, it calculates a result size limit per partition.
Each QueryOperation
runs on all partitions of a member, so it collects result entries
as long as the member limit is not exceeded. If that happens, a
QueryResultSizeExceededException
is thrown and propagated to the calling instance.
You can configure this limiter using the hazelcast.query.result.size.limit
property. See Configuring Query Result Size.
This limiter depends on an equal distribution of the data on the cluster members to calculate the result size limit for each member. Therefore, there is a hardcoded minimum value defined for the result size limit that is set to 100000:
-
If the value you set for
hazelcast.query.result.size.limit
is lower than 100000, it is automatically increased to 100000. -
The value of
hazelcast.query.result.size.limit
is taken into consideration only if it is higher than 100000.
Local Pre-check
In addition to the distributed result size check in the QueryOperations
,
there is a local pre-check on the calling instance. If you call the method from a client,
the pre-check is executed on the member that invokes the QueryOperations
.
Since the local pre-check can increase the latency of a QueryOperation
,
you can configure how many local partitions should be considered for the pre-check,
or you can deactivate the feature completely.
Scope of Result Size Limit
Besides the designated query operations, there are other operations that use predicates internally.
Those method calls throw the QueryResultSizeExceededException
as well.
See the following matrix for the methods that are covered by the query result size limit.
Configuring Query Result Size
The query result size limit is configured via the following system properties.
-
hazelcast.query.result.size.limit
: Result size limit for query operations on maps. This value defines the maximum number of returned elements for a single query result. If a query exceeds this number of elements, a QueryResultSizeExceededException is thrown. -
hazelcast.query.max.local.partition.limit.for.precheck
: Maximum value of local partitions to trigger local pre-check forPredicates#alwaysTrue()
query operations on maps.
See Configuring with System Properties to learn how to configure Hazelcast Platform using properties, such as the above ones.
See also System Properties to see the list of properties.