github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/docs/blocks-storage/compactor.md (about)

     1  ---
     2  title: "Compactor"
     3  linkTitle: "Compactor"
     4  weight: 4
     5  slug: compactor
     6  ---
     7  
     8  <!-- DO NOT EDIT THIS FILE - This file has been automatically generated from its .template -->
     9  
    10  The **compactor** is an service which is responsible to:
    11  
    12  - Compact multiple blocks of a given tenant into a single optimized larger block. This helps to reduce storage costs (deduplication, index size reduction), and increase query speed (querying fewer blocks is faster).
    13  - Keep the per-tenant bucket index updated. The [bucket index](./bucket-index.md) is used by [queriers](./querier.md), [store-gateways](./store-gateway.md) and rulers to discover new blocks in the storage.
    14  
    15  The compactor is **stateless**.
    16  
    17  ## How compaction works
    18  
    19  The blocks compaction has two main benefits:
    20  
    21  1. Vertically compact blocks uploaded by all ingesters for the same time range
    22  2. Horizontally compact blocks with small time ranges into a single larger block
    23  
    24  The **vertical compaction** merges all the blocks of a tenant uploaded by ingesters for the same time range (2 hours ranges by default) into a single block, while **de-duplicating samples** that are originally written to N blocks as a result of replication. This step reduces number of blocks for single 2 hours time range from #(number of ingesters) to 1 per tenant.
    25  
    26  The **horizontal compaction** triggers after the vertical compaction and compacts several blocks with adjacent 2-hour range periods into a single larger block. Even though the total size of block chunks doesn't change after this compaction, it may still significantly reduce the size of the index and the index-header kept in memory by store-gateways.
    27  
    28  ![Compactor - horizontal and vertical compaction](/images/blocks-storage/compactor-horizontal-and-vertical-compaction.png)
    29  
    30  <!-- Diagram source at https://docs.google.com/presentation/d/1bHp8_zcoWCYoNU2AhO2lSagQyuIrghkCncViSqn14cU/edit -->
    31  
    32  ## Compactor sharding
    33  
    34  The compactor optionally supports sharding.
    35  
    36  When sharding is enabled, multiple compactor instances can coordinate to split the workload and shard blocks by tenant. All the blocks of a tenant are processed by a single compactor instance at any given time, but compaction for different tenants may simultaneously run on different compactor instances.
    37  
    38  Whenever the pool of compactors increase or decrease (ie. following up a scale up/down), tenants are resharded across the available compactor instances without any manual intervention.
    39  
    40  The compactor sharding is based on the Cortex [hash ring](../architecture.md#the-hash-ring). At startup, a compactor generates random tokens and registers itself to the ring. While running, it periodically scans the storage bucket (every `-compactor.compaction-interval`) to discover the list of tenants in the storage and compacts blocks for each tenant whose hash matches the token ranges assigned to the instance itself within the ring.
    41  
    42  This feature can be enabled via `-compactor.sharding-enabled=true` and requires the backend [hash ring](../architecture.md#the-hash-ring) to be configured via `-compactor.ring.*` flags (or their respective YAML config options).
    43  
    44  ### Waiting for stable ring at startup
    45  
    46  In the event of a cluster cold start or scale up of 2+ compactor instances at the same time we may end up in a situation where each new compactor instance starts at a slightly different time and thus each one runs the first compaction based on a different state of the ring. This is not a critical condition, but may be inefficient, because multiple compactor replicas may start compacting the same tenant nearly at the same time.
    47  
    48  To reduce the likelihood this could happen, the compactor waits for a stable ring at startup. A ring is considered stable if no instance is added/removed to the ring for at least `-compactor.ring.wait-stability-min-duration`. If the ring keep getting changed after `-compactor.ring.wait-stability-max-duration`, the compactor will stop waiting for a stable ring and will proceed starting up normally.
    49  
    50  To disable this waiting logic, you can start the compactor with `-compactor.ring.wait-stability-min-duration=0`.
    51  
    52  ## Soft and hard blocks deletion
    53  
    54  When the compactor successfully compacts some source blocks into a larger block, source blocks are deleted from the storage. Blocks deletion is not immediate, but follows a two steps process:
    55  
    56  1. First, a block is **marked for deletion** (soft delete)
    57  2. Then, once a block is marked for deletion for longer then `-compactor.deletion-delay`, the block is **deleted** from the storage (hard delete)
    58  
    59  The compactor is both responsible to mark blocks for deletion and then hard delete them once the deletion delay expires.
    60  The soft deletion is based on a tiny `deletion-mark.json` file stored within the block location in the bucket which gets looked up both by queriers and store-gateways.
    61  
    62  This soft deletion mechanism is used to give enough time to queriers and store-gateways to discover the new compacted blocks before the old source blocks are deleted. If source blocks would be immediately hard deleted by the compactor, some queries involving the compacted blocks may fail until the queriers and store-gateways haven't rescanned the bucket and found both deleted source blocks and the new compacted ones.
    63  
    64  ## Compactor disk utilization
    65  
    66  The compactor needs to download source blocks from the bucket to the local disk, and store the compacted block to the local disk before uploading it to the bucket. Depending on the largest tenants in your cluster and the configured `-compactor.block-ranges`, the compactor may need a lot of disk space.
    67  
    68  Assuming `max_compaction_range_blocks_size` is the total size of blocks for the largest tenant (you can measure it inspecting the bucket) and the longest `-compactor.block-ranges` period, the formula to estimate the minimum disk space required is:
    69  
    70  ```
    71  min_disk_space_required = compactor.compaction-concurrency * max_compaction_range_blocks_size * 2
    72  ```
    73  
    74  Alternatively, assuming the largest `-compactor.block-ranges` is `24h` (default), you could consider 150GB of disk space every 10M active series owned by the largest tenant. For example, if your largest tenant has 30M active series and `-compactor.compaction-concurrency=1` we would recommend having a disk with at least 450GB available.
    75  
    76  ## Compactor HTTP endpoints
    77  
    78  - `GET /compactor/ring`<br />
    79    Displays the status of the compactors ring, including the tokens owned by each compactor and an option to remove (forget) instances from the ring.
    80  
    81  ## Compactor configuration
    82  
    83  This section described the compactor configuration. For the general Cortex configuration and references to common config blocks, please refer to the [configuration documentation](../configuration/config-file-reference.md).
    84  
    85  ### `compactor_config`
    86  
    87  The `compactor_config` configures the compactor for the blocks storage.
    88  
    89  ```yaml
    90  compactor:
    91    # List of compaction time ranges.
    92    # CLI flag: -compactor.block-ranges
    93    [block_ranges: <list of duration> | default = 2h0m0s,12h0m0s,24h0m0s]
    94  
    95    # Number of Go routines to use when syncing block index and chunks files from
    96    # the long term storage.
    97    # CLI flag: -compactor.block-sync-concurrency
    98    [block_sync_concurrency: <int> | default = 20]
    99  
   100    # Number of Go routines to use when syncing block meta files from the long
   101    # term storage.
   102    # CLI flag: -compactor.meta-sync-concurrency
   103    [meta_sync_concurrency: <int> | default = 20]
   104  
   105    # Minimum age of fresh (non-compacted) blocks before they are being processed.
   106    # Malformed blocks older than the maximum of consistency-delay and 48h0m0s
   107    # will be removed.
   108    # CLI flag: -compactor.consistency-delay
   109    [consistency_delay: <duration> | default = 0s]
   110  
   111    # Data directory in which to cache blocks and process compactions
   112    # CLI flag: -compactor.data-dir
   113    [data_dir: <string> | default = "./data"]
   114  
   115    # The frequency at which the compaction runs
   116    # CLI flag: -compactor.compaction-interval
   117    [compaction_interval: <duration> | default = 1h]
   118  
   119    # How many times to retry a failed compaction within a single compaction run.
   120    # CLI flag: -compactor.compaction-retries
   121    [compaction_retries: <int> | default = 3]
   122  
   123    # Max number of concurrent compactions running.
   124    # CLI flag: -compactor.compaction-concurrency
   125    [compaction_concurrency: <int> | default = 1]
   126  
   127    # How frequently compactor should run blocks cleanup and maintenance, as well
   128    # as update the bucket index.
   129    # CLI flag: -compactor.cleanup-interval
   130    [cleanup_interval: <duration> | default = 15m]
   131  
   132    # Max number of tenants for which blocks cleanup and maintenance should run
   133    # concurrently.
   134    # CLI flag: -compactor.cleanup-concurrency
   135    [cleanup_concurrency: <int> | default = 20]
   136  
   137    # Time before a block marked for deletion is deleted from bucket. If not 0,
   138    # blocks will be marked for deletion and compactor component will permanently
   139    # delete blocks marked for deletion from the bucket. If 0, blocks will be
   140    # deleted straight away. Note that deleting blocks immediately can cause query
   141    # failures.
   142    # CLI flag: -compactor.deletion-delay
   143    [deletion_delay: <duration> | default = 12h]
   144  
   145    # For tenants marked for deletion, this is time between deleting of last
   146    # block, and doing final cleanup (marker files, debug files) of the tenant.
   147    # CLI flag: -compactor.tenant-cleanup-delay
   148    [tenant_cleanup_delay: <duration> | default = 6h]
   149  
   150    # When enabled, at compactor startup the bucket will be scanned and all found
   151    # deletion marks inside the block location will be copied to the markers
   152    # global location too. This option can (and should) be safely disabled as soon
   153    # as the compactor has successfully run at least once.
   154    # CLI flag: -compactor.block-deletion-marks-migration-enabled
   155    [block_deletion_marks_migration_enabled: <boolean> | default = true]
   156  
   157    # Comma separated list of tenants that can be compacted. If specified, only
   158    # these tenants will be compacted by compactor, otherwise all tenants can be
   159    # compacted. Subject to sharding.
   160    # CLI flag: -compactor.enabled-tenants
   161    [enabled_tenants: <string> | default = ""]
   162  
   163    # Comma separated list of tenants that cannot be compacted by this compactor.
   164    # If specified, and compactor would normally pick given tenant for compaction
   165    # (via -compactor.enabled-tenants or sharding), it will be ignored instead.
   166    # CLI flag: -compactor.disabled-tenants
   167    [disabled_tenants: <string> | default = ""]
   168  
   169    # Shard tenants across multiple compactor instances. Sharding is required if
   170    # you run multiple compactor instances, in order to coordinate compactions and
   171    # avoid race conditions leading to the same tenant blocks simultaneously
   172    # compacted by different instances.
   173    # CLI flag: -compactor.sharding-enabled
   174    [sharding_enabled: <boolean> | default = false]
   175  
   176    sharding_ring:
   177      kvstore:
   178        # Backend storage to use for the ring. Supported values are: consul, etcd,
   179        # inmemory, memberlist, multi.
   180        # CLI flag: -compactor.ring.store
   181        [store: <string> | default = "consul"]
   182  
   183        # The prefix for the keys in the store. Should end with a /.
   184        # CLI flag: -compactor.ring.prefix
   185        [prefix: <string> | default = "collectors/"]
   186  
   187        # The consul_config configures the consul client.
   188        # The CLI flags prefix for this block config is: compactor.ring
   189        [consul: <consul_config>]
   190  
   191        # The etcd_config configures the etcd client.
   192        # The CLI flags prefix for this block config is: compactor.ring
   193        [etcd: <etcd_config>]
   194  
   195        multi:
   196          # Primary backend storage used by multi-client.
   197          # CLI flag: -compactor.ring.multi.primary
   198          [primary: <string> | default = ""]
   199  
   200          # Secondary backend storage used by multi-client.
   201          # CLI flag: -compactor.ring.multi.secondary
   202          [secondary: <string> | default = ""]
   203  
   204          # Mirror writes to secondary store.
   205          # CLI flag: -compactor.ring.multi.mirror-enabled
   206          [mirror_enabled: <boolean> | default = false]
   207  
   208          # Timeout for storing value to secondary store.
   209          # CLI flag: -compactor.ring.multi.mirror-timeout
   210          [mirror_timeout: <duration> | default = 2s]
   211  
   212      # Period at which to heartbeat to the ring. 0 = disabled.
   213      # CLI flag: -compactor.ring.heartbeat-period
   214      [heartbeat_period: <duration> | default = 5s]
   215  
   216      # The heartbeat timeout after which compactors are considered unhealthy
   217      # within the ring. 0 = never (timeout disabled).
   218      # CLI flag: -compactor.ring.heartbeat-timeout
   219      [heartbeat_timeout: <duration> | default = 1m]
   220  
   221      # Minimum time to wait for ring stability at startup. 0 to disable.
   222      # CLI flag: -compactor.ring.wait-stability-min-duration
   223      [wait_stability_min_duration: <duration> | default = 1m]
   224  
   225      # Maximum time to wait for ring stability at startup. If the compactor ring
   226      # keeps changing after this period of time, the compactor will start anyway.
   227      # CLI flag: -compactor.ring.wait-stability-max-duration
   228      [wait_stability_max_duration: <duration> | default = 5m]
   229  
   230      # Name of network interface to read address from.
   231      # CLI flag: -compactor.ring.instance-interface-names
   232      [instance_interface_names: <list of string> | default = [eth0 en0]]
   233  
   234      # Timeout for waiting on compactor to become ACTIVE in the ring.
   235      # CLI flag: -compactor.ring.wait-active-instance-timeout
   236      [wait_active_instance_timeout: <duration> | default = 10m]
   237  ```