ClickHouse 使用中遇见的异常


1. Array(String) cannot be inside Nullable type

DB::Exception: 
Nested type Array(String) cannot be inside Nullable type (version 20.4.6.53 (official build))

提示信息表示 ClickHouse 不支持将 Array 类型嵌套在 Nullable 类型中。在 ClickHouse 中,Array 类型的元素本身可以为 Nullable 类型,但不能将整个 Array 作为 Nullable 类型。要解决这个问题,请检查你的表结构和查询,确保没有将 Array 类型作为 Nullable 类型的一部分。

例如,如果你的表结构如下所示:

CREATE TABLE example
(
    id Int32,
    names Nullable(Array(String))
) ENGINE = MergeTree()
ORDER BY id;

这将会导致上述错误。正确的做法是将 Array 类型的元素设置为 Nullable 类型,如下所示:

CREATE TABLE example
(
    id Int32,
    names Array(Nullable(String))
) ENGINE = MergeTree()
ORDER BY id;

或者将对应的数据转成String。如下:

使用cast强转一下字段类型就行:
select splitByString(',',cast(col as String)) col from test

2. Cannot convert NULL value to non-Nullable type

DB::Exception: 
Cannot convert NULL value to non-Nullable type: 
while converting source column second_channel to destination column second_channel (version 20.4.6.53 (official build))

在执行查询时,ClickHouse 遇到了一个无法将 NULL 值转换为非 Nullable 类型的问题。这通常是由于源数据中的 NULL 值无法直接存储到目标表的非 Nullable 类型列中。

要解决这个问题,你可以采取以下方法之一:

  1. 修改目标表结构,将对应的列更改为 Nullable 类型。例如,如果你的表结构如下所示:
CREATE TABLE example
(
    id Int32,
    second_channel String
) ENGINE = MergeTree()
ORDER BY id;
-- 修改为: 
CREATE TABLE example
(
    id Int32,
    second_channel Nullable(String)
) ENGINE = MergeTree()
ORDER BY id;
  1. 在查询中处理 NULL 值,将其替换为默认值。例如,如果你的查询类似于以下内容:
INSERT INTO example (id, second_channel)
SELECT id, second_channel
FROM source_table;

-- 可以使用 ifNull 或 coalesce 函数处理 NULL 值:

INSERT INTO example (id, second_channel)
SELECT id, ifNull(second_channel, '')
FROM source_table;

-- 或 
INSERT INTO example (id, second_channel)
SELECT id, coalesce(second_channel, '')
FROM source_table;
-- 在插入数据时将所有 NULL 值替换为一个空字符串。根据需要替换为其他合适的默认值。

3. Memory limit (total) exceeded

DB::Exception: 
Memory limit (total) exceeded: 
would use 113.20 GiB (attempt to allocate chunk of 134200512 bytes), maximum: 113.14 GiB: 
While executing CreatingSetsTransform. (version 20.4.6.53 (official build))

这个错误表示在执行查询时,ClickHouse 遇到了一个内存限制问题。服务器尝试使用超过最大允许内存的内存,导致异常。在这种情况下,尝试分配了 134,200,512 字节的内存,但最大允许值为 113.14 GiB。

要解决这个问题,可以采取以下方法之一:

  1. 调整 ClickHouse 服务器配置以增加内存限制。可以在 config.xml 文件中找到 max_memory_usage 参数,并增加其值。例如:
<yandex>
    ...
    <profiles>
        <default>
            ...
            <max_memory_usage>130000000000</max_memory_usage>
            ...
        </default>
    </profiles>
    ...
</yandex>

上面的配置将最大内存使用限制设置为 130 GB。请确保的服务器有足够的内存来支持这个更改。

  1. 优化查询以减少内存使用。这可能包括减少查询中的数据量、使用更少的 JOIN 操作、减少聚合操作或使用更精确的数据类型。例如,可以尝试在查询中添加更多的过滤条件以减少处理的数据量。
  2. 如果可能的话,尝试将查询拆分为多个较小的查询。这可以通过将数据拆分为多个表或表分区来实现,然后执行针对这些较小表或分区的单独查询。这将有助于降低单个查询的内存需求。
  3. 在适当的情况下,还可以考虑将数据预先聚合或使用材化视图。这将使查询更加高效,并减少内存需求。

通过采用上述方法之一,应该能够解决因内存限制而导致的异常。请注意,在调整内存限制时确保不要超过服务器可用的物理内存,以免导致其他问题。

4. Table columns structure in ZooKeeper is different

DB::Exception: 
Table columns structure in ZooKeeper is different from local table structure 
(version 20.12.3.3 (official build))

