Embracing Flexibility with ClickHouse’s Memory Overcommit Feature

ClickHouse's Memory Overcommit Feature

Introduction

In the world of database management, efficiency and optimization are paramount. ClickHouse, a prominent column-oriented database management system renowned for its speed and efficiency in real-time query processing, introduced an innovative feature in version 22.5 that marks a significant advancement in how memory limits are handled: Memory Overcommit. This feature is designed to enhance the flexibility of memory usage limits for queries, making ClickHouse an even more powerful tool for handling large datasets and complex analytical tasks.

A Leap from Rigidity to Flexibility

Prior to version 22.5, ClickHouse enforced memory limits through the max_memory_usage setting, which acted as a rigid boundary for query execution. This setting, while useful in preventing individual queries from monopolizing resources, lacked the flexibility needed to maximize hardware utilization efficiently.

Recognizing the need for a more adaptive approach, ClickHouse developers introduced Memory Overcommit, a feature that allows for more flexible memory limits. With Memory Overcommit, ClickHouse can dynamically manage memory allocation, ensuring that resources are utilized efficiently without compromising the stability of the system.

Practical Implications and Use Cases

Memory Overcommit is particularly beneficial in environments where workloads are variable and unpredictable. For instance, in analytical platforms where both lightweight and heavy queries need to be executed simultaneously, Memory Overcommit ensures that lighter queries can proceed without being unduly delayed by more resource-intensive operations.

Furthermore, this feature introduces a more nuanced approach to resource management, allowing administrators to fine-tune settings to match the specific needs of their environment. By adjusting the overcommit ratio denominators and wait times, it’s possible to balance the need for efficiency with the requirement to maintain system stability.

Enabling Memory Overcommit

Memory Overcommit Settings: To enable Memory Overcommit, disable max_memory_usage and max_memory_usage_for_user by setting them to 0 and configure the overcommit-specific settings: memory_overcommit_ratio_denominator  and memory_overcommit_ratio_denominator_for_user and memory_usage_overcommit_max_wait_microseconds

These settings define the soft memory limits at both global and user levels. Overcommit Trackers and a Waiting Mechanism manage scenarios where memory limits are reached, identifying the most “overcommitted” query to be terminated and allowing other queries to wait for memory to be freed before continuing their execution.

Also configure Global Memory Server Settings

<clickhouse>
<max_server_memory_usage>0</max_server_memory_usage>
<max_server_memory_usage_to_ram_ratio>0.9</max_server_memory_usage_to_ram_ratio></clickhouse>

Utilizing Memory Overcommit

Imagine you are working with a ClickHouse database and you have a variety of queries running concurrently. Some of these queries are lightweight and quick to execute, while others are more memory-intensive, analyzing large datasets.

Without Memory Overcommit, managing these varying workloads efficiently can be challenging, as you must balance the memory allocation to ensure that smaller queries don’t get starved of resources by the larger ones. With Memory Overcommit enabled, this balance is achieved dynamically, allowing for more efficient use of system memory.

How Memory Overcommit Works

For our example, consider two queries. The first is a lightweight query that groups numbers from a smaller dataset:

SELECT number FROM numbers(100) GROUP BY number;

The second query is more memory-intensive, grouping numbers from a significantly larger dataset:

SELECT number FROM numbers(1000000) GROUP BY number SETTINGS memory_overcommit_ratio_denominator=4000, memory_usage_overcommit_max_wait_microseconds=500;

In this scenario, both queries are executed concurrently. Initially, both queries allocate memory within their limits. However, as the system’s memory becomes constrained due to the execution of the more memory-intensive query, Memory Overcommit kicks in.

Memory Overcommit in Action

  1. Memory Limit Reached: Once the system’s memory limit is approached, ClickHouse assesses which query is the most “overcommitted” based on the memory_overcommit_ratio_denominator setting. In our example, the second query with the specific settings (memory_overcommit_ratio_denominator=4000) is identified as such.
  2. Query Selection for Termination: If the memory-intensive query is deemed overcommitted and causing a strain on the system’s resources, it may be selected for termination to free up memory. This decision is made based on the overcommit ratios calculated for each query.
  3. Waiting Mechanism: Meanwhile, other queries (like our first, less resource-intensive query) will wait for a brief period (memory_usage_overcommit_max_wait_microseconds=500) for memory to become available. This waiting mechanism ensures that smaller queries are not unduly affected by the larger queries’ memory demands.
  4. Query Continuation or Termination: If, during the waiting period, sufficient memory is freed up (either through the completion of other queries or the termination of overcommitted queries), the waiting queries can continue execution. If not, they may be terminated with a MEMORY_LIMIT_EXCEEDED exception to prevent system overload.

When deciding which query to terminate under memory pressure with ClickHouse’s Memory Overcommit feature, the system evaluates the overcommit ratios for all running queries. The query with the highest overcommit ratio is typically selected for termination. The overcommit ratio is calculated by dividing the number of allocated bytes by the value of the memory_overcommit_ratio_denominator setting for each query.

Given two queries with different memory_overcommit_ratio_denominator settings:

  • Query 1: memory_overcommit_ratio_denominator=4000
  • Query 2: memory_overcommit_ratio_denominator=7000

The system calculates the overcommit ratio for each query based on their memory usage and their respective memory_overcommit_ratio_denominator values. The query with the higher overcommit ratio is more likely to be terminated. However, the actual query to be terminated also depends on the amount of memory each query has allocated; the memory_overcommit_ratio_denominator is just one part of the equation. The decision is based on the ratio of allocated memory to the denominator value: a lower memory_overcommit_ratio_denominator could indicate a higher overcommitment if the allocated memory is significantly high.

Which one to use?

The key difference between memory_overcommit_ratio_denominator and memory_overcommit_ratio_denominator_for_user lies in their scope of application:

  • Use memory_overcommit_ratio_denominator when you need to control the memory usage of individual queries. This is useful in scenarios where certain queries are known to be more memory-intensive and might require tighter control over their memory allocation to prevent them from affecting the system’s overall stability.
  • Use memory_overcommit_ratio_denominator_for_user when you want to manage memory usage more broadly for all queries executed by a specific user. This approach is beneficial in environments where it’s important to ensure fair memory distribution among multiple users or to cap the total memory usage by a single user’s queries to prevent monopolization of resources.

In practice, administrators can combine both settings to achieve a balanced and fair allocation of memory resources, ensuring that the system remains stable and efficient while catering to the needs of individual queries and users.

This example demonstrates the flexibility and efficiency of Memory Overcommit in managing diverse workloads. By dynamically adjusting memory allocation based on current demand and query characteristics, ClickHouse ensures that all queries have a fair chance of execution without compromising the system’s stability.

Conclusion

ClickHouse’s introduction of Memory Overcommit represents a significant step forward in database management, offering unparalleled flexibility in memory allocation and resource management. This feature not only enhances the efficiency of query processing but also ensures that ClickHouse remains at the forefront of database technology, capable of meeting the demands of modern data-intensive applications. As with any advanced feature, effective use of Memory Overcommit requires a thorough understanding of its mechanisms and careful tuning to achieve the best balance between performance and resource utilization.

To read more about Memory in ClickHouse, please do consider reading the below articles: