Cover image for Clickhouse Server - Troubleshooting

  抽象的

  • 当我们遇到像 CPU 使用率高这样的 Clickhouse 性能问题时,为了调查真正的问题是什么以及如何解决或提供解决方法,我们需要了解 Clickhouse 系统/用户配置属性。

目录

🚀 max_part_loading_threads

ClickHouse启动时读取部件的最大线程数。

  •  可能的值:
      任何正整数。

    默认值:auto(CPU 核心数)。

  • 在启动过程中,ClickHouse 会读取所有表的所有部分(读取包含部分元数据的文件),以在内存中构建所有部分的列表。

    在某些具有大量部件的系统中,此过程可能需要很长时间,并且可以通过增加 max_part_loading_threads 来缩短此时间(如果此过程不受 CPU 和磁盘 I/O 限制)。

  •  查询检查

SELECT *
FROM system.merge_tree_settings
WHERE name = 'max_part_loading_threads'

Query id: 5f8c7c7a-5dec-4e89-88dc-71f06d800e04

┌─name─────────────────────┬─value─────┬─changed─┬─description──────────────────────────────────────────┬─type───────┐
│ max_part_loading_threads │ 'auto(4)' │       0 │ The number of threads to load data parts at startup. │ MaxThreads │
└──────────────────────────┴───────────┴─────────┴──────────────────────────────────────────────────────┴────────────┘

1 rows in set. Elapsed: 0.003 sec. 

🚀 max_part_removal_threads

用于并发删除不活动数据部分的线程数。一个通常就足够了,但在“Google 计算环境 SSD 永久磁盘”中,文件删除(取消链接)操作非常慢,您可能必须增加此数字(建议最多 16 个)。

🚀 number_of_free_entries_in_pool_to_execute_mutation

  • 该属性必须与 background_pool_size 对齐,其值必须 <= background_pool_size 的值
SELECT *
FROM system.merge_tree_settings
WHERE name = 'number_of_free_entries_in_pool_to_execute_mutation'

┌─name───────────────────────────────────────────────┬─value─┬─changed─┬─description──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ number_of_free_entries_in_pool_to_execute_mutation │ 10    │       0 │ When there is less than specified number of free entries in pool, do not execute part mutations. This is to leave free threads for regular merges and avoid "Too many parts" │
└────────────────────────────────────────────────────┴───────┴─────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

🚀 背景池大小

  •   背景池大小

    设置在表引擎中执行后台操作的线程数(例如,MergeTree 引擎表中的合并)。此设置从 ClickHouse 服务器启动时的默认配置文件应用,并且无法在用户会话中更改。

    通过调整此设置,您可以管理 CPU 和磁盘负载。较小的池大小占用较少的 CPU 和磁盘资源,但后台进程进展较慢,最终可能会影响查询性能。

  • 在更改之前,还请查看相关的 MergeTree 设置,例如 number_of_free_entries_in_pool_to_lower_max_size_of_merge 和 number_of_free_entries_in_pool_to_execute_mutation。

  •  可能的值:
      任何正整数。
      默认值:16。

  •  启动日志

2021.08.29 04:22:30.824446 [ 12372 ] {} &lt;Information&gt; BackgroundSchedulePool/BgSchPool: Create BackgroundSchedulePool with 16 threads
2021.08.29 04:22:47.891697 [ 12363 ] {} &lt;Information&gt; Application: Available RAM: 15.08 GiB; physical cores: 4; logical cores: 8.
  • 如何更新这个值,例如。 5

 更新 config.xml

      &lt;merge_tree&gt;
        &lt;number_of_free_entries_in_pool_to_execute_mutation&gt;5&lt;/number_of_free_entries_in_pool_to_execute_mutation&gt;
      &lt;/merge_tree&gt;

 更新 users.xml

    &lt;profiles&gt;
        &lt;default&gt;
            &lt;background_pool_size&gt;5&lt;/background_pool_size&gt;
        &lt;/default&gt;
    &lt;/profiles&gt;