此异常表示在 ClickHouse 分布式表中,ZooKeeper 中的表结构与本地表结构不一致。这可能是由于表结构在集群中的不同节点上发生了变化,但这些更改尚未同步到所有节点。

要解决这个问题,可以采取以下步骤:

  1. 首先,检查集群中的所有节点,确保它们都在运行相同版本的 ClickHouse。不同版本的 ClickHouse 可能会导致表结构不一致的问题。
  2. 确定哪个节点的表结构是最新的或正确的。然后,将正确的表结构从该节点导出为 SQL 文件。可以使用 SHOW CREATE TABLE 查询来获取表结构:
SHOW CREATE TABLE your_table_name;
  1. 使用上一步中导出的 SQL 文件,在集群中的其他节点上更新表结构。这可以通过在其他节点上运行 ALTER TABLE 查询来实现。如果有任何新增的列,请使用 ADD COLUMN 子句;如果有任何更改的列,请使用 MODIFY COLUMN 子句。例如:
ALTER TABLE your_table_name
    ADD COLUMN new_column_name Column_Type,
    MODIFY COLUMN existing_column_name New_Column_Type;
  1. 在集群中的所有节点上运行 SYSTEM SYNC REPLICA your_table_name; 命令,以确保所有节点与 ZooKeeper 同步。例如:
SYSTEM SYNC REPLICA your_table_name;
  1. 请确保所有节点上的表结构现在都是一致的,可以使用 SHOW CREATE TABLE 查询在每个节点上检查表结构。

5. Too many parts (300).

Too many parts (300). Merges are processing significantly slower than inserts...

这个异常表明 ClickHouse 表中的写入数量过多,导致合并操作比插入操作慢很多。这种情况可能会导致性能下降和磁盘空间占用过高。要解决这个问题,可以尝试以下方法:

  1. 调整表分区策略:根据业务需求和数据访问模式,对表进行适当的分区。合理的分区策略可以减少每个分区内的部分数量,从而提高合并的速度。

  2. 调整表的索引粒度:索引粒度越小,每个部分的行数越多,合并操作就越快。但是,较小的索引粒度可能会导致查询性能下降。可以通过更改表设置 index_granularity 来调整索引粒度。

  3. 优化插入操作:尽量将数据批量插入,而不是逐条插入。批量插入可以减少生成的部分数量,从而减轻合并操作的压力。

  4. 手动触发合并操作:可以手动触发某些分区的合并操作,以减少部分数量。使用 OPTIMIZE TABLE 查询来合并指定分区:

    OPTIMIZE TABLE your_table_name PARTITION partition_id;
  5. 检查磁盘性能:如果磁盘性能较差,合并操作可能会受到影响。检查磁盘性能,并确保为 ClickHouse 配置了足够的 IOPS。

  6. 检查系统资源:确保 ClickHouse 服务器具有足够的 CPU、内存和磁盘空间来处理合并操作。如果资源不足,可能需要升级硬件配置或优化 ClickHouse 配置。

  7. 调整 ClickHouse 配置:可以尝试调整 ClickHouse 配置中与合并相关的参数,例如 max_bytes_to_merge_at_min_space_in_poolbackground_pool_size。这些参数可以影响合并操作的速度和资源占用。

6. Connection reset by peer, while reading

DB::NetException: Connection reset by peer, while reading from socket xxx

# clickhouse-server进程自己挂掉

DB::NetException: Connection reset by peer 这个异常通常表示 ClickHouse 在尝试从远程服务器读取数据时,远程服务器关闭了连接。以下是一些建议的解决方法:

  1. 检查网络连接:确保 ClickHouse 服务器与远程服务器之间的网络连接稳定且没有阻塞。可以尝试使用 pingtraceroute 命令来检查网络连接。

  2. 检查远程服务器状态:确保远程服务器正在运行,且 ClickHouse 服务正常。可以通过查看服务器的日志或监控工具来检查服务器状态。

  3. 调整 ClickHouse 超时设置:如果确定网络连接和远程服务器状态正常,可以尝试调整 ClickHouse 的超时设置。例如,可以增加 receive_timeoutsend_timeout 参数的值。在 ClickHouse 配置文件中,可以设置这些参数:

    <receive_timeout>300</receive_timeout>
    <send_timeout>300</send_timeout>

    请注意,需要根据具体情况调整超时值。

  4. 检查并发查询限制:确保没有达到 ClickHouse 的并发查询限制。如果并发查询过多,可能导致服务器资源耗尽并关闭连接。可以通过调整 max_concurrent_queries 参数来设置并发查询的最大限制。例如,在 ClickHouse 配置文件中:

    <max_concurrent_queries>100</max_concurrent_queries>

    根据硬件和性能需求调整这个值。

  5. 查看 ClickHouse 日志:查看 ClickHouse 服务器的日志,以获取有关异常的更多详细信息。日志文件通常位于 /var/log/clickhouse-server/ 目录中。

