首頁>技術>

摘要:

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 等中的使用習慣一樣了。

18
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 5分鐘讓你理解K8S必備架構概念,以及網路模型(一)