A newer version of Platform is available.

View latest

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.

Methods Covered by 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 for Predicates#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.