7. follower从leader同步文件时超时

zookeeper的snapshot文件太大,follower从leader同步文件时超时

原因:clickhouse对zookeeper的依赖非常的重,表的元数据信息,每个数据块的信息,每次插入的时候,数据同步的时候,都需要和zookeeper进行交互,存储的数据非常的多。

ZooKeeper 的 snapshot 文件过大可能导致从属节点(follower)在与领导节点(leader)同步时超时。要解决这个问题,可以尝试以下方法:

  1. 调整 ZooKeeper 配置:修改 ZooKeeper 配置文件(通常位于 /etc/zookeeper/conf/zoo.cfg),增加以下配置项,以延长同步超时时间:

    makefileCopy code
    syncLimit=10

    syncLimit 的值以 tickTime(默认为 2000 毫秒)为单位。将 syncLimit 增加到一个较大的值可以为从属节点提供更多的时间来同步 snapshot。

    修改配置后,重启 ZooKeeper 服务:

    Copy code
    sudo systemctl restart zookeeper
  2. 减小 snapshot 大小:通过删除不必要的数据或将数据移动到其他 ZooKeeper 集群,减小 snapshot 文件的大小。

  3. 定期清理 ZooKeeper:ZooKeeper 提供了一个名为 autopurge 的功能,可以定期清理旧的事务日志和 snapshot。在 ZooKeeper 配置文件中启用它,并设置合适的清理间隔:

    Copy codeautopurge.snapRetainCount=3
    autopurge.purgeInterval=1

    这里的配置表示保留最近的 3 个 snapshot,每隔 1 天执行一次自动清理。

    启用 autopurge 之后,重启 ZooKeeper 服务。

  4. 手动清理旧的 snapshot:如果仍然遇到问题,可以手动删除旧的 snapshot。这些文件通常位于 /var/lib/zookeeper/version-2/ 目录中。在删除任何文件之前,请确保备份这些文件以防止数据丢失。

8. ”read only mode”,插入失败

分布式clickhouse表处于”read only mode”,插入失败

在 ClickHouse 分布式表处于 “read-only mode” 时插入数据会失败。这种情况通常是由于某些配置问题或资源限制导致的。要解决此问题,请按照以下步骤进行操作:

  1. 检查本地表:分布式表实际上是一个虚拟表,它将数据插入到底层的本地表。确保本地表的状态正常,没有任何损坏或错误。可以使用 OPTIMIZE TABLEALTER TABLE ... DETACH PARTITIONATTACH PARTITION 等命令来修复潜在的问题。

  2. 检查磁盘空间:确保 ClickHouse 服务器上有足够的磁盘空间。磁盘空间不足可能导致表处于只读模式。可以通过清理旧的日志文件、备份和不再需要的数据来释放磁盘空间。

  3. 查看 ClickHouse 配置:检查 ClickHouse 配置文件(通常位于 /etc/clickhouse-server/config.xml),确保没有任何错误或错误的设置。特别是检查 <readonly> 配置项,确保它的值设置为 0。

    <readonly>0</readonly>
  4. 检查 ZooKeeper 配置:分布式表依赖于 ZooKeeper 服务。确保 ZooKeeper 服务配置正确,并且 ClickHouse 服务器可以访问它。检查 ClickHouse 配置文件中的 <zookeeper> 部分,确保所有设置正确。

  5. 重启 ClickHouse 服务:在检查并解决潜在问题后,尝试重启 ClickHouse 服务。

    sudo systemctl restart clickhouse-server
  6. 查看 ClickHouse 日志:查看 ClickHouse 服务器的日志,以获取有关异常的更多详细信息。日志文件通常位于 /var/log/clickhouse-server/ 目录中。


文章作者: hnbian
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hnbian !
评论
 上一篇
Hive 数据倾斜问题定位以及排查 Hive 数据倾斜问题定位以及排查
1. 背景介绍多数介绍数据倾斜的文章都是以大篇幅的理论为主,并没有给出具体的数据倾斜案例。当工作中遇到了倾斜问题,这些理论很难直接应用,导致我们面对倾斜时还是不知所措。 今天我们不扯大篇理论,直接以例子来实践,排查是否出现了数据倾斜,具体是
2021-12-18
下一篇 
关于 HDFS 中小文件的处理方式 关于 HDFS 中小文件的处理方式
1. 介绍在Hadoop应用过程中,处理小文件问题是一项常见的挑战。由于HDFS主要针对大型数据集(M字节以上)设计,大量小文件的出现可能导致Namenode内存使用效率下降、RPC调用速度减慢、block扫描处理速度降低,从而影响整个应用
2021-11-14
  目录