🚀background_schedule_pool_size

  • 背景_计划_池_大小

    设置为复制表、Kafka 流、DNS 缓存更新执行后台任务的线程数。此设置在 ClickHouse 服务器启动时应用,并且无法在用户会话中更改。

  •  可能的值:
      任何正整数。
      默认值:128。

  • 如何更新这个值? - 在用户个人资料 -> 更新 users.xml (如果我们不使用 ReplicatedMergeTree 引擎,则禁用 background_schedule_pool_size

    &lt;profiles&gt;
      &lt;default&gt;
          &lt;background_schedule_pool_size&gt;0&lt;/background_schedule_pool_size&gt;
      &lt;/default&gt;
    &lt;/profiles&gt;
  •  获取池大小
SELECT
    name,
    value
FROM system.settings
WHERE name LIKE '%pool%'

┌─name─────────────────────────────────────────┬─value─┐
│ connection_pool_max_wait_ms                  │ 0     │
│ distributed_connections_pool_size            │ 1024  │
│ background_buffer_flush_schedule_pool_size   │ 16    │
│ background_pool_size                         │ 100   │
│ background_move_pool_size                    │ 8     │
│ background_fetches_pool_size                 │ 8     │
│ background_schedule_pool_size                │ 0     │
│ background_message_broker_schedule_pool_size │ 16    │
│ background_distributed_schedule_pool_size    │ 16    │
└──────────────────────────────────────────────┴───────┘
  • 获取后台池任务
SELECT
    metric,
    value
FROM system.metrics
WHERE metric LIKE 'Background%'

┌─metric──────────────────────────────────┬─value─┐
│ BackgroundPoolTask                      │     0 │
│ BackgroundFetchesPoolTask               │     0 │
│ BackgroundMovePoolTask                  │     0 │
│ BackgroundSchedulePoolTask              │     0 │
│ BackgroundBufferFlushSchedulePoolTask   │     0 │
│ BackgroundDistributedSchedulePoolTask   │     0 │
│ BackgroundMessageBrokerSchedulePoolTask │     0 │
└─────────────────────────────────────────┴───────┘
  •  获取 BgSchPool
# ps H -o 'tid comm' $(pidof -s clickhouse-server) |  tail -n +2 | awk '{ printf("%s\t%s\n", $1, $2) }' | grep BgSchPool
7346    BgSchPool/D
SELECT 
    cluster, 
    shard_num, 
    replica_num, 
    host_name
FROM system.clusters

┌─cluster───────────────────────────┬─shard_num─┬─replica_num─┬─host_name─┐
│ test_cluster_two_shards           │         1 │           1 │ 127.0.0.1 │
│ test_cluster_two_shards           │         2 │           1 │ 127.0.0.2 │
│ test_cluster_two_shards_localhost │         1 │           1 │ localhost │
│ test_cluster_two_shards_localhost │         2 │           1 │ localhost │
│ test_shard_localhost              │         1 │           1 │ localhost │
│ test_shard_localhost_secure       │         1 │           1 │ localhost │
│ test_unavailable_shard            │         1 │           1 │ localhost │
│ test_unavailable_shard            │         2 │           1 │ localhost │
└───────────────────────────────────┴───────────┴─────────────┴───────────┘

  🚀 最大线程数

  最大线程数

  • 查询处理线程的最大数量,不包括用于从远程服务器检索数据的线程(请参阅“max_distributed_connections”参数)。

  • 此参数适用于并行执行查询处理管道的相同阶段的线程。

    例如,当从表中读取时,如果可以使用函数计算表达式、使用 WHERE 进行过滤并使用至少“max_threads”数量的线程并行预聚合 GROUP BY,则使用“max_threads”。

  • 默认值:物理CPU核数。

  • 对于由于 LIMIT 而快速完成的查询,您可以设置较低的“max_threads”。例如,如果每个块中都有必要数量的条目,并且 max_threads = 8,则将检索 8 个块,尽管只读取一个块就足够了。

  • max_threads值越小,消耗的内存越少。

  • 在用户配置文件中更新此值

🚀 获取表格大小

clickhouse-get-tables-size.sql

select concat(database, '.', table)                         as table,
       formatReadableSize(sum(bytes))                       as size,
       sum(rows)                                            as rows,
       max(modification_time)                               as latest_modification,
       sum(bytes)                                           as bytes_size,
       any(engine)                                          as engine,
       formatReadableSize(sum(primary_key_bytes_in_memory)) as primary_keys_size
from system.parts
where active
group by database, table
order by bytes_size desc
  • 对于数据库的表详细信息
select parts.*,
       columns.compressed_size,
       columns.uncompressed_size,
       columns.ratio
from (
         select table,
                formatReadableSize(sum(data_uncompressed_bytes))          AS uncompressed_size,
                formatReadableSize(sum(data_compressed_bytes))            AS compressed_size,
                sum(data_compressed_bytes) / sum(data_uncompressed_bytes) AS ratio
         from system.columns
         where database = currentDatabase()
         group by table
         ) columns
         right join (
    select table,
           sum(rows)                                            as rows,
           max(modification_time)                               as latest_modification,
           formatReadableSize(sum(bytes))                       as disk_size,
           formatReadableSize(sum(primary_key_bytes_in_memory)) as primary_keys_size,
           any(engine)                                          as engine,
           sum(bytes)                                           as bytes_size
    from system.parts
    where active and database = currentDatabase()
    group by database, table
    ) parts on columns.table = parts.table
order by parts.bytes_size desc;

🚀 了解 clickhouse 压缩

🚀 启用allow_introspection_functions进行查询分析

  • 自省功能。在用户个人资料中更新
        &lt;default&gt;
            &lt;allow_introspection_functions&gt;1&lt;/allow_introspection_functions&gt;
        &lt;/default&gt;
  • 获取线程堆栈跟踪
WITH arrayMap(x -&gt; demangle(addressToSymbol(x)), trace) AS all
SELECT
    thread_id,
    query_id,
    arrayStringConcat(all, '\n') AS res
FROM system.stack_trace
WHERE res LIKE '%SchedulePool%'

┌─thread_id─┬─query_id─┬─res──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│      7346 │          │ pthread_cond_wait
DB::BackgroundSchedulePool::delayExecutionThreadFunction()

ThreadPoolImpl&lt;std::__1::thread&gt;::worker(std::__1::__list_iterator&lt;std::__1::thread, void*&gt;)

start_thread
clone │
└───────────┴──────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

🚀要扔的零件插入

  • parts_to_throw_insert 如果单个分区中的活动部件数超过 parts_to_throw_insert 值,则 INSERT 将因部件过多 (N) 而中断。合并的处理速度明显慢于插入异常。

 可能的值:
  任何正整数。
  默认值:300。

为了实现 SELECT 查询的最大性能,有必要最大限度地减少处理的部分数量,请参阅合并树。

您可以将较大的值设置为 600 (1200),这将减少 Too much parts 错误的概率,但同时 SELECT 性能可能会降低。

此外,如果出现合并问题(例如,由于磁盘空间不足),您会比原始 300 晚注意到它。

  •   面临问题?
2021.08.30 11:30:44.526367 [ 7369 ] {} &lt;Error&gt; void DB::SystemLog&lt;DB::MetricLogElement&gt;::flushImpl(const std::vector&lt;LogElement&gt; &amp;, uint64_t) [LogElement = DB::MetricLogElement]: Code: 252, e.displayText() = DB::Exception: Too many parts (300). Parts cleaning are processing significantly slower than inserts, Stack trace (when copying this message, always include the lines below):
  • 并且您决定增加 parts_to_throw_insert -> 更新 config.xml
    &lt;merge_tree&gt;
         &lt;parts_to_throw_insert&gt;600&lt;/parts_to_throw_insert&gt;
    &lt;/merge_tree&gt;

[

vumdao image

](https://dev.to/vumdao)