From d7142b3c56d67208eea68f8486cd15d6a94f2cc6 Mon Sep 17 00:00:00 2001 From: Filitov Mikhail Date: Mon, 25 Aug 2025 08:58:39 +0200 Subject: [PATCH 1/3] Added spilling docs (#21718) Co-authored-by: Ivan Blinkov (cherry picked from commit efe102d8c9dc34099a5f955067b596cbe23d0545) --- ydb/docs/en/core/concepts/glossary.md | 6 + ydb/docs/en/core/concepts/spilling.md | 85 ++++++ ydb/docs/en/core/concepts/toc_i.yaml | 2 + .../en/core/contributor/spilling-service.md | 86 ++++++ ydb/docs/en/core/contributor/toc_i.yaml | 2 + .../devops/concepts/system-requirements.md | 2 + .../manual/initial-deployment.md | 21 ++ .../en/core/reference/configuration/index.md | 2 +- .../configuration/memory_controller_config.md | 121 +++++++++ .../configuration/table_service_config.md | 255 ++++++++++++++++++ .../core/reference/configuration/toc_p.yaml | 2 + .../spilling/can-not-run-operation.md | 28 ++ .../en/core/troubleshooting/spilling/index.md | 18 ++ .../spilling/permission-denied.md | 26 ++ .../spilling/service-not-started.md | 21 ++ .../core/troubleshooting/spilling/toc_p.yaml | 9 + .../spilling/total-size-limit-exceeded.md | 28 ++ ydb/docs/en/core/troubleshooting/toc_p.yaml | 5 + ydb/docs/ru/core/concepts/glossary.md | 6 + ydb/docs/ru/core/concepts/spilling.md | 84 ++++++ ydb/docs/ru/core/concepts/toc_i.yaml | 2 + .../ru/core/contributor/spilling-service.md | 86 ++++++ ydb/docs/ru/core/contributor/toc_i.yaml | 2 + .../devops/concepts/system-requirements.md | 2 + .../manual/initial-deployment.md | 21 ++ .../ru/core/reference/configuration/index.md | 2 +- .../configuration/memory_controller_config.md | 121 +++++++++ .../configuration/table_service_config.md | 255 ++++++++++++++++++ .../core/reference/configuration/toc_p.yaml | 2 + .../spilling/can-not-run-operation.md | 28 ++ .../ru/core/troubleshooting/spilling/index.md | 18 ++ .../spilling/permission-denied.md | 26 ++ .../spilling/service-not-started.md | 21 ++ .../core/troubleshooting/spilling/toc_p.yaml | 9 + .../spilling/total-size-limit-exceeded.md | 29 ++ ydb/docs/ru/core/troubleshooting/toc_p.yaml | 5 + 36 files changed, 1436 insertions(+), 2 deletions(-) create mode 100644 ydb/docs/en/core/concepts/spilling.md create mode 100644 ydb/docs/en/core/contributor/spilling-service.md create mode 100644 ydb/docs/en/core/reference/configuration/memory_controller_config.md create mode 100644 ydb/docs/en/core/reference/configuration/table_service_config.md create mode 100644 ydb/docs/en/core/troubleshooting/spilling/can-not-run-operation.md create mode 100644 ydb/docs/en/core/troubleshooting/spilling/index.md create mode 100644 ydb/docs/en/core/troubleshooting/spilling/permission-denied.md create mode 100644 ydb/docs/en/core/troubleshooting/spilling/service-not-started.md create mode 100644 ydb/docs/en/core/troubleshooting/spilling/toc_p.yaml create mode 100644 ydb/docs/en/core/troubleshooting/spilling/total-size-limit-exceeded.md create mode 100644 ydb/docs/ru/core/concepts/spilling.md create mode 100644 ydb/docs/ru/core/contributor/spilling-service.md create mode 100644 ydb/docs/ru/core/reference/configuration/memory_controller_config.md create mode 100644 ydb/docs/ru/core/reference/configuration/table_service_config.md create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/can-not-run-operation.md create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/index.md create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/permission-denied.md create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/service-not-started.md create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/toc_p.yaml create mode 100644 ydb/docs/ru/core/troubleshooting/spilling/total-size-limit-exceeded.md diff --git a/ydb/docs/en/core/concepts/glossary.md b/ydb/docs/en/core/concepts/glossary.md index 8cf421edf580..0e984d4da6a9 100644 --- a/ydb/docs/en/core/concepts/glossary.md +++ b/ydb/docs/en/core/concepts/glossary.md @@ -440,6 +440,12 @@ A **shared cache** is an [actor](#actor) that stores data pages recently accesse A **memory controller** is an [actor](#actor) that manages {{ ydb-short-name }} [memory limits](../reference/configuration/index.md#memory-controller). +### Spilling {#spilling} + +**Spilling** is a memory management mechanism in {{ ydb-short-name }} that temporarily offloads intermediate query data to external storage when such data exceeds the available node RAM capacity. In {{ ydb-short-name }}, disk storage is currently used for spilling. + +For more details on spilling, see [{#T}](spilling.md). + ### Tablet types {#tablet-types} [Tablets](#tablet) can be considered a framework for building reliable components operating in a distributed system. {{ ydb-short-name }} has multiple components implemented using this framework, listed below. diff --git a/ydb/docs/en/core/concepts/spilling.md b/ydb/docs/en/core/concepts/spilling.md new file mode 100644 index 000000000000..99578a50fe1c --- /dev/null +++ b/ydb/docs/en/core/concepts/spilling.md @@ -0,0 +1,85 @@ +# Spilling + +## Spilling in General + +**Spilling** is a memory management mechanism that temporarily offloads intermediate data arising from computations and exceeding available node RAM capacity to external storage. In {{ ydb-short-name }}, disk storage is currently used for spilling. Spilling enables execution of user queries that require processing large data volumes exceeding available node memory. + +In data processing systems, including {{ ydb-short-name }}, spilling is essential for: + +- processing queries with large data volumes when intermediate results don't fit in RAM +- executing complex analytical operations (aggregations, table joins) over large datasets +- optimizing query performance through intermediate materialization of part of the data in external memory, which in certain scenarios can accelerate overall execution time + + +Spilling operates based on the memory hierarchy principle: + +1. **Random Access Memory (RAM)** — fast but limited. +2. **External storage** — slower but more capacious. + +When memory usage approaches the limit, the system: + +- serializes part of the data +- saves it to external storage +- frees the corresponding memory +- continues processing the query using data remaining in memory +- loads data back into memory, when necessary, to continue computations + + +## Spilling in {{ ydb-short-name }} + +{{ ydb-short-name }} implements the spilling mechanism through the **Spilling Service**, an [actor service](glossary.md#actor-service) that provides temporary storage for data blobs. Spilling is only performed on [database nodes](glossary.md#database-node). Detailed technical information about it is available in [{#T}](../contributor/spilling-service.md). + +### Types of Spilling in {{ ydb-short-name }} + +{{ ydb-short-name }} implements two primary types of spilling that operate at different levels of the computational process: + +* [Computation Spilling](#computation-spilling) +* [Transport Spilling](#transport-spilling) + +These types work independently and can activate simultaneously within a single query, providing comprehensive memory management. + +#### Computation Spilling {#computation-spilling} + +{{ ydb-short-name }} compute cores automatically offload intermediate data to disk when executing operations that require significant memory. This type of spilling is implemented at the level of individual computational operations and activates when memory limits are reached. + +Main usage scenarios: + +* **Aggregations** — when grouping large data volumes, the system offloads intermediate hash tables to disk. +* **Join operations** — when joining large tables, the [Grace Hash Join](https://en.wikipedia.org/wiki/Hash_join#Grace_hash_join) algorithm is used with data partitioning and offloading to disk. + +##### Operation Mechanism + +Compute nodes contain specialized objects for monitoring memory usage. When the data volume approaches the set limit: + +1. The system switches to spilling mode. +2. Data is serialized and divided into blocks (buckets). +3. Part of the blocks is transferred to the Spilling Service for disk storage. +4. Metadata about the data location is kept in memory. +5. The system continues processing the data remaining in memory, which frees additional space. +6. When necessary, data is loaded back and processed. + + +#### Transport Spilling {#transport-spilling} + +This type of spilling operates at the level of data transfer between different query execution stages. The system automatically buffers and offloads data when transfer buffers overflow. This helps avoid blocking the execution of data-generating operations, even when receiving operations are not ready to accept data. + +##### Operation Mechanism + +The data transfer system continuously monitors its state: + +1. **Buffering**: Incoming data accumulates in the transfer system's internal buffers +2. **Fill control**: The system tracks buffer fill levels +3. **Automatic spilling**: When limits are reached, data is automatically serialized and transferred to the Spilling Service +4. **Continued operation**: The transfer system continues accepting new data after freeing memory space +5. **Recovery**: When the next stage is ready, data is read from external storage and passed further + +## Interaction with Memory Controller + +When executing queries, {{ ydb-short-name }} tries to stay within the memory limit set by the [memory controller](../reference/configuration/memory_controller_config.md). To continue fitting within this limit as intermediate computations grow, spilling is used. For more details, see the [Memory Management section](../reference/configuration/table_service_config.md#memory-management). + +## See Also + +- [Spilling Service](../contributor/spilling-service.md) +- [Spilling configuration](../reference/configuration/table_service_config.md) +- [{{ ydb-short-name }} monitoring](../devops/observability/monitoring.md) +- [Performance diagnostics](../troubleshooting/performance/index.md) \ No newline at end of file diff --git a/ydb/docs/en/core/concepts/toc_i.yaml b/ydb/docs/en/core/concepts/toc_i.yaml index d1100619417b..73df9e0fd278 100644 --- a/ydb/docs/en/core/concepts/toc_i.yaml +++ b/ydb/docs/en/core/concepts/toc_i.yaml @@ -16,6 +16,8 @@ items: href: secondary_indexes.md - name: Vector search href: vector_search.md +- name: Spilling + href: spilling.md - name: Change Data Capture (CDC) href: cdc.md when: feature_changefeed diff --git a/ydb/docs/en/core/contributor/spilling-service.md b/ydb/docs/en/core/contributor/spilling-service.md new file mode 100644 index 000000000000..a0007e4665bc --- /dev/null +++ b/ydb/docs/en/core/contributor/spilling-service.md @@ -0,0 +1,86 @@ +# Spilling Service + +## Overview + +The **Spilling Service** is an [actor service](../concepts/glossary.md#actor-service) that provides temporary storage for data blobs in the {{ ydb-short-name }} system. The service operates as a key-value store where clients can save data using a unique identifier and later retrieve it with that identifier. + +## Architecture + +### Main Components + +- **Task queue**: The service maintains an internal queue of read and write operations. All spilling requests are placed in this queue and processed asynchronously. +- **Thread pool**: A pool of worker threads is used to perform I/O operations. The number of threads is [configurable](../reference/configuration/table_service_config.md#workerscount) and affects service performance. +- **File management**: The service automatically creates, deletes, and manages files on disk. +- **Resource monitoring**: The service monitors disk space usage, the number of active operations, and other performance metrics. + +### Data Storage + +Data is saved in files on the local file system. The Spilling Service ensures: + +* distribution of records across files +* file deletion +* data lifecycle management + +In case of an unexpected restart, obsolete files are automatically deleted. + +## Component Interaction + +System components are integrated with the Spilling Service and interact with it through actor system events, explained below. + +### Memory State Monitoring + +Compute nodes continuously monitor memory state through the allocator. The allocator informs nodes about decreasing free memory volume. However, the system does not wait for complete memory exhaustion because the spilling process also requires additional memory resources for serialization and buffering. + +### Event Dispatch + +When spilling is required, the compute component (data transfer system or compute core) performs the following actions: + +1. Serializes data into a blob. +2. Generates a unique identifier for the blob. +3. Creates a spilling request with the blob and the generated identifier. +4. Sends the request to the Spilling Service. +5. Releases resources and enters waiting mode, allowing other tasks to utilize computational resources. + +### Waiting for Results + +After sending the request, the compute component releases resources for other tasks and enters waiting mode, allowing the system to optimally utilize cluster computing resources until the external storage write is complete. + +### Response Handling + +The Spilling Service processes the request and returns a write confirmation for the specified identifier or an error message. The compute component can continue only after receiving confirmation. + +### Data Reading + +When data recovery is needed, the component sends a read request with the blob identifier. The Spilling Service reads data from external storage and returns a response with the recovered data. During data loading, freed computational resources are utilized to process other tasks. + +## Spilling Workflow Diagram + +```mermaid +sequenceDiagram + participant CN as Compute node + participant SS as Spilling Service + participant ES as External storage + + Note over CN: Memory full + CN->>SS: Send data (asynchronously) + Note over CN: Continues working with other data + SS->>ES: Save data + SS-->>CN: Write confirmation (asynchronously) + + Note over CN: Need saved data + CN->>SS: Request data (asynchronously) + Note over CN: Continues working with other data + SS->>ES: Read data + SS-->>CN: Return data (asynchronously) +``` + +## Configuration + +Detailed information about configuring the Spilling Service is available in the [Spilling configuration](../reference/configuration/table_service_config.md) section. + +## See Also + +- [Spilling Concept](../concepts/spilling.md) +- [Spilling configuration](../reference/configuration/table_service_config.md) +- [{{ ydb-short-name }} monitoring](../devops/observability/monitoring.md) +- [Performance diagnostics](../troubleshooting/performance/index.md) diff --git a/ydb/docs/en/core/contributor/toc_i.yaml b/ydb/docs/en/core/contributor/toc_i.yaml index aa121e3a3ddc..cab8b708efed 100644 --- a/ydb/docs/en/core/contributor/toc_i.yaml +++ b/ydb/docs/en/core/contributor/toc_i.yaml @@ -28,6 +28,8 @@ items: href: datashard-locks-and-change-visibility.md - name: Distributed transactions href: datashard-distributed-txs.md + - name: Spilling Service + href: spilling-service.md - name: Testing with load actors href: load-actors-overview.md items: diff --git a/ydb/docs/en/core/devops/concepts/system-requirements.md b/ydb/docs/en/core/devops/concepts/system-requirements.md index 380c69d1c8c7..eae2d45b1638 100644 --- a/ydb/docs/en/core/devops/concepts/system-requirements.md +++ b/ydb/docs/en/core/devops/concepts/system-requirements.md @@ -28,6 +28,8 @@ Prefer to use physical local disk drives for {{ ydb-short-name }} instead of vir Remember that {{ ydb-short-name }} uses some disk space for internal needs when planning disk capacity. For example, on a medium-sized cluster of 8 nodes, you can expect approximately 100 GB to be consumed for a static group on the whole cluster. On a large cluster with more than 1500 nodes, this will be about 200 GB. There are also 25.6 GB of logs on each Pdisk and a system area on each Pdisk. Its size depends on the size of the Pdisk, but is no less than 0.2 GB. +The disk is also used for [spilling](../../concepts/glossary.md#spilling), a memory management mechanism that temporarily saves intermediate query execution results to disk when RAM is insufficient. This is important to consider when planning disk capacity. Detailed spilling configuration is described in the [Spilling Configuration](../../reference/configuration/table_service_config.md) section. + ## Software Configuration {#software} A {{ ydb-short-name }} server can be run on servers with a Linux operating system, kernel 4.19 and higher, and libc 2.30. For example, Ubuntu 20.04, Debian 11, Fedora 34, or newer releases. {{ ydb-short-name }} uses the [TCMalloc](https://google.github.io/tcmalloc) memory allocator. To make it efficient, [enable](https://google.github.io/tcmalloc/tuning.html#system-level-optimizations) Transparent Huge Pages and Memory overcommitment. diff --git a/ydb/docs/en/core/devops/deployment-options/manual/initial-deployment.md b/ydb/docs/en/core/devops/deployment-options/manual/initial-deployment.md index 40be37c55437..aec049304fe2 100644 --- a/ydb/docs/en/core/devops/deployment-options/manual/initial-deployment.md +++ b/ydb/docs/en/core/devops/deployment-options/manual/initial-deployment.md @@ -77,6 +77,27 @@ To ensure that {{ ydb-short-name }} can access block disks, add the user that wi sudo usermod -aG disk ydb ``` +## Configure File Descriptor Limits {#file-descriptors} + +For proper operation of {{ ydb-short-name }}, especially when using [spilling](../../../concepts/spilling.md) in multi-node clusters, it is recommended to increase the limit of simultaneously open file descriptors. + +To change the file descriptor limit, add the following lines to the `/etc/security/limits.conf` file: + +```bash +ydb soft nofile 10000 +ydb hard nofile 10000 +``` + +Where `ydb` is the username under which `ydbd` runs. + +After changing the file, you need to reboot the system or log in again to apply the new limits. + +{% note info %} + +For more information about spilling configuration and its relationship with file descriptors, see the [Spilling Configuration](../../../reference/configuration/table_service_config.md#file-system-requirements) section. + +{% endnote %} + ## Install {{ ydb-short-name }} Software on Each Server {#install-binaries} 1. Download and unpack an archive with the `ydbd` executable and the libraries required for {{ ydb-short-name }} to run: diff --git a/ydb/docs/en/core/reference/configuration/index.md b/ydb/docs/en/core/reference/configuration/index.md index 0da7b47bef4a..f0ea173773c5 100644 --- a/ydb/docs/en/core/reference/configuration/index.md +++ b/ydb/docs/en/core/reference/configuration/index.md @@ -557,7 +557,7 @@ The activity components include: - KQP -The memory limit for each activity component specifies the maximum amount of memory it can attempt to use. However, to prevent the {{ ydb-short-name }} process from exceeding the soft memory limit, the total consumption of activity components is further constrained by an additional limit known as the activities memory limit. If the total memory usage of the activity components exceeds this limit, any additional memory requests will be denied. +The memory limit for each activity component specifies the maximum amount of memory it can attempt to use. However, to prevent the {{ ydb-short-name }} process from exceeding the soft memory limit, the total consumption of activity components is further constrained by an additional limit known as the activities memory limit. If the total memory usage of the activity components exceeds this limit, any additional memory requests will be denied. When query execution approaches memory limits, {{ ydb-short-name }} activates [spilling](../../concepts/spilling.md) to temporarily save intermediate data to disk, preventing memory limit violations. As a result, while the combined individual limits of the activity components might collectively exceed the activities memory limit, each component's individual limit should be less than this overall cap. Additionally, the sum of the minimum memory limits for the cache components, plus the activities memory limit, must be less than the soft memory limit. diff --git a/ydb/docs/en/core/reference/configuration/memory_controller_config.md b/ydb/docs/en/core/reference/configuration/memory_controller_config.md new file mode 100644 index 000000000000..d0b5e0821caf --- /dev/null +++ b/ydb/docs/en/core/reference/configuration/memory_controller_config.md @@ -0,0 +1,121 @@ +# memory_controller_config + +There are many components inside {{ ydb-short-name }} [database nodes](../../concepts/glossary.md#database-node) that utilize memory. Most of them need a fixed amount, but some are flexible and can use varying amounts of memory, typically to improve performance. If {{ ydb-short-name }} components allocate more memory than is physically available, the operating system is likely to [terminate](https://en.wikipedia.org/wiki/Out_of_memory#Recovery) the entire {{ ydb-short-name }} process, which is undesirable. The memory controller's goal is to allow {{ ydb-short-name }} to avoid out-of-memory situations while still efficiently using the available memory. + +Examples of components managed by the memory controller: + +- [Shared cache](../../concepts/glossary.md#shared-cache): stores recently accessed data pages read from [distributed storage](../../concepts/glossary.md#distributed-storage) to reduce disk I/O and accelerate data retrieval. +- [MemTable](../../concepts/glossary.md#memtable): holds data that has not yet been flushed to [SST](../../concepts/glossary.md#sst). +- [KQP](../../concepts/glossary.md#kqp): stores intermediate query results. +- Allocator caches: keep memory blocks that have been released but not yet returned to the operating system. + +Memory limits can be configured to control overall memory usage, ensuring the database operates efficiently within the available resources. + +## Hard Memory Limit {#hard-memory-limit} + +The hard memory limit specifies the total amount of memory available to the {{ ydb-short-name }} process. + +By default, the hard memory limit for the {{ ydb-short-name }} process is set to its [cgroups](https://en.wikipedia.org/wiki/Cgroups) memory limit. + +In environments without a cgroups memory limit, the default hard memory limit equals the host's total available memory. This configuration allows the database to utilize all available resources but may lead to resource competition with other processes on the same host. Although the memory controller attempts to account for this external consumption, such a setup is not recommended. + +Additionally, the hard memory limit can be specified in the configuration. Note that the database process may still exceed this limit. Therefore, it is highly recommended to use cgroups memory limits in production environments to enforce strict memory control. + +Most of other memory limits can be configured either in absolute bytes or as a percentage relative to the hard memory limit. Using percentages is advantageous for managing clusters with nodes of varying capacities. If both absolute byte and percentage limits are specified, the memory controller uses a combination of both (maximum for lower limits and minimum for upper limits). + +Example of the `memory_controller_config` section with a specified hard memory limit: + +```yaml +memory_controller_config: + hard_limit_bytes: 16106127360 +``` + +## Soft Memory Limit {#soft-memory-limit} + +The soft memory limit specifies a dangerous threshold that should not be exceeded by the {{ ydb-short-name }} process under normal circumstances. + +If the soft limit is exceeded, {{ ydb-short-name }} gradually reduces the [shared cache](../../concepts/glossary.md#shared-cache) size to zero. Therefore, more database nodes should be added to the cluster as soon as possible, or per-component memory limits should be reduced. + +## Target Memory Utilization {#target-memory-utilization} + +The target memory utilization specifies a threshold for the {{ ydb-short-name }} process memory usage that is considered optimal. + +Flexible cache sizes are calculated according to their limit thresholds to keep process consumption around this value. + +For example, in a database that consumes a little memory on query execution, caches consume memory around this threshold, and other memory stays free. If query execution consumes more memory, caches start to reduce their sizes to their minimum threshold. + +## Per-Component Memory Limits + +There are two different types of components within {{ ydb-short-name }}. + +The first type, known as cache components, functions as caches, for example, by storing the most recently used data. Each cache component has minimum and maximum memory limit thresholds, allowing them to adjust their capacity dynamically based on the current {{ ydb-short-name }} process consumption. + +The second type, known as activity components, allocates memory for specific activities, such as query execution or the [compaction](../../concepts/glossary.md#compaction) process. Each activity component has a fixed memory limit. Additionally, there is a total memory limit for these activities from which they attempt to draw the required memory. + +Many other auxiliary components and processes operate alongside the {{ ydb-short-name }} process, consuming memory. Currently, these components do not have any memory limits. + +### Cache Components Memory Limits + +The cache components include: + +- Shared cache +- MemTable + +Each cache component's limits are dynamically recalculated every second to ensure that each component consumes memory proportionally to its limit thresholds while the total consumed memory stays close to the target memory utilization. + +The minimum memory limit threshold for cache components isn't reserved, meaning the memory remains available until it is actually used. However, once this memory is filled, the components typically retain the data, operating within their current memory limit. Consequently, the sum of the minimum memory limits for cache components is expected to be less than the target memory utilization. + +If needed, both the minimum and maximum thresholds should be overridden; otherwise, any missing threshold will have a default value. + +Example of the `memory_controller_config` section with specified shared cache limits: + +```yaml +memory_controller_config: + shared_cache_min_percent: 10 + shared_cache_max_percent: 30 +``` + +### Activity Components Memory Limits + +The activity components include: + +- KQP + +The memory limit for each activity component specifies the maximum amount of memory it can attempt to use. However, to prevent the {{ ydb-short-name }} process from exceeding the soft memory limit, the total consumption of activity components is further constrained by an additional limit known as the activities memory limit. If the total memory usage of the activity components exceeds this limit, any additional memory requests will be denied. When query execution approaches memory limits, {{ ydb-short-name }} activates [spilling](../../concepts/spilling.md) to temporarily save intermediate data to disk, preventing memory limit violations. + +As a result, while the combined individual limits of the activity components might collectively exceed the activities memory limit, each component's individual limit should be less than this overall cap. Additionally, the sum of the minimum memory limits for the cache components, plus the activities memory limit, must be less than the soft memory limit. + +There are some other activity components that currently do not have individual memory limits. + +Example of the `memory_controller_config` section with a specified KQP limit: + +```yaml +memory_controller_config: + query_execution_limit_percent: 25 +``` + +## Configuration Parameters + +Each configuration parameter applies within the context of a single database node. + +As mentioned above, the sum of the minimum memory limits for the cache components plus the activities memory limit should be less than the soft memory limit. + +This restriction can be expressed in a simplified form: + +$shared\_cache\_min\_percent + mem\_table\_min\_percent + activities\_limit\_percent < soft\_limit\_percent$ + +Or in a detailed form: + +$Max(shared\_cache\_min\_percent * hard\_limit\_bytes / 100, shared\_cache\_min\_bytes) + Max(mem\_table\_min\_percent * hard\_limit\_bytes / 100, mem\_table\_min\_bytes) + Min(activities\_limit\_percent * hard\_limit\_bytes / 100, activities\_limit\_bytes) < Min(soft\_limit\_percent * hard\_limit\_bytes / 100, soft\_limit\_bytes)$ + +| Parameter | Default | Description | +| --- | --- | --- | +| `hard_limit_bytes` | CGroup memory limit /
Host memory | Hard memory usage limit. | +| `soft_limit_percent` /
`soft_limit_bytes` | 75% | Soft memory usage limit. | +| `target_utilization_percent` /
`target_utilization_bytes` | 50% | Target memory utilization. | +| `activities_limit_percent` /
`activities_limit_bytes` | 30% | Activities memory limit. | +| `shared_cache_min_percent` /
`shared_cache_min_bytes` | 20% | Minimum threshold for the shared cache memory limit. | +| `shared_cache_max_percent` /
`shared_cache_max_bytes` | 50% | Maximum threshold for the shared cache memory limit. | +| `mem_table_min_percent` /
`mem_table_min_bytes` | 1% | Minimum threshold for the MemTable memory limit. | +| `mem_table_max_percent` /
`mem_table_max_bytes` | 3% | Maximum threshold for the MemTable memory limit. | +| `query_execution_limit_percent` /
`query_execution_limit_bytes` | 20% | KQP memory limit. | diff --git a/ydb/docs/en/core/reference/configuration/table_service_config.md b/ydb/docs/en/core/reference/configuration/table_service_config.md new file mode 100644 index 000000000000..a0d50437408d --- /dev/null +++ b/ydb/docs/en/core/reference/configuration/table_service_config.md @@ -0,0 +1,255 @@ +# `table_service_config` configuration section + +The `table_service_config` section contains configuration parameters for the table service, including spilling settings. + +## spilling_service_config + +[Spilling](../../concepts/spilling.md) is a memory management mechanism in {{ ydb-short-name }} that temporarily saves data to disk when the system runs out of RAM. + +### Primary Configuration Parameters + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 21474836480 + io_thread_pool: + workers_count: 2 + queue_size: 1000 +``` + +### Directory Configuration + +#### local_file_config.root + +**Type:** `string` +**Default:** `""` (temporary directory) +**Description:** A filesystem directory for saving spilling files. + +For each `ydbd` process, a separate directory is created with a unique name. Spilling directories have the following name format: + +`node__` + +Where: + +- `node_id` — [node](../../concepts/glossary.md#node) identifier +- `spilling_service_id` — unique instance identifier that is created when initializing the [Spilling Service](../../contributor/spilling-service.md) one time when the ydbd process starts + +Spilling files are stored inside each such directory. + +Example of a complete spilling directory path: + +```bash +/tmp/spilling-tmp-/node_1_32860791-037c-42b4-b201-82a0a337ac80 +``` + +Where: + +- `/tmp` — value of the `root` parameter +- `` — username under which the `ydbd` process is running + +**Important notes:** + +- At process startup, all existing spilling directories in the specified directory are automatically deleted. Spilling directories have a special name format that includes an instance identifier, which is generated once when the ydbd process starts. When a new process starts, all directories in the spilling directory that match the name format but have a different `spilling_service_id` from the current one are deleted. +- The directory must have sufficient write and read permissions for the user under which ydbd is running + +{% note info %} + +Spilling is only performed on [database nodes](../../concepts/glossary.md#database-node). + +{% endnote %} + +##### Possible errors + +- `Permission denied` — insufficient directory access permissions. See [{#T}](../../troubleshooting/spilling/permission-denied.md) + +#### local_file_config.max_total_size + +**Type:** `uint64` +**Default:** `21474836480` (20 GiB) +**Description:** Maximum total size of all spilling files on each [node](../../concepts/glossary.md#node). When the limit is exceeded, spilling operations fail with an error. The total spilling limit across the entire cluster is the sum of `max_total_size` values from all nodes. + +##### Recommendations + +- Set the value based on available disk space + +##### Possible errors + +- `Total size limit exceeded: X/YMb` — maximum total size of spilling files exceeded. See [{#T}](../../troubleshooting/spilling/total-size-limit-exceeded.md) + +### Thread Pool Configuration + +{% note info %} + +I/O pool threads for spilling are created in addition to threads allocated for the [actor system](../../concepts/glossary.md#actor-system). When planning the number of threads, consider the overall system load. + +**Important:** The spilling thread pool is separate from the actor system thread pools. + +For information about configuring actor system thread pools and their impact on system performance, see [Actor System Configuration](index.md#actor-system) and [Changing Actor System Configuration](../../devops/configuration-management/configuration-v1/change_actorsystem_configs.md). For Configuration V2, the actor system settings are described in the [Configuration V2 settings](../../devops/configuration-management/configuration-v2/config-settings.md). + +{% endnote %} + +#### local_file_config.io_thread_pool.workers_count + +**Type:** `uint32` +**Default:** `2` +**Description:** Number of worker threads for processing spilling I/O operations. + +##### Recommendations + +- Increase for high-load systems + +##### Possible errors + +- `Can not run operation` — I/O thread pool operation queue overflow. See [{#T}](../../troubleshooting/spilling/can-not-run-operation.md) + +#### local_file_config.io_thread_pool.queue_size + +**Type:** `uint32` +**Default:** `1000` +**Description:** Size of the spilling operations queue. Each task sends only one data block to spilling at a time, so large values are usually not required. + +##### Possible errors + +- `Can not run operation` — I/O thread pool operation queue overflow. See [{#T}](../../troubleshooting/spilling/can-not-run-operation.md) + +### Memory Management {#memory-management} + +#### Relationship with memory_controller_config + +Spilling activation is closely related to memory controller settings. Detailed `memory_controller_config` configuration is described in a [separate article](memory_controller_config.md). + +The key parameter for spilling is **`activities_limit_percent`**, which determines the amount of memory allocated for query processing activities. This parameter affects the available memory for user queries and, accordingly, the frequency of spilling activation. + +#### Impact on spilling + +- When increasing `activities_limit_percent`, more memory is available for queries → spilling activates less frequently +- When decreasing `activities_limit_percent`, less memory is available for queries → spilling activates more frequently + +{% note warning %} + +However, it's important to consider that spilling itself requires memory. If you set `activities_limit_percent` too high, memory may still be exhausted despite spilling, as the spilling mechanism itself consumes memory resources. + +{% endnote %} + +### File System Requirements + +#### File Descriptors + +{% note info %} + +For information about configuring file descriptor limits during initial deployment, see the [File Descriptor Limits](../../../devops/deployment-options/manual/initial-deployment.html#file-descriptors) section. + +{% endnote %} + +### Configuration Examples + +#### High-load System + +For maximum performance in high-load systems, it is recommended to increase the spilling size and number of worker threads: + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 107374182400 # 100 GiB + io_thread_pool: + workers_count: 8 + queue_size: 2000 +``` + +#### Limited Resources + +For systems with limited resources, it is recommended to use conservative settings: + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 5368709120 # 5 GiB + io_thread_pool: + workers_count: 1 + queue_size: 500 +``` + +### Advanced Configuration + +#### Enabling and Disabling Spilling + +The following parameters control the enabling and disabling of various spilling types. They should typically only be changed when there are specific system requirements. + +##### local_file_config.enable + +**Location:** `table_service_config.spilling_service_config.local_file_config.enable` +**Type:** `boolean` +**Default:** `true` +**Description:** Enables or disables the spilling service. When disabled (`false`), [spilling](../../concepts/spilling.md) does not function, which may lead to errors when processing large data volumes. + +##### Possible errors + +- `Spilling Service not started` / `Service not started` — attempt to use spilling when Spilling Service is disabled. See [{#T}](../../troubleshooting/spilling/service-not-started.md) + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + enable: true +``` + +##### enable_spilling_nodes + +**Location:** `table_service_config.enable_spilling_nodes` +**Type:** `bool` +**Default:** `true` +**Description:** Enables spilling on database nodes. When disabled (`false`), spilling does not function on database nodes. + +```yaml +table_service_config: + enable_spilling_nodes: true +``` + +##### enable_query_service_spilling + +**Location:** `table_service_config.enable_query_service_spilling` +**Type:** `boolean` +**Default:** `true` +**Description:** Global option that enables transport spilling during data transfer between tasks. + +```yaml +table_service_config: + enable_query_service_spilling: true +``` + +{% note info %} + +This setting works in conjunction with the local spilling service configuration. When disabled (`false`), transport spilling does not function even with enabled `spilling_service_config`. + +{% endnote %} + +### Complete Example + +```yaml +table_service_config: + enable_spilling_nodes: true + enable_query_service_spilling: true + spilling_service_config: + local_file_config: + enable: true + root: "/var/spilling" + max_total_size: 53687091200 # 50 GiB + io_thread_pool: + workers_count: 4 + queue_size: 1500 +``` + +## See Also + +- [Spilling Concept](../../concepts/spilling.md) +- [Spilling Service Architecture](../../contributor/spilling-service.md) +- [Spilling Troubleshooting](../../troubleshooting/spilling/index.md) +- [Memory Controller Configuration](memory_controller_config.md) +- [{{ ydb-short-name }} Monitoring](../../devops/observability/monitoring.md) +- [Performance Diagnostics](../../troubleshooting/performance/index.md) diff --git a/ydb/docs/en/core/reference/configuration/toc_p.yaml b/ydb/docs/en/core/reference/configuration/toc_p.yaml index 9ba30bda53e5..93d48917828b 100644 --- a/ydb/docs/en/core/reference/configuration/toc_p.yaml +++ b/ydb/docs/en/core/reference/configuration/toc_p.yaml @@ -3,3 +3,5 @@ items: href: tls.md - name: client_certificate_authorization href: client_certificate_authorization.md +- name: table_service_config + href: table_service_config.md diff --git a/ydb/docs/en/core/troubleshooting/spilling/can-not-run-operation.md b/ydb/docs/en/core/troubleshooting/spilling/can-not-run-operation.md new file mode 100644 index 000000000000..77d95fd3c9f9 --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/can-not-run-operation.md @@ -0,0 +1,28 @@ +# Can not run operation + +I/O thread pool operation queue overflow. This occurs when the spilling I/O thread pool queue is full and cannot accept new operations, causing spilling operations to fail. + +## Diagnostics + +Check the I/O thread pool configuration and usage: + +- Check the `queue_size` parameter in `io_thread_pool` configuration +- Review the `workers_count` parameter for the I/O thread pool + +## Recommendations + +To resolve this issue: + +1. **Increase queue size:** + - Increase `queue_size` in `io_thread_pool` configuration + - This allows more operations to be queued before overflow occurs + +2. **Increase worker threads:** + - Increase `workers_count` for faster operation processing + - More worker threads can process operations faster, reducing queue buildup + +{% note info %} + +The I/O thread pool processes spilling operations asynchronously. If the queue overflows, new spilling operations will fail until space becomes available. + +{% endnote %} diff --git a/ydb/docs/en/core/troubleshooting/spilling/index.md b/ydb/docs/en/core/troubleshooting/spilling/index.md new file mode 100644 index 000000000000..6170ce9ed324 --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/index.md @@ -0,0 +1,18 @@ +# Spilling Troubleshooting + +This section provides troubleshooting information for common spilling issues in {{ ydb-short-name }}. Spilling is a memory management mechanism that temporarily saves intermediate computation data to disk when the system runs out of RAM. These errors can occur during query execution when the system attempts to use spilling functionality and can be observed in logs and query responses. + +## Common Issues + +- [Permission denied](permission-denied.md) - Insufficient access permissions to the spilling directory +- [Spilling Service not started](service-not-started.md) - Attempt to use spilling when the Spilling Service is disabled +- [Total size limit exceeded](total-size-limit-exceeded.md) - Maximum total size of spilling files exceeded +- [Can not run operation](can-not-run-operation.md) - I/O thread pool operation queue overflow + +## See Also + +- [Spilling Configuration](../../reference/configuration/table_service_config.md) +- [Spilling Concept](../../concepts/spilling.md) +- [Memory Controller Configuration](../../reference/configuration/memory_controller_config.md) +- [{{ ydb-short-name }} Monitoring](../../devops/observability/monitoring.md) +- [Performance Diagnostics](../performance/index.md) diff --git a/ydb/docs/en/core/troubleshooting/spilling/permission-denied.md b/ydb/docs/en/core/troubleshooting/spilling/permission-denied.md new file mode 100644 index 000000000000..3bb33c45aac5 --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/permission-denied.md @@ -0,0 +1,26 @@ +# Permission Denied + +Insufficient access permissions to the spilling directory prevent {{ ydb-short-name }} from writing data to disk during spilling operations. This can cause queries to fail when they require spilling to handle large data volumes. + +## Diagnostics + +Check if the spilling directory exists and has proper permissions: + +- Verify that the spilling directory exists (see [Spilling Configuration](../../reference/configuration/table_service_config.md#root) for information on how to find the spilling directory) +- Ensure the directory has read and write permissions for the user under which `ydbd` is running +- Check access permissions to the spilling directory +- Verify that the user under which `ydbd` runs can read and write to the directory + +## Recommendations + +If permissions are incorrect: + +1. Change the directory owner to the user under which `ydbd` runs. +2. Ensure read/write permissions are set for the directory owner. +3. Restart the `ydbd` process to apply the changes. + +{% note info %} + +The spilling directory is automatically created by {{ ydb-short-name }} when the process starts. If the directory doesn't exist, check that the `root` parameter in the spilling configuration is set correctly. + +{% endnote %} diff --git a/ydb/docs/en/core/troubleshooting/spilling/service-not-started.md b/ydb/docs/en/core/troubleshooting/spilling/service-not-started.md new file mode 100644 index 000000000000..5bf83878b571 --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/service-not-started.md @@ -0,0 +1,21 @@ +# Spilling Service Not Started + +An attempt to use spilling occurs when the Spilling Service is disabled. This happens when the spilling service is not properly configured or has been disabled in the configuration. + +## Diagnostics + +Check the spilling service configuration: + +- Verify that [`table_service_config.spilling_service_config.local_file_config.enable`](../../reference/configuration/table_service_config.md#local-file-config-enable) is set to `true`. + +## Recommendations + +To enable spilling: + +1. Set [`table_service_config.spilling_service_config.local_file_config.enable`](../../reference/configuration/table_service_config.md#local-file-config-enable): `true` in your configuration. + +{% note info %} + +Read more about the spilling architecture in [Spilling Architecture in {{ ydb-short-name }}](../../concepts/spilling.md#spilling-architecture-in-ydb). + +{% endnote %} diff --git a/ydb/docs/en/core/troubleshooting/spilling/toc_p.yaml b/ydb/docs/en/core/troubleshooting/spilling/toc_p.yaml new file mode 100644 index 000000000000..a7c03f45ceeb --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/toc_p.yaml @@ -0,0 +1,9 @@ +items: +- name: Can not run operation + href: can-not-run-operation.md +- name: Permission denied + href: permission-denied.md +- name: Spilling Service not started + href: service-not-started.md +- name: Total size limit exceeded + href: total-size-limit-exceeded.md diff --git a/ydb/docs/en/core/troubleshooting/spilling/total-size-limit-exceeded.md b/ydb/docs/en/core/troubleshooting/spilling/total-size-limit-exceeded.md new file mode 100644 index 000000000000..25a1270812f2 --- /dev/null +++ b/ydb/docs/en/core/troubleshooting/spilling/total-size-limit-exceeded.md @@ -0,0 +1,28 @@ +# Total Size Limit Exceeded + +The maximum total size of spilling files has been exceeded (parameter [`max_total_size`](../../reference/configuration/table_service_config.md#local-file-config-max-total-size)). This occurs when the total size of all spilling files reaches the configured limit, preventing new spilling operations. + +## Diagnostics + +Check the current spilling usage: + +- Monitor the total size of spilling files in the spilling directory. +- Check the current value of the `max_total_size` parameter. +- Review available disk space in the spilling directory location. +- Check if there are any stuck spilling files that should have been cleaned up. + +## Recommendations + +To resolve this issue: + +1. **Increase the spilling size limit:** + - If there is sufficient free disk space, increase the [`max_total_size`](../../reference/configuration/table_service_config.md#local-file-config-max-total-size) parameter in the configuration. + - Increase the value by 20–50% from the current one. + +2. **Expand disk space:** + - If there is insufficient free disk space, add additional disk space. + - Ensure that the spilling directory is located on a disk with sufficient capacity. + +3. **Try repeating the query:** + - Wait for other resource-intensive queries to complete. + - Repeat the query execution during less busy times. diff --git a/ydb/docs/en/core/troubleshooting/toc_p.yaml b/ydb/docs/en/core/troubleshooting/toc_p.yaml index 89fa605dbc17..0422e1a34a6a 100644 --- a/ydb/docs/en/core/troubleshooting/toc_p.yaml +++ b/ydb/docs/en/core/troubleshooting/toc_p.yaml @@ -4,3 +4,8 @@ items: include: mode: link path: performance/toc_p.yaml +- name: Spilling issues + href: spilling/index.md + include: + mode: link + path: spilling/toc_p.yaml diff --git a/ydb/docs/ru/core/concepts/glossary.md b/ydb/docs/ru/core/concepts/glossary.md index e598e0187d99..956bf6d81199 100644 --- a/ydb/docs/ru/core/concepts/glossary.md +++ b/ydb/docs/ru/core/concepts/glossary.md @@ -470,6 +470,12 @@ SID идентифицирует индивидуального [пользов **Контроллер памяти** или **memory controller**— это [актор](#actor), который управляет [лимитами памяти](../reference/configuration/index.md#memory-controller) {{ ydb-short-name }}. +### Спиллинг {#spilling} + +**Спиллинг** или **spilling** — это механизм управления памятью в {{ ydb-short-name }}, который временно выгружает промежуточные данные запросов во внешнее хранилище, когда такие данные превышают доступный объём оперативной памяти узла. В {{ ydb-short-name }} для спиллинга в настоящее время используется диск. + +Подробнее о спиллинге см. в [{#T}](spilling.md). + ### Типы таблеток {#tablet-types} [Таблетки](#tablet) можно рассматривать как фреймворк для создания надёжных компонентов, работающих в распределённой системе. Многие компоненты {{ ydb-short-name }} — как системные, так и работающие с пользовательскими данными — реализованы с использованием этого фреймворка, основные из них перечислены ниже. diff --git a/ydb/docs/ru/core/concepts/spilling.md b/ydb/docs/ru/core/concepts/spilling.md new file mode 100644 index 000000000000..2ee0ad1faa79 --- /dev/null +++ b/ydb/docs/ru/core/concepts/spilling.md @@ -0,0 +1,84 @@ +# Спиллинг + +## Спиллинг в общем + +**Спиллинг** — это механизм управления памятью, при котором промежуточные данные, возникающие в результате выполнения запросов и превышающие доступный объём оперативной памяти узла, временно выгружаются во внешнее хранилище. В {{ ydb-short-name }} для спиллинга в настоящее время используется диск. Спиллинг обеспечивает выполнение пользовательских запросов, которые требуют обработки больших объёмов данных, превышающих доступную память узла. + +В системах обработки данных, включая {{ ydb-short-name }}, спиллинг важен для: + +- обработки запросов с большими объёмами данных, когда промежуточные результаты не помещаются в оперативную память; +- выполнения сложных аналитических операций (агрегации, соединения таблиц) над большими наборами данных; +- оптимизации производительности запросов за счет промежуточной материализации части данных во внешней памяти, что в определенных сценариях может ускорить общее время выполнения. + +Спиллинг функционирует на основе принципа иерархии памяти: + +1. **Оперативная память (RAM)** — быстрый, но ограниченный ресурс. +2. **Внешняя память** — медленнее, но более ёмкая. + +Когда использование памяти приближается к лимиту, система: + +- сериализует часть данных; +- сохраняет их во внешней памяти; +- освобождает соответствующую память; +- продолжает обработку запроса, используя данные, находящиеся в памяти; +- при необходимости загружает данные обратно в память для продолжения вычислений. + + +## Спиллинг в {{ ydb-short-name }} {#architecture} + +{{ ydb-short-name }} реализует механизм спиллинга через **Spilling Service** — [акторный сервис](glossary.md#actor-service), который предоставляет временное хранилище для блобов данных. Спиллинг осуществляется только на [узлах базы данных](glossary.md#database-node). Подробная техническая информация о Spilling Service доступна в разделе [Spilling Service](../contributor/spilling-service.md). + +### Типы спиллинга в {{ ydb-short-name }} + +{{ ydb-short-name }} реализует два основных типа спиллинга, функционирующие на различных уровнях вычислительного процесса: + +* [Спиллинг в вычислениях](#computation-spilling) +* [Спиллинг в транспорте](#transport-spilling) + +Эти типы работают независимо друг от друга и могут активироваться одновременно в рамках одного запроса, обеспечивая комплексное управление памятью. + +#### Спиллинг в вычислениях {#computation-spilling} + +Вычислительные ядра {{ ydb-short-name }} автоматически выгружают промежуточные данные на диск при выполнении операций, требующих значительного объема памяти. Данный тип спиллинга реализован на уровне отдельных вычислительных операций и активируется при достижении лимитов памяти. + +**Основные сценарии использования:** + +* **Агрегации** — при группировке больших объемов данных система выгружает промежуточные хеш-таблицы на диск + +* **Join операции** — при объединении таблиц большого размера используется алгоритм Grace Hash Join с разделением данных на партиции и их выгрузкой на диск + +##### Механизм функционирования + +Вычислительные узлы содержат специализированные объекты для мониторинга использования памяти. При приближении объема данных к установленному лимиту: + +1. Система переключается в режим спиллинга +2. Данные сериализуются и разделяются на блоки (бакеты) +3. Часть блоков передается в Spilling Service для сохранения на диске +4. В памяти сохраняется метаинформация о расположении данных +5. Система продолжает обработку данных, оставшихся в памяти, что позволяет освободить дополнительное место +6. При необходимости данные загружаются обратно и обрабатываются + +#### Спиллинг в транспорте {#transport-spilling} + +Данный тип спиллинга функционирует на уровне передачи данных между различными этапами выполнения запроса. Подсистема передачи данных автоматически буферизует и выгружает данные при переполнении буферов. Это помогает не блокировать операции, генерирующие данные, даже в ситуациях, когда принимающая сторона временно не готова принять данные. + +##### Механизм функционирования + +Подсистема передачи данных осуществляет постоянный мониторинг своего состояния: + +1. **Буферизация**: Входящие данные накапливаются во внутренних буферах подсистемы +2. **Контроль заполнения**: Система отслеживает уровень заполнения буферов +3. **Автоматический спиллинг**: При достижении лимитов данные автоматически сериализуются и передаются в Spilling Service +4. **Продолжение функционирования**: Подсистема продолжает прием новых данных после освобождения места в памяти +5. **Восстановление**: При готовности следующего этапа данные читаются из внешнего хранилища и передаются далее + +## Взаимодействие с контроллером памяти + +При выполнении запросов {{ ydb-short-name }} старается умещаться в заданный лимит памяти, который устанавливается [контроллером памяти](../reference/configuration/memory_controller_config.md). Чтобы продолжать помещаться в этот лимит даже при росте промежуточных вычислений, используется спиллинг. Подробнее см. раздел [Управление памятью](../reference/configuration/table_service_config.md#memory-management). + +## См. также + +- [Spilling Service](../contributor/spilling-service.md) +- [Конфигурация спиллинга](../reference/configuration/table_service_config.md) +- [Мониторинг {{ ydb-short-name }}](../devops/observability/monitoring.md) +- [Диагностика производительности](../troubleshooting/performance/index.md) diff --git a/ydb/docs/ru/core/concepts/toc_i.yaml b/ydb/docs/ru/core/concepts/toc_i.yaml index 7421b5075b84..8b9115af876a 100644 --- a/ydb/docs/ru/core/concepts/toc_i.yaml +++ b/ydb/docs/ru/core/concepts/toc_i.yaml @@ -16,6 +16,8 @@ items: href: secondary_indexes.md - name: Векторный поиск href: vector_search.md +- name: Спиллинг + href: spilling.md - name: Change Data Capture (CDC) href: cdc.md when: feature_changefeed diff --git a/ydb/docs/ru/core/contributor/spilling-service.md b/ydb/docs/ru/core/contributor/spilling-service.md new file mode 100644 index 000000000000..ab3b8997e286 --- /dev/null +++ b/ydb/docs/ru/core/contributor/spilling-service.md @@ -0,0 +1,86 @@ +# Spilling Service + +## Обзор + +**Spilling Service** — это [акторный сервис](../concepts/glossary.md#actor-service), который предоставляет временное хранилище для блобов данных в системе {{ ydb-short-name }}. Сервис работает по принципу key-value хранилища, где клиенты могут сохранять данные по уникальному идентификатору и получать их обратно по этому идентификатору. + +## Архитектура + +### Основные компоненты + +- **Task queue**: Сервис поддерживает внутреннюю очередь операций записи и чтения. Все запросы на спиллинг помещаются в данную очередь и обрабатываются асинхронно. +- **Thread pool**: Для выполнения операций ввода-вывода используется пул рабочих потоков. Количество потоков [конфигурируется](../reference/configuration/table_service_config.md#workerscount) и влияет на производительность сервиса. +- **File management**: Сервис автоматически создает, удаляет и управляет файлами на диске. +- **Resource monitoring**: Сервис осуществляет мониторинг использования дискового пространства, количества активных операций и других метрик производительности. + +### Хранение данных + +Данные сохраняются в файлах на локальной файловой системе. Spilling Service обеспечивает: + +* распределение записей между файлами; +* удаление файлов; +* управление жизненным циклом данных. + +При непредвиденном перезапуске устаревшие файлы удаляются автоматически. + +## Взаимодействие с компонентами + +Компоненты системы интегрированы с Spilling Service и взаимодействуют с ним через события акторной системы: + +### Мониторинг состояния памяти + +Вычислительные узлы осуществляют постоянный мониторинг состояния памяти через аллокатор. Аллокатор информирует узлы о снижении объема свободной памяти. Однако, система не дожидается полного исчерпания памяти, поскольку процесс спиллинга также требует дополнительных ресурсов памяти для сериализации и буферизации данных. + +### Отправка событий + +При обнаружении необходимости спиллинга данных вычислительный компонент (подсистема передачи данных или вычислительное ядро) выполняет следующие действия: + +1. Сериализует данные в блоб +2. Генерирует уникальный идентификатор для блоба +3. Создает запрос на спиллинг с блобом и сгенерированным идентификатором +4. Отправляет запрос в Spilling Service +5. Освобождает ресурсы и переходит в режим ожидания, давая возможность другим задачам использовать вычислительные ресурсы + +### Ожидание результатов + +После отправки запроса вычислительный компонент освобождает ресурсы для других задач и переходит в режим ожидания, позволяя системе оптимально использовать вычислительные мощности кластера до завершения записи во внешнее хранилище. + +### Обработка ответов + +Spilling Service обрабатывает запрос и возвращает подтверждение записи по указанному идентификатору или сообщение об ошибке. Продолжение работы вычислительного компонента возможно только после получения подтверждения. + +### Чтение данных + +При необходимости восстановления данных компонент отправляет запрос чтения с идентификатором блоба. Spilling Service читает данные из внешней памяти и возвращает ответ с восстановленными данными. Во время ожидания загрузки данных освободившиеся вычислительные ресурсы используются для обработки других задач. + +## Схема работы спиллинга + +```mermaid +sequenceDiagram + participant CN as Вычислительный узел + participant SS as Spilling Service + participant ES as Внешнее хранилище + + Note over CN: Память заполнена + CN->>SS: Отправка данных (асинхронно) + Note over CN: Продолжает работу с другими данными + SS->>ES: Сохранение данных + SS-->>CN: Подтверждение записи (асинхронно) + + Note over CN: Нужны сохраненные данные + CN->>SS: Запрос данных (асинхронно) + Note over CN: Продолжает работу с другими данными + SS->>ES: Чтение данных + SS-->>CN: Возврат данных (асинхронно) +``` + +## Конфигурация + +Подробная информация о настройке Spilling Service доступна в разделе [Конфигурация спиллинга](../reference/configuration/table_service_config.md). + +## См. также + +- [Концепция спиллинга](../concepts/spilling.md) +- [Конфигурация спиллинга](../reference/configuration/table_service_config.md) +- [Мониторинг {{ ydb-short-name }}](../devops/observability/monitoring.md) +- [Диагностика производительности](../troubleshooting/performance/index.md) diff --git a/ydb/docs/ru/core/contributor/toc_i.yaml b/ydb/docs/ru/core/contributor/toc_i.yaml index 72e9158480cc..153eae5846f4 100644 --- a/ydb/docs/ru/core/contributor/toc_i.yaml +++ b/ydb/docs/ru/core/contributor/toc_i.yaml @@ -30,6 +30,8 @@ items: href: datashard-distributed-txs.md - name: Конфигурация V2 href: configuration-v2.md + - name: Spilling Service + href: spilling-service.md - name: Тестирование с помощью нагружающих акторов href: load-actors-overview.md items: diff --git a/ydb/docs/ru/core/devops/concepts/system-requirements.md b/ydb/docs/ru/core/devops/concepts/system-requirements.md index 029d676fdaa2..5b7632a0db81 100644 --- a/ydb/docs/ru/core/devops/concepts/system-requirements.md +++ b/ydb/docs/ru/core/devops/concepts/system-requirements.md @@ -28,6 +28,8 @@ При планировании объёма хранилища следует учитывать, что {{ ydb-short-name }} использует часть дискового пространства для своих внутренних нужд. Так, например, на кластере среднего размера из 8 узлов можно ожидать потребления порядка 100 ГБ на весь кластер под статическую группу. На большом кластере с >1500 узлов — около 200 ГБ. Также имеются системные логи объёмом 25.6 ГБ на каждом Pdisk и системная область на каждом Pdisk. Её размер зависит от объёма Pdisk, но составляет не менее 0.2 ГБ. + Также диск используется для [спиллинга](../../concepts/glossary.md#spilling) — механизма управления памятью, который позволяет временно сохранять промежуточные результаты выполнения запросов на диск при нехватке оперативной памяти. Это также важно учитывать при планировании объёма диска. Подробная конфигурация спиллинга описана в разделе [Конфигурация спиллинга](../../reference/configuration/table_service_config.md). + ## Программная конфигурация {#software} {{ ydb-short-name }} сервер может быть запущен на серверах с операционной системой Linux с ядром версии 4.19 и выше и libc версии 2.30. Например, Ubuntu 20.04, Debian 11, Fedora 34 или более новые версии. {{ ydb-short-name }} использует аллокатор памяти [TCMalloc](https://google.github.io/tcmalloc), для его эффективной работы рекомендуется [включить](https://google.github.io/tcmalloc/tuning.html#system-level-optimizations) Transparent Huge Pages и Memory overcommitment. diff --git a/ydb/docs/ru/core/devops/deployment-options/manual/initial-deployment.md b/ydb/docs/ru/core/devops/deployment-options/manual/initial-deployment.md index 0ed7dc35f2e1..eec2925c892a 100644 --- a/ydb/docs/ru/core/devops/deployment-options/manual/initial-deployment.md +++ b/ydb/docs/ru/core/devops/deployment-options/manual/initial-deployment.md @@ -77,6 +77,27 @@ sudo useradd ydb -g ydb sudo usermod -aG disk ydb ``` +## Настройте лимиты файловых дескрипторов {#file-descriptors} + +Для корректной работы {{ ydb-short-name }}, особенно при использовании [спиллинга](../../../concepts/spilling.md) в многоузловых кластерах, рекомендуется увеличить лимит на количество одновременно открытых файловых дескрипторов. + +Для изменения лимита файловых дескрипторов добавьте следующие строки в файл `/etc/security/limits.conf`: + +```bash +ydb soft nofile 10000 +ydb hard nofile 10000 +``` + +Где `ydb` — имя пользователя, под которым запускается `ydbd`. + +После изменения файла необходимо перезагрузить систему или заново залогиниться для применения новых лимитов. + +{% note info %} + +Для получения дополнительной информации о конфигурации спиллинга и его связи с файловыми дескрипторами см. раздел [«Конфигурация спиллинга»](../../../reference/configuration/table_service_config.md#file-system-requirements). + +{% endnote %} + ## Установите программное обеспечение {{ ydb-short-name }} на каждом сервере {#install-binaries} 1. Скачайте и распакуйте архив с исполняемым файлом `ydbd` и необходимыми для работы {{ ydb-short-name }} библиотеками: diff --git a/ydb/docs/ru/core/reference/configuration/index.md b/ydb/docs/ru/core/reference/configuration/index.md index d9b9051ce52a..f560d34f5b9d 100644 --- a/ydb/docs/ru/core/reference/configuration/index.md +++ b/ydb/docs/ru/core/reference/configuration/index.md @@ -881,7 +881,7 @@ memory_controller_config: - KQP. -Лимит памяти для каждого из компонентов-активностей указывает максимальное количество памяти, которое он может попытаться использовать. Однако, чтобы предотвратить превышение процессом {{ ydb-short-name }} мягкого лимита памяти, общее потребление компонентов-активностей ограничивается дополнительным лимитом, называемым лимитом памяти для активностей. Если общее использование памяти активными компонентами превышает этот лимит, любые дополнительные запросы на память будут отклонены. +Лимит памяти для каждого из компонентов-активностей указывает максимальное количество памяти, которое он может попытаться использовать. Однако, чтобы предотвратить превышение процессом {{ ydb-short-name }} мягкого лимита памяти, общее потребление компонентов-активностей ограничивается дополнительным лимитом, называемым лимитом памяти для активностей. Если общее использование памяти активными компонентами превышает этот лимит, любые дополнительные запросы на память будут отклонены. Когда выполнение запросов приближается к лимитам памяти, {{ ydb-short-name }} активирует [спиллинг](../../concepts/spilling.md) для временного сохранения промежуточных данных на диск, предотвращая нарушение лимитов памяти. Таким образом, хотя суммарные индивидуальные лимиты компонентов-активностей могут в совокупности превышать лимит памяти для активностей, индивидуальный лимит каждого компонента должен быть меньше этого общего предела. Кроме того, сумма минимальных лимитов памяти для кеш-компонентов плюс лимит памяти для активностей должна быть меньше мягкого лимита памяти. diff --git a/ydb/docs/ru/core/reference/configuration/memory_controller_config.md b/ydb/docs/ru/core/reference/configuration/memory_controller_config.md new file mode 100644 index 000000000000..97ada99b4588 --- /dev/null +++ b/ydb/docs/ru/core/reference/configuration/memory_controller_config.md @@ -0,0 +1,121 @@ +# memory_controller_config + +Внутри [узлов](../../concepts/glossary.md#database-node) {{ ydb-short-name }} работают множество различных компонентов, использующих память. Большинству из них требуется фиксированное количество памяти, но некоторые из них могут гибко варьировать объём используемой памяти, тем самым улучшая производительность всей системы. Если компоненты {{ ydb-short-name }} выделяют больше памяти, чем физически доступно, операционная система, вероятно, [завершит](https://en.wikipedia.org/wiki/Out_of_memory#Recovery) весь процесс {{ ydb-short-name }}, что крайне нежелательно. Цель контроллера памяти — позволить {{ ydb-short-name }} избегать ситуаций с нехваткой памяти, при этом эффективно используя имеющийся её объём. + +Примеры компонентов, управляемых контроллером памяти: + +- [Общий кеш](../../concepts/glossary.md#shared-cache): хранит недавно доступные страницы данных, считанные из [распределённого хранилища](../../concepts/glossary.md#distributed-storage), чтобы уменьшить количество операций ввода-вывода с диска и ускорить получение данных. +- [MemTable](../../concepts/glossary.md#memtable): содержит данные, которые ещё не были записаны в [SST](../../concepts/glossary.md#sst). +- [KQP](../../concepts/glossary.md#kqp): хранит промежуточные результаты обработки запросов. +- Кеши аллокатора: хранят блоки памяти, которые были освобождены, но ещё не возвращены операционной системе. + +Лимиты памяти могут быть настроены для контроля общего использования памяти, обеспечивая эффективную работу базы данных в рамках доступных ресурсов. + +## Жёсткий лимит памяти {#hard-memory-limit} + +Жёсткий лимит памяти определяет общее количество памяти, доступное для процесса {{ ydb-short-name }}. + +По умолчанию жёсткий лимит памяти для процесса {{ ydb-short-name }} равен лимиту памяти, указанному в его [cgroups](https://en.wikipedia.org/wiki/Cgroups). + +В окружениях без лимита памяти cgroups значение жёсткого лимита памяти по умолчанию равно общему объёму доступной памяти хоста. Эта конфигурация позволяет базе данных использовать все доступные ресурсы, но может привести к конкуренции за ресурсы с другими процессами на том же хосте. Хотя контроллер памяти пытается учесть это внешнее потребление, такое использование не рекомендуется. + +Жёсткий лимит памяти также может быть задан в конфигурации. Обратите внимание, что процесс базы данных всё равно может превысить этот лимит. Поэтому настоятельно рекомендуется использовать лимиты памяти cgroups в производственных окружениях для строгого контроля памяти. + +Большинство других лимитов памяти можно настроить либо в абсолютных байтах, либо в процентах относительно жёсткого лимита памяти. Использование процентов удобно для управления кластерами с узлами разной ёмкости. Если указаны как абсолютные лимиты в байтах, так и процентные лимиты, контроллер памяти использует комбинацию обоих (максимум для нижних лимитов и минимум для верхних лимитов). + +Пример секции `memory_controller_config` с указанным жёстким лимитом памяти: + +```yaml +memory_controller_config: + hard_limit_bytes: 16106127360 +``` + +## Мягкий лимит памяти {#soft-memory-limit} + +Мягкий лимит памяти определяет опасный порог, который процесс {{ ydb-short-name }} не должен превышать при нормальных обстоятельствах. + +Если мягкий лимит превышен, {{ ydb-short-name }} постепенно уменьшает размер [общего кеша](../../concepts/glossary.md#shared-cache) до нуля. В таком случае следует как можно скорее добавить больше узлов баз данных в кластер или снизить лимиты памяти для отдельных компонентов. + +## Целевое использование памяти {#target-memory-utilization} + +Целевое использование памяти определяет порог использования памяти процессом {{ ydb-short-name }}, который считается оптимальным. + +Гибкие размеры кешей рассчитываются в соответствии с их пределами, чтобы поддерживать потребление памяти процессом вблизи этого значения. + +Например, в базе данных, которая расходует немного памяти на выполнение запросов, кеши используют память вблизи этого порога, а остальная память остаётся свободной. Если выполнение запросов начинает потреблять больше памяти, кеши начинают сокращать свои размеры до минимального порога. + +## Лимиты памяти для отдельных компонентов + +Внутри {{ ydb-short-name }} существует два разных типа компонентов. + +Первый тип компонентов, или кеш-компоненты, функционируют как кеши, например, храня последние использованные данные. Каждый кеш-компонент имеет минимальный и максимальный пороговые значения лимита памяти, что позволяет ему динамически изменять свою ёмкость в зависимости от текущего потребления памяти процессом {{ ydb-short-name }}. + +Второй тип компонентов, или компоненты-активности, выделяют память для конкретных задач, таких как выполнение запросов или процесс компактизации. Каждый компонент-активность имеет фиксированный лимит памяти. Также существует дополнительный общий лимит памяти для таких компонентов, из которого они пытаются получить необходимую память. + +Многие другие вспомогательные компоненты и процессы работают параллельно с процессом {{ ydb-short-name }}, потребляя память. В настоящее время эти компоненты не имеют каких-либо лимитов памяти. + +### Лимиты памяти для кеш-компонентов + +К кеш-компонентам относятся: + +- Общий кеш; +- MemTable. + +Лимиты каждого кеш-компонента динамически пересчитываются каждую секунду, чтобы каждый компонент потреблял память пропорционально своим предельным значениям, а общее потребление памяти оставалось около целевого использования памяти. + +Минимальный порог лимита памяти кеш-компонентов не резервируется, что означает, что память остаётся доступной до тех пор, пока она не будет фактически использована. Однако, как только эта память заполнена, компоненты обычно сохраняют данные, действуя в рамках своего текущего лимита памяти. Таким образом, ожидается, что сумма минимальных лимитов памяти кеш-компонентов будет меньше целевого использования памяти. + +При необходимости следует переопределить как минимальные, так и максимальные пороговые значения; в противном случае, если пороговое значение отсутствует, оно будет иметь значение по умолчанию. + +Пример секции `memory_controller_config` с указанными лимитами общего кеша: + +```yaml +memory_controller_config: + shared_cache_min_percent: 10 + shared_cache_max_percent: 30 +``` + +### Лимиты памяти для компонентов-активностей + +К компонентам-активностям относятся: + +- KQP. + +Лимит памяти для каждого из компонентов-активностей указывает максимальное количество памяти, которое он может попытаться использовать. Однако, чтобы предотвратить превышение процессом {{ ydb-short-name }} мягкого лимита памяти, общее потребление компонентов-активностей ограничивается дополнительным лимитом, называемым лимитом памяти для активностей. Если общее использование памяти активными компонентами превышает этот лимит, любые дополнительные запросы на память будут отклонены. Когда выполнение запросов приближается к лимитам памяти, {{ ydb-short-name }} активирует [спиллинг](../../concepts/spilling.md) для временного сохранения промежуточных данных на диск, предотвращая нарушение лимитов памяти. + +Таким образом, хотя суммарные индивидуальные лимиты компонентов-активностей могут в совокупности превышать лимит памяти для активностей, индивидуальный лимит каждого компонента должен быть меньше этого общего предела. Кроме того, сумма минимальных лимитов памяти для кеш-компонентов плюс лимит памяти для активностей должна быть меньше мягкого лимита памяти. + +Существуют и другие компоненты-активности, которые в настоящее время не имеют каких-либо индивидуальных лимитов памяти. + +Пример секции `memory_controller_config` с указанным лимитом для KQP: + +```yaml +memory_controller_config: + query_execution_limit_percent: 25 +``` + +## Параметры конфигурации + +Каждый параметр конфигурации применяется в контексте одного узла базы данных. + +Как упоминалось ранее, ожидается, что сумма минимальных лимитов памяти для кеш-компонентов плюс лимит памяти для активностей должна быть меньше мягкого лимита памяти. + +Это ограничение можно выразить в упрощённой форме: + +$shared\_cache\_min\_percent + mem\_table\_min\_percent + activities\_limit\_percent < soft\_limit\_percent$ + +Или в детализированной форме: + +$Max(shared\_cache\_min\_percent * hard\_limit\_bytes / 100, shared\_cache\_min\_bytes) + Max(mem\_table\_min\_percent * hard\_limit\_bytes / 100, mem\_table\_min\_bytes) + Min(activities\_limit\_percent * hard\_limit\_bytes / 100, activities\_limit\_bytes) < Min(soft\_limit\_percent * hard\_limit\_bytes / 100, soft\_limit\_bytes)$ + +| Параметры | Значение по умолчанию | Описание | +| --- | --- | --- | +| `hard_limit_bytes` | CGroup memory limit /
Память хоста | Жёсткий лимит использования памяти. | +| `soft_limit_percent` /
`soft_limit_bytes` | 75% | Мягкий лимит использования памяти. | +| `target_utilization_percent` /
`target_utilization_bytes` | 50% | Целевое использование памяти. | +| `activities_limit_percent` /
`activities_limit_bytes` | 30% | Лимит памяти для активностей. | +| `shared_cache_min_percent` /
`shared_cache_min_bytes` | 20% | Минимальный порог для лимита памяти общего кеша. | +| `shared_cache_max_percent` /
`shared_cache_max_bytes` | 50% | Максимальный порог для лимита памяти общего кеша. | +| `mem_table_min_percent` /
`mem_table_min_bytes` | 1% | Минимальный порог для лимита памяти MemTable. | +| `mem_table_max_percent` /
`mem_table_max_bytes` | 3% | Максимальный порог для лимита памяти MemTable. | +| `query_execution_limit_percent` /
`query_execution_limit_bytes` | 20% | Лимит памяти для KQP. | diff --git a/ydb/docs/ru/core/reference/configuration/table_service_config.md b/ydb/docs/ru/core/reference/configuration/table_service_config.md new file mode 100644 index 000000000000..9a359501b742 --- /dev/null +++ b/ydb/docs/ru/core/reference/configuration/table_service_config.md @@ -0,0 +1,255 @@ +# Секция конфигурации `table_service_config` + +Секция `table_service_config` содержит параметры конфигурации для сервиса таблиц, включая настройки спиллинга. + +## spilling_service_config + +[Спиллинг](../../concepts/spilling.md) — это механизм управления памятью в {{ ydb-short-name }}, который временно сохраняет данные на диск при нехватке оперативной памяти. + +### Основные параметры конфигурации + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 21474836480 + io_thread_pool: + workers_count: 2 + queue_size: 1000 +``` + +### Конфигурация директории + +#### local_file_config.root + +**Тип:** `string` +**По умолчанию:** `""` (временная директория) +**Описание:** Файловая директория для сохранения файлов спиллинга. + +Для каждого процесса `ydbd` создается отдельная директория с уникальным именем. Директории спиллинга имеют следующий формат имени: + +`node__` + +Где: + +- `node_id` — идентификатор [узла](../../concepts/glossary.md#node) +- `spilling_service_id` — уникальный идентификатор экземпляра, который создается при инициализации [Spilling Service](../../contributor/spilling-service.md) один раз при запуске процесса ydbd + +Файлы спиллинга хранятся внутри каждой такой директории. + +Пример полного пути к директории спиллинга: + +```bash +/tmp/spilling-tmp-/node_1_32860791-037c-42b4-b201-82a0a337ac80 +``` + +Где: + +- `/tmp` — значение параметра `root` +- `` — имя пользователя, под которым запускается процесс `ydbd` + +**Важные замечания:** + +- При запуске процесса все существующие директории спиллинга в указанной директории автоматически удаляются. Директории спиллинга имеют специальный формат имени, который включает идентификатор экземпляра, генерируемый один раз при запуске процесса ydbd. При запуске нового процесса все директории в директории спиллинга, которые соответствуют формату имени, но имеют другой `spilling_service_id` от текущего, удаляются. +- Директория должна иметь достаточные права на запись и чтение для пользователя, под которым запускается ydbd + +{% note info %} + +Спиллинг выполняется только на [узлах базы данных](../../concepts/glossary.md#database-node). + +{% endnote %} + +##### Возможные ошибки + +- `Permission denied` — недостаточные права доступа к директории. См. [{#T}](../../troubleshooting/spilling/permission-denied.md) + +#### local_file_config.max_total_size + +**Тип:** `uint64` +**По умолчанию:** `21474836480` (20 GiB) +**Описание:** Максимальный суммарный размер всех файлов спиллинга на каждом [узле](../../concepts/glossary.md#node). При превышении лимита операции спиллинга завершаются ошибкой. Общий лимит спиллинга во всем кластере равен сумме значений `max_total_size` со всех узлов. + +##### Рекомендации + +- Устанавливайте значение исходя из доступного дискового пространства + +##### Возможные ошибки + +- `Total size limit exceeded: X/YMb` — превышен максимальный суммарный размер файлов спиллинга. См. [{#T}](../../troubleshooting/spilling/total-size-limit-exceeded.md) + +### Конфигурация пула потоков + +{% note info %} + +Потоки пула I/O для спиллинга создаются дополнительно к потокам, выделяемым для [акторной системы](../../concepts/glossary.md#actor-system). При планировании количества потоков учитывайте общую нагрузку на систему. + +**Важно:** Пул потоков спиллинга отделен от пулов потоков акторной системы. + +Для получения информации о настройке пулов потоков акторной системы и их влиянии на производительность системы см. [Конфигурация акторной системы](index.md#actor-system) и [Изменение конфигурации акторной системы](../../devops/configuration-management/configuration-v1/change_actorsystem_configs.md). Для Configuration V2 настройки акторной системы описаны в [настройках Configuration V2](../../devops/configuration-management/configuration-v2/config-settings.md). + +{% endnote %} + +#### local_file_config.io_thread_pool.workers_count + +**Тип:** `uint32` +**По умолчанию:** `2` +**Описание:** Количество рабочих потоков для обработки операций ввода-вывода спиллинга. + +##### Рекомендации + +- Увеличивайте для высоконагруженных систем + +##### Возможные ошибки + +- `Can not run operation` — переполнение очереди операций в пуле потоков I/O. См. [{#T}](../../troubleshooting/spilling/can-not-run-operation.md) + +#### local_file_config.io_thread_pool.queue_size + +**Тип:** `uint32` +**По умолчанию:** `1000` +**Описание:** Размер очереди операций спиллинга. Каждая задача отправляет только один блок данных на спиллинг одновременно, поэтому большие значения обычно не требуются. + +##### Возможные ошибки + +- `Can not run operation` — переполнение очереди операций в пуле потоков I/O. См. [{#T}](../../troubleshooting/spilling/can-not-run-operation.md) + +### Управление памятью {#memory-management} + +#### Связь с memory_controller_config + +Активация спиллинга тесно связана с настройками контроллера памяти. Подробная конфигурация `memory_controller_config` описана в [отдельной статье](memory_controller_config.md). + +Ключевым параметром для спиллинга является **`activities_limit_percent`**, который определяет объем памяти, выделяемый для активностей по обработке запросов. От этого параметра зависит доступная память для пользовательских запросов и, соответственно, частота активации спиллинга. + +#### Влияние на спиллинг + +- При увеличении `activities_limit_percent` больше памяти доступно для запросов → спиллинг активируется реже +- При уменьшении `activities_limit_percent` меньше памяти доступно для запросов → спиллинг активируется чаще + +{% note warning %} + +Однако важно учитывать, что сам спиллинг также требует память. Если установить `activities_limit_percent` слишком высоким, память может все равно закончиться несмотря на спиллинг, поскольку механизм спиллинга сам потребляет ресурсы памяти. + +{% endnote %} + +### Требования к файловой системе + +#### Файловые дескрипторы + +{% note info %} + +Для получения информации о настройке лимитов файловых дескрипторов при первоначальном развертывании см. раздел [Лимиты файловых дескрипторов](../../../devops/deployment-options/manual/initial-deployment.html#file-descriptors). + +{% endnote %} + +### Примеры конфигурации + +#### Высоконагруженная система + +Для максимальной производительности в высоконагруженных системах рекомендуется увеличить размер спиллинга и количество рабочих потоков: + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 107374182400 # 100 GiB + io_thread_pool: + workers_count: 8 + queue_size: 2000 +``` + +#### Ограниченные ресурсы + +Для систем с ограниченными ресурсами рекомендуется использовать консервативные настройки: + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + root: "" + max_total_size: 5368709120 # 5 GiB + io_thread_pool: + workers_count: 1 + queue_size: 500 +``` + +### Расширенная конфигурация + +#### Включение и отключение спиллинга + +Следующие параметры управляют включением и отключением различных типов спиллинга. Их следует изменять только при наличии специфических требований системы. + +##### local_file_config.enable + +**Расположение:** `table_service_config.spilling_service_config.local_file_config.enable` +**Тип:** `boolean` +**По умолчанию:** `true` +**Описание:** Включает или отключает сервис спиллинга. При отключении (`false`) [спиллинг](../../concepts/spilling.md) не функционирует, что может привести к ошибкам при обработке больших объемов данных. + +##### Возможные ошибки + +- `Spilling Service not started` / `Service not started` — попытка использования спиллинга при выключенном Spilling Service. См. [{#T}](../../troubleshooting/spilling/service-not-started.md) + +```yaml +table_service_config: + spilling_service_config: + local_file_config: + enable: true +``` + +##### enable_spilling_nodes + +**Расположение:** `table_service_config.enable_spilling_nodes` +**Тип:** `bool` +**По умолчанию:** `true` +**Описание:** Включает спиллинг на узлах базы данных. При отключении (`false`) спиллинг не функционирует на узлах базы данных. + +```yaml +table_service_config: + enable_spilling_nodes: true +``` + +##### enable_query_service_spilling + +**Расположение:** `table_service_config.enable_query_service_spilling` +**Тип:** `boolean` +**По умолчанию:** `true` +**Описание:** Глобальная опция, которая включает транспортный спиллинг при передаче данных между задачами. + +```yaml +table_service_config: + enable_query_service_spilling: true +``` + +{% note info %} + +Эта настройка работает совместно с локальной конфигурацией сервиса спиллинга. При отключении (`false`) транспортный спиллинг не функционирует даже при включенном `spilling_service_config`. + +{% endnote %} + +### Полный пример + +```yaml +table_service_config: + enable_spilling_nodes: true + enable_query_service_spilling: true + spilling_service_config: + local_file_config: + enable: true + root: "/var/spilling" + max_total_size: 53687091200 # 50 GiB + io_thread_pool: + workers_count: 4 + queue_size: 1500 +``` + +## См. также + +- [Концепция спиллинга](../../concepts/spilling.md) +- [Архитектура Spilling Service](../../contributor/spilling-service.md) +- [Устранение неполадок спиллинга](../../troubleshooting/spilling/index.md) +- [Конфигурация контроллера памяти](memory_controller_config.md) +- [Мониторинг {{ ydb-short-name }}](../../devops/observability/monitoring.md) +- [Диагностика производительности](../../troubleshooting/performance/index.md) diff --git a/ydb/docs/ru/core/reference/configuration/toc_p.yaml b/ydb/docs/ru/core/reference/configuration/toc_p.yaml index 9ba30bda53e5..93d48917828b 100644 --- a/ydb/docs/ru/core/reference/configuration/toc_p.yaml +++ b/ydb/docs/ru/core/reference/configuration/toc_p.yaml @@ -3,3 +3,5 @@ items: href: tls.md - name: client_certificate_authorization href: client_certificate_authorization.md +- name: table_service_config + href: table_service_config.md diff --git a/ydb/docs/ru/core/troubleshooting/spilling/can-not-run-operation.md b/ydb/docs/ru/core/troubleshooting/spilling/can-not-run-operation.md new file mode 100644 index 000000000000..5854c367bcac --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/can-not-run-operation.md @@ -0,0 +1,28 @@ +# Can not run operation + +Переполнение очереди операций в пуле потоков I/O. Это происходит, когда очередь пула потоков I/O для спиллинга заполнена и не может принимать новые операции, что приводит к сбою операций спиллинга. + +## Диагностика + +Проверьте конфигурацию и использование пула потоков I/O: + +- Проверьте параметр `queue_size` в конфигурации `io_thread_pool`. +- Проверьте параметр `workers_count` для пула потоков I/O. + +## Рекомендации + +Для решения этой проблемы: + +1. **Увеличьте размер очереди:** + - Увеличьте значение `queue_size` в конфигурации `io_thread_pool`. + - Это позволит поставить в очередь больше операций до возникновения переполнения. + +2. **Увеличьте количество рабочих потоков:** + - Увеличьте значение `workers_count` для более быстрой обработки операций. + - Большее количество рабочих потоков позволит быстрее обрабатывать операции, уменьшая накопление в очереди. + +{% note info %} + +Пул потоков I/O обрабатывает операции спиллинга асинхронно. Если очередь переполняется, новые операции спиллинга будут завершаться сбоем до тех пор, пока не освободится место. + +{% endnote %} diff --git a/ydb/docs/ru/core/troubleshooting/spilling/index.md b/ydb/docs/ru/core/troubleshooting/spilling/index.md new file mode 100644 index 000000000000..733871eb3bf9 --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/index.md @@ -0,0 +1,18 @@ +# Устранение неполадок спиллинга + +Этот раздел предоставляет информацию по устранению неполадок для распространенных проблем со спиллингом в {{ ydb-short-name }}. Спиллинг — это механизм управления памятью, который временно сохраняет промежуточные вычислительные данные на диск при нехватке оперативной памяти. Эти ошибки могут возникать во время выполнения запросов, когда система пытается использовать функциональность спиллинга, и могут наблюдаться в логах и ответах запросов. + +## Частые проблемы + +- [Permission denied](permission-denied.md) - Недостаточные права доступа к директории спиллинга +- [Spilling Service not started](service-not-started.md) - Попытка использования спиллинга при выключенном Spilling Service +- [Total size limit exceeded](total-size-limit-exceeded.md) - Превышен максимальный суммарный размер файлов спиллинга +- [Can not run operation](can-not-run-operation.md) - Переполнение очереди операций в пуле потоков I/O + +## См. также + +- [Конфигурация спиллинга](../../reference/configuration/table_service_config.md) +- [Концепция спиллинга](../../concepts/spilling.md) +- [Конфигурация контроллера памяти](../../reference/configuration/memory_controller_config.md) +- [Мониторинг {{ ydb-short-name }}](../../devops/observability/monitoring.md) +- [Диагностика производительности](../performance/index.md) diff --git a/ydb/docs/ru/core/troubleshooting/spilling/permission-denied.md b/ydb/docs/ru/core/troubleshooting/spilling/permission-denied.md new file mode 100644 index 000000000000..d24e08dca593 --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/permission-denied.md @@ -0,0 +1,26 @@ +# Permission denied + +Недостаточные права доступа к директории спиллинга не позволяют {{ ydb-short-name }} записывать данные на диск во время операций спиллинга. Это может привести к сбою запросов, если для их выполнения требуется спиллинг для обработки больших объемов данных. + +## Диагностика + +Проверьте, существует ли директория спиллинга и имеет ли она правильные права доступа: + +- Убедитесь, что директория спиллинга существует (см. [Конфигурация спиллинга](../../reference/configuration/table_service_config.md#root) для получения информации о том, как найти директорию спиллинга). +- Убедитесь, что директория имеет права на чтение и запись для пользователя, под которым запущен `ydbd`. +- Проверьте права доступа к директории спиллинга. +- Убедитесь, что пользователь, под которым запускается `ydbd`, может читать и записывать данные в директорию. + +## Рекомендации + +Если права доступа заданы неправильно: + +1. Измените владельца директории на пользователя, под которым запускается `ydbd`. +2. Убедитесь, что установлены права на чтение и запись для владельца директории. +3. Перезапустите процесс `ydbd` для применения изменений. + +{% note info %} + +Директория спиллинга автоматически создается {{ ydb-short-name }} при запуске процесса. Если директория не существует, проверьте, что параметр `root` в конфигурации спиллинга установлен правильно. + +{% endnote %} diff --git a/ydb/docs/ru/core/troubleshooting/spilling/service-not-started.md b/ydb/docs/ru/core/troubleshooting/spilling/service-not-started.md new file mode 100644 index 000000000000..7db7364f23c7 --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/service-not-started.md @@ -0,0 +1,21 @@ +# Spilling Service not started + +Попытка использования спиллинга при выключенном Spilling Service. Это происходит, когда сервис спиллинга неправильно настроен или отключен в конфигурации. + +## Диагностика + +Проверьте конфигурацию сервиса спиллинга: + +- Убедитесь, что [`table_service_config.spilling_service_config.local_file_config.enable`](../../reference/configuration/table_service_config.md#local-file-config-enable) установлен в `true`. + +## Рекомендации + +Для включения спиллинга: + +1. Установите [`table_service_config.spilling_service_config.local_file_config.enable`](../../reference/configuration/table_service_config.md#local-file-config-enable): `true` в вашей конфигурации. + +{% note info %} + +Подробнее об архитектуре спиллинга см. в разделе [Архитектура спиллинга в {{ ydb-short-name }}](../../concepts/spilling.md#architecture). + +{% endnote %} diff --git a/ydb/docs/ru/core/troubleshooting/spilling/toc_p.yaml b/ydb/docs/ru/core/troubleshooting/spilling/toc_p.yaml new file mode 100644 index 000000000000..a7c03f45ceeb --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/toc_p.yaml @@ -0,0 +1,9 @@ +items: +- name: Can not run operation + href: can-not-run-operation.md +- name: Permission denied + href: permission-denied.md +- name: Spilling Service not started + href: service-not-started.md +- name: Total size limit exceeded + href: total-size-limit-exceeded.md diff --git a/ydb/docs/ru/core/troubleshooting/spilling/total-size-limit-exceeded.md b/ydb/docs/ru/core/troubleshooting/spilling/total-size-limit-exceeded.md new file mode 100644 index 000000000000..c1d0a57d6dcd --- /dev/null +++ b/ydb/docs/ru/core/troubleshooting/spilling/total-size-limit-exceeded.md @@ -0,0 +1,29 @@ +# Total size limit exceeded + +Превышен максимальный суммарный размер файлов спиллинга (параметр [`max_total_size`](../../reference/configuration/table_service_config.md#local-file-config-max-total-size)). Это происходит, когда общий размер всех файлов спиллинга достигает настроенного лимита, что препятствует новым операциям спиллинга. + +## Диагностика + +Проверьте текущее использование спиллинга: + +- Отслеживайте общий размер файлов спиллинга в директории спиллинга +- Проверьте текущее значение параметра [`max_total_size`](../../reference/configuration/table_service_config.md#local-file-config-max-total-size) +- Просмотрите доступное дисковое пространство в расположении директории спиллинга +- Проверьте, есть ли зависшие файлы спиллинга, которые должны были быть очищены + +## Рекомендации + +Для решения этой проблемы: + +1. **Увеличьте лимит размера спиллинга:** + - Если на диске достаточно свободного места, увеличьте параметр [`max_total_size`](../../reference/configuration/table_service_config.md#local-file-config-max-total-size) в конфигурации + - Рекомендуется увеличить значение на 20-50% от текущего + +2. **Расширьте дисковое пространство:** + - Если свободного места на диске недостаточно, добавьте дополнительное дисковое пространство + - Убедитесь, что директория спиллинга находится на диске с достаточным объемом + +3. **Попробуйте повторить запрос:** + - Дождитесь завершения других ресурсоемких запросов + - Повторите выполнение запроса в менее загруженное время + diff --git a/ydb/docs/ru/core/troubleshooting/toc_p.yaml b/ydb/docs/ru/core/troubleshooting/toc_p.yaml index 29a61848d8da..e28c190b9d7e 100644 --- a/ydb/docs/ru/core/troubleshooting/toc_p.yaml +++ b/ydb/docs/ru/core/troubleshooting/toc_p.yaml @@ -4,3 +4,8 @@ items: include: mode: link path: performance/toc_p.yaml +- name: Проблемы со спиллингом + href: spilling/index.md + include: + mode: link + path: spilling/toc_p.yaml From b210658a8d18d96b86eda98c079aa5c1405b6b45 Mon Sep 17 00:00:00 2001 From: Filitov Mikhail Date: Sun, 14 Sep 2025 14:30:38 +0200 Subject: [PATCH 2/3] fixed links --- ydb/docs/en/core/concepts/spilling.md | 4 ++-- .../en/core/reference/configuration/table_service_config.md | 4 ++-- ydb/docs/en/core/troubleshooting/spilling/index.md | 2 +- ydb/docs/ru/core/concepts/spilling.md | 2 +- .../ru/core/reference/configuration/table_service_config.md | 4 ++-- ydb/docs/ru/core/troubleshooting/spilling/index.md | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ydb/docs/en/core/concepts/spilling.md b/ydb/docs/en/core/concepts/spilling.md index 99578a50fe1c..d478716beb1a 100644 --- a/ydb/docs/en/core/concepts/spilling.md +++ b/ydb/docs/en/core/concepts/spilling.md @@ -75,11 +75,11 @@ The data transfer system continuously monitors its state: ## Interaction with Memory Controller -When executing queries, {{ ydb-short-name }} tries to stay within the memory limit set by the [memory controller](../reference/configuration/memory_controller_config.md). To continue fitting within this limit as intermediate computations grow, spilling is used. For more details, see the [Memory Management section](../reference/configuration/table_service_config.md#memory-management). +When executing queries, {{ ydb-short-name }} tries to stay within the memory limit set by the [memory controller](../reference/configuration/index.md#memory-controller). To continue fitting within this limit as intermediate computations grow, spilling is used. For more details, see the [Memory Management section](../reference/configuration/table_service_config.md#memory-management). ## See Also - [Spilling Service](../contributor/spilling-service.md) - [Spilling configuration](../reference/configuration/table_service_config.md) - [{{ ydb-short-name }} monitoring](../devops/observability/monitoring.md) -- [Performance diagnostics](../troubleshooting/performance/index.md) \ No newline at end of file +- [Performance diagnostics](../troubleshooting/performance/index.md) diff --git a/ydb/docs/en/core/reference/configuration/table_service_config.md b/ydb/docs/en/core/reference/configuration/table_service_config.md index a0d50437408d..f80090d65a6c 100644 --- a/ydb/docs/en/core/reference/configuration/table_service_config.md +++ b/ydb/docs/en/core/reference/configuration/table_service_config.md @@ -118,7 +118,7 @@ For information about configuring actor system thread pools and their impact on #### Relationship with memory_controller_config -Spilling activation is closely related to memory controller settings. Detailed `memory_controller_config` configuration is described in a [separate article](memory_controller_config.md). +Spilling activation is closely related to memory controller settings. Detailed `memory_controller_config` configuration is described in a [separate article](index.md#memory-controller). The key parameter for spilling is **`activities_limit_percent`**, which determines the amount of memory allocated for query processing activities. This parameter affects the available memory for user queries and, accordingly, the frequency of spilling activation. @@ -250,6 +250,6 @@ table_service_config: - [Spilling Concept](../../concepts/spilling.md) - [Spilling Service Architecture](../../contributor/spilling-service.md) - [Spilling Troubleshooting](../../troubleshooting/spilling/index.md) -- [Memory Controller Configuration](memory_controller_config.md) +- [Memory Controller Configuration](index.md#memory-controller) - [{{ ydb-short-name }} Monitoring](../../devops/observability/monitoring.md) - [Performance Diagnostics](../../troubleshooting/performance/index.md) diff --git a/ydb/docs/en/core/troubleshooting/spilling/index.md b/ydb/docs/en/core/troubleshooting/spilling/index.md index 6170ce9ed324..5edc8ffbac8d 100644 --- a/ydb/docs/en/core/troubleshooting/spilling/index.md +++ b/ydb/docs/en/core/troubleshooting/spilling/index.md @@ -13,6 +13,6 @@ This section provides troubleshooting information for common spilling issues in - [Spilling Configuration](../../reference/configuration/table_service_config.md) - [Spilling Concept](../../concepts/spilling.md) -- [Memory Controller Configuration](../../reference/configuration/memory_controller_config.md) +- [Memory Controller Configuration](../../reference/configuration/index.md#memory-controller) - [{{ ydb-short-name }} Monitoring](../../devops/observability/monitoring.md) - [Performance Diagnostics](../performance/index.md) diff --git a/ydb/docs/ru/core/concepts/spilling.md b/ydb/docs/ru/core/concepts/spilling.md index 2ee0ad1faa79..f5869aa31044 100644 --- a/ydb/docs/ru/core/concepts/spilling.md +++ b/ydb/docs/ru/core/concepts/spilling.md @@ -74,7 +74,7 @@ ## Взаимодействие с контроллером памяти -При выполнении запросов {{ ydb-short-name }} старается умещаться в заданный лимит памяти, который устанавливается [контроллером памяти](../reference/configuration/memory_controller_config.md). Чтобы продолжать помещаться в этот лимит даже при росте промежуточных вычислений, используется спиллинг. Подробнее см. раздел [Управление памятью](../reference/configuration/table_service_config.md#memory-management). +При выполнении запросов {{ ydb-short-name }} старается умещаться в заданный лимит памяти, который устанавливается [контроллером памяти](../reference/configuration/index.md#memory-controller). Чтобы продолжать помещаться в этот лимит даже при росте промежуточных вычислений, используется спиллинг. Подробнее см. раздел [Управление памятью](../reference/configuration/table_service_config.md#memory-management). ## См. также diff --git a/ydb/docs/ru/core/reference/configuration/table_service_config.md b/ydb/docs/ru/core/reference/configuration/table_service_config.md index 9a359501b742..13cf03d72575 100644 --- a/ydb/docs/ru/core/reference/configuration/table_service_config.md +++ b/ydb/docs/ru/core/reference/configuration/table_service_config.md @@ -118,7 +118,7 @@ table_service_config: #### Связь с memory_controller_config -Активация спиллинга тесно связана с настройками контроллера памяти. Подробная конфигурация `memory_controller_config` описана в [отдельной статье](memory_controller_config.md). +Активация спиллинга тесно связана с настройками контроллера памяти. Подробная конфигурация `memory_controller_config` описана в [отдельной статье](index.md#memory-controller). Ключевым параметром для спиллинга является **`activities_limit_percent`**, который определяет объем памяти, выделяемый для активностей по обработке запросов. От этого параметра зависит доступная память для пользовательских запросов и, соответственно, частота активации спиллинга. @@ -250,6 +250,6 @@ table_service_config: - [Концепция спиллинга](../../concepts/spilling.md) - [Архитектура Spilling Service](../../contributor/spilling-service.md) - [Устранение неполадок спиллинга](../../troubleshooting/spilling/index.md) -- [Конфигурация контроллера памяти](memory_controller_config.md) +- [Конфигурация контроллера памяти](index.md#memory-controller) - [Мониторинг {{ ydb-short-name }}](../../devops/observability/monitoring.md) - [Диагностика производительности](../../troubleshooting/performance/index.md) diff --git a/ydb/docs/ru/core/troubleshooting/spilling/index.md b/ydb/docs/ru/core/troubleshooting/spilling/index.md index 733871eb3bf9..763428836187 100644 --- a/ydb/docs/ru/core/troubleshooting/spilling/index.md +++ b/ydb/docs/ru/core/troubleshooting/spilling/index.md @@ -13,6 +13,6 @@ - [Конфигурация спиллинга](../../reference/configuration/table_service_config.md) - [Концепция спиллинга](../../concepts/spilling.md) -- [Конфигурация контроллера памяти](../../reference/configuration/memory_controller_config.md) +- [Конфигурация контроллера памяти](../../reference/configuration/index.md#memory-controller) - [Мониторинг {{ ydb-short-name }}](../../devops/observability/monitoring.md) - [Диагностика производительности](../performance/index.md) From 0b3ce4779a0153a556fb898bc5039b77dcb508f4 Mon Sep 17 00:00:00 2001 From: Filitov Mikhail Date: Sun, 14 Sep 2025 14:44:16 +0200 Subject: [PATCH 3/3] remove redundand --- .../configuration/memory_controller_config.md | 121 ------------------ .../configuration/memory_controller_config.md | 121 ------------------ 2 files changed, 242 deletions(-) delete mode 100644 ydb/docs/en/core/reference/configuration/memory_controller_config.md delete mode 100644 ydb/docs/ru/core/reference/configuration/memory_controller_config.md diff --git a/ydb/docs/en/core/reference/configuration/memory_controller_config.md b/ydb/docs/en/core/reference/configuration/memory_controller_config.md deleted file mode 100644 index d0b5e0821caf..000000000000 --- a/ydb/docs/en/core/reference/configuration/memory_controller_config.md +++ /dev/null @@ -1,121 +0,0 @@ -# memory_controller_config - -There are many components inside {{ ydb-short-name }} [database nodes](../../concepts/glossary.md#database-node) that utilize memory. Most of them need a fixed amount, but some are flexible and can use varying amounts of memory, typically to improve performance. If {{ ydb-short-name }} components allocate more memory than is physically available, the operating system is likely to [terminate](https://en.wikipedia.org/wiki/Out_of_memory#Recovery) the entire {{ ydb-short-name }} process, which is undesirable. The memory controller's goal is to allow {{ ydb-short-name }} to avoid out-of-memory situations while still efficiently using the available memory. - -Examples of components managed by the memory controller: - -- [Shared cache](../../concepts/glossary.md#shared-cache): stores recently accessed data pages read from [distributed storage](../../concepts/glossary.md#distributed-storage) to reduce disk I/O and accelerate data retrieval. -- [MemTable](../../concepts/glossary.md#memtable): holds data that has not yet been flushed to [SST](../../concepts/glossary.md#sst). -- [KQP](../../concepts/glossary.md#kqp): stores intermediate query results. -- Allocator caches: keep memory blocks that have been released but not yet returned to the operating system. - -Memory limits can be configured to control overall memory usage, ensuring the database operates efficiently within the available resources. - -## Hard Memory Limit {#hard-memory-limit} - -The hard memory limit specifies the total amount of memory available to the {{ ydb-short-name }} process. - -By default, the hard memory limit for the {{ ydb-short-name }} process is set to its [cgroups](https://en.wikipedia.org/wiki/Cgroups) memory limit. - -In environments without a cgroups memory limit, the default hard memory limit equals the host's total available memory. This configuration allows the database to utilize all available resources but may lead to resource competition with other processes on the same host. Although the memory controller attempts to account for this external consumption, such a setup is not recommended. - -Additionally, the hard memory limit can be specified in the configuration. Note that the database process may still exceed this limit. Therefore, it is highly recommended to use cgroups memory limits in production environments to enforce strict memory control. - -Most of other memory limits can be configured either in absolute bytes or as a percentage relative to the hard memory limit. Using percentages is advantageous for managing clusters with nodes of varying capacities. If both absolute byte and percentage limits are specified, the memory controller uses a combination of both (maximum for lower limits and minimum for upper limits). - -Example of the `memory_controller_config` section with a specified hard memory limit: - -```yaml -memory_controller_config: - hard_limit_bytes: 16106127360 -``` - -## Soft Memory Limit {#soft-memory-limit} - -The soft memory limit specifies a dangerous threshold that should not be exceeded by the {{ ydb-short-name }} process under normal circumstances. - -If the soft limit is exceeded, {{ ydb-short-name }} gradually reduces the [shared cache](../../concepts/glossary.md#shared-cache) size to zero. Therefore, more database nodes should be added to the cluster as soon as possible, or per-component memory limits should be reduced. - -## Target Memory Utilization {#target-memory-utilization} - -The target memory utilization specifies a threshold for the {{ ydb-short-name }} process memory usage that is considered optimal. - -Flexible cache sizes are calculated according to their limit thresholds to keep process consumption around this value. - -For example, in a database that consumes a little memory on query execution, caches consume memory around this threshold, and other memory stays free. If query execution consumes more memory, caches start to reduce their sizes to their minimum threshold. - -## Per-Component Memory Limits - -There are two different types of components within {{ ydb-short-name }}. - -The first type, known as cache components, functions as caches, for example, by storing the most recently used data. Each cache component has minimum and maximum memory limit thresholds, allowing them to adjust their capacity dynamically based on the current {{ ydb-short-name }} process consumption. - -The second type, known as activity components, allocates memory for specific activities, such as query execution or the [compaction](../../concepts/glossary.md#compaction) process. Each activity component has a fixed memory limit. Additionally, there is a total memory limit for these activities from which they attempt to draw the required memory. - -Many other auxiliary components and processes operate alongside the {{ ydb-short-name }} process, consuming memory. Currently, these components do not have any memory limits. - -### Cache Components Memory Limits - -The cache components include: - -- Shared cache -- MemTable - -Each cache component's limits are dynamically recalculated every second to ensure that each component consumes memory proportionally to its limit thresholds while the total consumed memory stays close to the target memory utilization. - -The minimum memory limit threshold for cache components isn't reserved, meaning the memory remains available until it is actually used. However, once this memory is filled, the components typically retain the data, operating within their current memory limit. Consequently, the sum of the minimum memory limits for cache components is expected to be less than the target memory utilization. - -If needed, both the minimum and maximum thresholds should be overridden; otherwise, any missing threshold will have a default value. - -Example of the `memory_controller_config` section with specified shared cache limits: - -```yaml -memory_controller_config: - shared_cache_min_percent: 10 - shared_cache_max_percent: 30 -``` - -### Activity Components Memory Limits - -The activity components include: - -- KQP - -The memory limit for each activity component specifies the maximum amount of memory it can attempt to use. However, to prevent the {{ ydb-short-name }} process from exceeding the soft memory limit, the total consumption of activity components is further constrained by an additional limit known as the activities memory limit. If the total memory usage of the activity components exceeds this limit, any additional memory requests will be denied. When query execution approaches memory limits, {{ ydb-short-name }} activates [spilling](../../concepts/spilling.md) to temporarily save intermediate data to disk, preventing memory limit violations. - -As a result, while the combined individual limits of the activity components might collectively exceed the activities memory limit, each component's individual limit should be less than this overall cap. Additionally, the sum of the minimum memory limits for the cache components, plus the activities memory limit, must be less than the soft memory limit. - -There are some other activity components that currently do not have individual memory limits. - -Example of the `memory_controller_config` section with a specified KQP limit: - -```yaml -memory_controller_config: - query_execution_limit_percent: 25 -``` - -## Configuration Parameters - -Each configuration parameter applies within the context of a single database node. - -As mentioned above, the sum of the minimum memory limits for the cache components plus the activities memory limit should be less than the soft memory limit. - -This restriction can be expressed in a simplified form: - -$shared\_cache\_min\_percent + mem\_table\_min\_percent + activities\_limit\_percent < soft\_limit\_percent$ - -Or in a detailed form: - -$Max(shared\_cache\_min\_percent * hard\_limit\_bytes / 100, shared\_cache\_min\_bytes) + Max(mem\_table\_min\_percent * hard\_limit\_bytes / 100, mem\_table\_min\_bytes) + Min(activities\_limit\_percent * hard\_limit\_bytes / 100, activities\_limit\_bytes) < Min(soft\_limit\_percent * hard\_limit\_bytes / 100, soft\_limit\_bytes)$ - -| Parameter | Default | Description | -| --- | --- | --- | -| `hard_limit_bytes` | CGroup memory limit /
Host memory | Hard memory usage limit. | -| `soft_limit_percent` /
`soft_limit_bytes` | 75% | Soft memory usage limit. | -| `target_utilization_percent` /
`target_utilization_bytes` | 50% | Target memory utilization. | -| `activities_limit_percent` /
`activities_limit_bytes` | 30% | Activities memory limit. | -| `shared_cache_min_percent` /
`shared_cache_min_bytes` | 20% | Minimum threshold for the shared cache memory limit. | -| `shared_cache_max_percent` /
`shared_cache_max_bytes` | 50% | Maximum threshold for the shared cache memory limit. | -| `mem_table_min_percent` /
`mem_table_min_bytes` | 1% | Minimum threshold for the MemTable memory limit. | -| `mem_table_max_percent` /
`mem_table_max_bytes` | 3% | Maximum threshold for the MemTable memory limit. | -| `query_execution_limit_percent` /
`query_execution_limit_bytes` | 20% | KQP memory limit. | diff --git a/ydb/docs/ru/core/reference/configuration/memory_controller_config.md b/ydb/docs/ru/core/reference/configuration/memory_controller_config.md deleted file mode 100644 index 97ada99b4588..000000000000 --- a/ydb/docs/ru/core/reference/configuration/memory_controller_config.md +++ /dev/null @@ -1,121 +0,0 @@ -# memory_controller_config - -Внутри [узлов](../../concepts/glossary.md#database-node) {{ ydb-short-name }} работают множество различных компонентов, использующих память. Большинству из них требуется фиксированное количество памяти, но некоторые из них могут гибко варьировать объём используемой памяти, тем самым улучшая производительность всей системы. Если компоненты {{ ydb-short-name }} выделяют больше памяти, чем физически доступно, операционная система, вероятно, [завершит](https://en.wikipedia.org/wiki/Out_of_memory#Recovery) весь процесс {{ ydb-short-name }}, что крайне нежелательно. Цель контроллера памяти — позволить {{ ydb-short-name }} избегать ситуаций с нехваткой памяти, при этом эффективно используя имеющийся её объём. - -Примеры компонентов, управляемых контроллером памяти: - -- [Общий кеш](../../concepts/glossary.md#shared-cache): хранит недавно доступные страницы данных, считанные из [распределённого хранилища](../../concepts/glossary.md#distributed-storage), чтобы уменьшить количество операций ввода-вывода с диска и ускорить получение данных. -- [MemTable](../../concepts/glossary.md#memtable): содержит данные, которые ещё не были записаны в [SST](../../concepts/glossary.md#sst). -- [KQP](../../concepts/glossary.md#kqp): хранит промежуточные результаты обработки запросов. -- Кеши аллокатора: хранят блоки памяти, которые были освобождены, но ещё не возвращены операционной системе. - -Лимиты памяти могут быть настроены для контроля общего использования памяти, обеспечивая эффективную работу базы данных в рамках доступных ресурсов. - -## Жёсткий лимит памяти {#hard-memory-limit} - -Жёсткий лимит памяти определяет общее количество памяти, доступное для процесса {{ ydb-short-name }}. - -По умолчанию жёсткий лимит памяти для процесса {{ ydb-short-name }} равен лимиту памяти, указанному в его [cgroups](https://en.wikipedia.org/wiki/Cgroups). - -В окружениях без лимита памяти cgroups значение жёсткого лимита памяти по умолчанию равно общему объёму доступной памяти хоста. Эта конфигурация позволяет базе данных использовать все доступные ресурсы, но может привести к конкуренции за ресурсы с другими процессами на том же хосте. Хотя контроллер памяти пытается учесть это внешнее потребление, такое использование не рекомендуется. - -Жёсткий лимит памяти также может быть задан в конфигурации. Обратите внимание, что процесс базы данных всё равно может превысить этот лимит. Поэтому настоятельно рекомендуется использовать лимиты памяти cgroups в производственных окружениях для строгого контроля памяти. - -Большинство других лимитов памяти можно настроить либо в абсолютных байтах, либо в процентах относительно жёсткого лимита памяти. Использование процентов удобно для управления кластерами с узлами разной ёмкости. Если указаны как абсолютные лимиты в байтах, так и процентные лимиты, контроллер памяти использует комбинацию обоих (максимум для нижних лимитов и минимум для верхних лимитов). - -Пример секции `memory_controller_config` с указанным жёстким лимитом памяти: - -```yaml -memory_controller_config: - hard_limit_bytes: 16106127360 -``` - -## Мягкий лимит памяти {#soft-memory-limit} - -Мягкий лимит памяти определяет опасный порог, который процесс {{ ydb-short-name }} не должен превышать при нормальных обстоятельствах. - -Если мягкий лимит превышен, {{ ydb-short-name }} постепенно уменьшает размер [общего кеша](../../concepts/glossary.md#shared-cache) до нуля. В таком случае следует как можно скорее добавить больше узлов баз данных в кластер или снизить лимиты памяти для отдельных компонентов. - -## Целевое использование памяти {#target-memory-utilization} - -Целевое использование памяти определяет порог использования памяти процессом {{ ydb-short-name }}, который считается оптимальным. - -Гибкие размеры кешей рассчитываются в соответствии с их пределами, чтобы поддерживать потребление памяти процессом вблизи этого значения. - -Например, в базе данных, которая расходует немного памяти на выполнение запросов, кеши используют память вблизи этого порога, а остальная память остаётся свободной. Если выполнение запросов начинает потреблять больше памяти, кеши начинают сокращать свои размеры до минимального порога. - -## Лимиты памяти для отдельных компонентов - -Внутри {{ ydb-short-name }} существует два разных типа компонентов. - -Первый тип компонентов, или кеш-компоненты, функционируют как кеши, например, храня последние использованные данные. Каждый кеш-компонент имеет минимальный и максимальный пороговые значения лимита памяти, что позволяет ему динамически изменять свою ёмкость в зависимости от текущего потребления памяти процессом {{ ydb-short-name }}. - -Второй тип компонентов, или компоненты-активности, выделяют память для конкретных задач, таких как выполнение запросов или процесс компактизации. Каждый компонент-активность имеет фиксированный лимит памяти. Также существует дополнительный общий лимит памяти для таких компонентов, из которого они пытаются получить необходимую память. - -Многие другие вспомогательные компоненты и процессы работают параллельно с процессом {{ ydb-short-name }}, потребляя память. В настоящее время эти компоненты не имеют каких-либо лимитов памяти. - -### Лимиты памяти для кеш-компонентов - -К кеш-компонентам относятся: - -- Общий кеш; -- MemTable. - -Лимиты каждого кеш-компонента динамически пересчитываются каждую секунду, чтобы каждый компонент потреблял память пропорционально своим предельным значениям, а общее потребление памяти оставалось около целевого использования памяти. - -Минимальный порог лимита памяти кеш-компонентов не резервируется, что означает, что память остаётся доступной до тех пор, пока она не будет фактически использована. Однако, как только эта память заполнена, компоненты обычно сохраняют данные, действуя в рамках своего текущего лимита памяти. Таким образом, ожидается, что сумма минимальных лимитов памяти кеш-компонентов будет меньше целевого использования памяти. - -При необходимости следует переопределить как минимальные, так и максимальные пороговые значения; в противном случае, если пороговое значение отсутствует, оно будет иметь значение по умолчанию. - -Пример секции `memory_controller_config` с указанными лимитами общего кеша: - -```yaml -memory_controller_config: - shared_cache_min_percent: 10 - shared_cache_max_percent: 30 -``` - -### Лимиты памяти для компонентов-активностей - -К компонентам-активностям относятся: - -- KQP. - -Лимит памяти для каждого из компонентов-активностей указывает максимальное количество памяти, которое он может попытаться использовать. Однако, чтобы предотвратить превышение процессом {{ ydb-short-name }} мягкого лимита памяти, общее потребление компонентов-активностей ограничивается дополнительным лимитом, называемым лимитом памяти для активностей. Если общее использование памяти активными компонентами превышает этот лимит, любые дополнительные запросы на память будут отклонены. Когда выполнение запросов приближается к лимитам памяти, {{ ydb-short-name }} активирует [спиллинг](../../concepts/spilling.md) для временного сохранения промежуточных данных на диск, предотвращая нарушение лимитов памяти. - -Таким образом, хотя суммарные индивидуальные лимиты компонентов-активностей могут в совокупности превышать лимит памяти для активностей, индивидуальный лимит каждого компонента должен быть меньше этого общего предела. Кроме того, сумма минимальных лимитов памяти для кеш-компонентов плюс лимит памяти для активностей должна быть меньше мягкого лимита памяти. - -Существуют и другие компоненты-активности, которые в настоящее время не имеют каких-либо индивидуальных лимитов памяти. - -Пример секции `memory_controller_config` с указанным лимитом для KQP: - -```yaml -memory_controller_config: - query_execution_limit_percent: 25 -``` - -## Параметры конфигурации - -Каждый параметр конфигурации применяется в контексте одного узла базы данных. - -Как упоминалось ранее, ожидается, что сумма минимальных лимитов памяти для кеш-компонентов плюс лимит памяти для активностей должна быть меньше мягкого лимита памяти. - -Это ограничение можно выразить в упрощённой форме: - -$shared\_cache\_min\_percent + mem\_table\_min\_percent + activities\_limit\_percent < soft\_limit\_percent$ - -Или в детализированной форме: - -$Max(shared\_cache\_min\_percent * hard\_limit\_bytes / 100, shared\_cache\_min\_bytes) + Max(mem\_table\_min\_percent * hard\_limit\_bytes / 100, mem\_table\_min\_bytes) + Min(activities\_limit\_percent * hard\_limit\_bytes / 100, activities\_limit\_bytes) < Min(soft\_limit\_percent * hard\_limit\_bytes / 100, soft\_limit\_bytes)$ - -| Параметры | Значение по умолчанию | Описание | -| --- | --- | --- | -| `hard_limit_bytes` | CGroup memory limit /
Память хоста | Жёсткий лимит использования памяти. | -| `soft_limit_percent` /
`soft_limit_bytes` | 75% | Мягкий лимит использования памяти. | -| `target_utilization_percent` /
`target_utilization_bytes` | 50% | Целевое использование памяти. | -| `activities_limit_percent` /
`activities_limit_bytes` | 30% | Лимит памяти для активностей. | -| `shared_cache_min_percent` /
`shared_cache_min_bytes` | 20% | Минимальный порог для лимита памяти общего кеша. | -| `shared_cache_max_percent` /
`shared_cache_max_bytes` | 50% | Максимальный порог для лимита памяти общего кеша. | -| `mem_table_min_percent` /
`mem_table_min_bytes` | 1% | Минимальный порог для лимита памяти MemTable. | -| `mem_table_max_percent` /
`mem_table_max_bytes` | 3% | Максимальный порог для лимита памяти MemTable. | -| `query_execution_limit_percent` /
`query_execution_limit_bytes` | 20% | Лимит памяти для KQP. |