摘要:
ClickHouse 挺好用的,但是這些坑防不勝防,用過的才懂。本篇文章將持續更新...
1.記憶體限制
2.寫資料失敗
4.Join 關聯預設值
現在用不到沒關係,先收藏,防止後面找不到哦。
#大資料# #大資料學習#
1、group by 使用記憶體限制錯誤資訊如下:
Code: 241.DB::Exception: Memory limit (for query) exceeded:would use 9.37 GiB (attempt to allocate chunk of 134217760 bytes), maximum: 9.31 GiB.
定位到該查詢中的 SQL 中使用了 group by ,預設的配置中沒有對 group by 做記憶體限制。
解決方案:
執行 SQL 之前,在客戶端進行如下設定
set max_memory_usage=32000000000;set max_bytes_before_external_group_by=16000000000;-- 下面是 sql 內容
在進行group by的時候,記憶體使用量已經達到了max_bytes_before_external_group_by的時候就進行寫磁碟(基於磁碟的group by相對於基於磁碟的order by效能損耗要好很多的),一般max_bytes_before_external_group_by設定為max_memory_usage / 2,原因是在clickhouse中聚合分兩個階段:查詢並且建立中間資料;合併中間資料 寫磁碟在第一個階段,如果無須寫磁碟,clickhouse在第一個和第二個階段需要使用相同的記憶體。
https://clickhouse.tech/docs/en/sql-reference/statements/select/group-by/#select-group-by-in-external-memory
2、寫入資料失敗1.錯誤資訊如下:
Too many parts (300). Merges are processing significantly slower than inserts...
使用 Flink 實時消費 Kafka 的資料,Sink 到 ClickHouse ,策略是一條一條插入,任務上線一段時間之後,ClickHouse 扛不住資料插入的壓力了(
是因為MergeTree的merge的速度跟不上 data part 生成的速度。),就報錯了上述的報錯資訊。
解決方案:
最佳化 FLink ClickHouse Sink邏輯, 根據時間和資料量做觸發,滿足其一才會執行插入操作。
2.錯誤資訊如下
Code: 252, e.displayText() = DB::Exception: Too many partitionsfor single INSERT block (more than 100).
大概意思就是單次插入的資料分割槽太多了,超過預設配置的 100 個了。
解決方案:
1.合理設定分割槽欄位 2.修改這個 max_partitions_per_insert_block 引數,調大這個值。
Code: 359,e.displayText()=DB::Exception: Table or Partition in xxx was not dropped.Reason:1. Size (158.40 GB) is greater than max_[table/partition]_size_to_drop (50.00 GB)2. File '/data/clickhouse/clickhouse-server/flags/force_drop_table' intended to force DROP doesn't exist
從報錯資訊中的原因 1 可以看到,刪除的資料實際大小已經超過了配置的大小。原因 2 說明是可以跳過配置檢查,進行強制刪除的,但是沒找到這個檔案 /data/clickhouse/clickhouse-server/flags/force_drop_table,所以不能跳過檢查,也就是不能強制刪除。
根據錯誤提示2 ,在所在的節點執行:
sudo touch '/data/clickhouse/clickhouse-server/flags/force_drop_table' && sudo chmod 666 '/data/clickhouse/clickhouse-server/flags/force_drop_table'
然後再次執行 刪除操作就可以了。
4、Join 誤用關聯兩張表,對於未關聯的行,使用該欄位的預設值填充,而不是使用 null 填充。
在 system.settings 表中可以找到引數 join_use_nulls
這和我們在 Mysql 或者 Hive 等使用習慣上不一致,如果想要改成一樣的,需要修改這個引數 join_use_nulls 為 1。
準備資料
-- 建表 1create table st_center.test_join_1( id String, name String) engine = MergeTree() order by tuple() SETTINGS index_granularity = 8192;-- 建表 2create table st_center.test_join_2( id String, name String) engine = MergeTree() order by tuple() SETTINGS index_granularity = 8192;-- 插入測試資料insert into test_join_1(id, name) values ('1','大資料學習指南');insert into test_join_1(id, name) values ('2','大資料進階之路');insert into test_join_2(id, name) values ('1','大資料學習指南');
資料準備好了,下面我們測試一下。
select * from st_center.test_join_1 as t1all left join st_center.test_join_2 as t2on t1.id = t2.id
關聯結果如下,未連線的行使用預設值填充的。String型別就填充空字串,數值型別就填充 0
修改引數,在 SQL 最後加入 settings join_use_nulls = 1
select * from st_center.test_join_1 as t1all left join st_center.test_join_2 as t2on t1.id = t2.idsettings join_use_nulls = 1
關聯結果如下,和我們在 mysql 等中的使用習慣一樣了。