clickhouse分區設計操作以及優化


一、分區設計

1.使用類型

  1)不指定分區鍵

  如果建表時不指定分區鍵,則數據默認不分區,所有數據寫到一個默認分區all里面。

  2)使用整型

  如果分區鍵取值屬於整型且無法轉換為日期類型YYYVYMMDD格式,則直接按照該整型的字符形式輸出作為分區ID的取值。

  3)使用日期類型

  如果分區鍵取值屬於日期類型,或者是能夠轉換為YYYYMMDD日期格式的整型,則按照分區表達式邏輯格式化后作為分區ID的取值。

  4)使用其它類型

  如果分區鍵取值既不屬於整型,也不屬於日期類型,例如String、Float等,則通過128位Hash算法取其Hash值作為分區ID的取值。

     (默認情況下,不支持浮點分區鍵。要使用它,請啟用設置allow_floating_point_partition_key

  5)使用tuple元組類型

  分區鍵也可以是表達式的元組(類似於主鍵

ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));

 

2.分區目錄命名規則

20220124_1_1_0_[11]
20220123_1_2_0
partition_id_ min_block_number_ max_block _number_ level [_version]

  

  !!!舊類型表的部分具有以下名稱:(20220117_20220123_2_2_0最小日期 - 最大日期 - 最小塊數 - 最大塊數 - 級別)。

  1)partition_id:20220124,分區生成規則見上;

  2)min_block_number:1,最小塊編號,MergeTree引|擎從1開始計數,每次+1;

  3)max block_number:1,最大塊編號,新插入的數據,最小與最大編號一致;

  4)level:0,這個可以理解為合並的次數,新插入的數據都是0,每合並1次+1。

  5)mutation version:11是突變版本(如果部分突變)。[並非所有都帶有突變]

3.分區目錄合並過程

  如圖:  

  

 

  向表中插入新數據時,此數據存儲為按主鍵排序的單獨部分(塊)。插入后10-15分鍾,同一分區的部分合並為整個部分。

  !!!合並僅適用於分區表達式具有相同值的數據部分。這意味着不應該制作過於精細的分區(超過大約一千個分區)。否則,SELECT由於文件系統中的文件數量過多以及打開的文件描述符,查詢性能會很差。

  使用system.parts表查看表部分和分區。例如,假設我們有一個visits按月分區的表。讓我們對表執行SELECT查詢system.parts

SELECT
    partition,
    name,
    active
FROM system.parts
WHERE table = 'visits' and database ='test';
┌─partition─┬─name──────────────┬─active─┐
│ 202201    │ 202201_1_3_10 │
│ 202201    │ 202201_1_9_2_111 │
│ 202201    │ 202201_8_8_00 │
│ 202201    │ 202201_9_9_00 │
│ 202202    │ 202202_4_6_1_111 │
│ 202202    │ 202202_10_10_0_111 │
│ 202202    │ 202202_11_11_0_111 │
└───────────┴───────────────────┴────────┘

  該active列顯示部件的狀態。1活躍; 0處於非活動狀態。例如,非活動部分是合並到較大部分后剩余的源部分。損壞的數據部分也被指示為非活動的。

  同一分區有多個獨立的部分(例如,202201_1_3_1202201_1_9_2)。這意味着這些部分尚未合並。ClickHouse 會定期合並插入的部分數據,大約在插入后 15 分鍾。此外,可以使用OPTIMIZE查詢執行非計划合並。

  合並后大約 10 分鍾將刪除不活動的部分。

 4.分區設計

  分區選擇考慮merge (寫入放大)、查詢(slelect part數量)、啟動等方面考慮。在實際生產中選擇時間作為分區鍵,根據表數據的大小按天或者按周進行了分區。

  如圖:

 

二、分區操作

分區操作

  • DETACH PARTITION - 將分區移動到detached目錄並忘記它。
  • DROP PARTITION — 刪除分區。
  • ATTACH PART|PARTITION — 將detached目錄中的數據塊或分區添加到表中。
  • ATTACH PARTITION FROM — 將數據分區從一個表復制到另一個表並添加。
  • REPLACE PARTITION — 將數據分區從一個表復制到另一個表並替換。
  • MOVE PARTITION TO TABLE — 將數據分區從一個表移動到另一個表。
  • CLEAR COLUMN IN PARTITION — 重置分區中指定列的值。
  • CLEAR INDEX IN PARTITION — 重置分區中指定的二級索引。
  • FREEZE PARTITION — 創建分區的備份。
  • UNFREEZE PARTITION — 刪除分區的備份。
  • FETCH PARTITION|PART — 從另一台服務器下載數據塊或分區。
  • MOVE PARTITION|PART — 將分區/數據塊移動到另一個磁盤或卷。
  • UPDATE IN PARTITION — 按條件更新分區內的數據。
  • DELETE IN PARTITION — 按條件刪除分區內的數據。

  DETACH PARTITION|PART

ALTER TABLE table_name DETACH PARTITION|PART partition_expr

 

  將指定分區的所有數據移動到detached目錄中。服務器忘記了分離的數據分區,就好像它不存在一樣。在進行ATTACH查詢之前,服務器不會知道此數據。

  例子:

ALTER TABLE mt DETACH PARTITION '2020-11-21';
ALTER TABLE mt DETACH PART 'all_2_2_0';

 

  執行查詢后,你可以對detached目錄中的數據做任何你想做的事情——從文件系統中刪除它,或者直接離開它。

  此查詢被復制——它將數據移動到detached所有副本上的目錄。請注意,只能在領導者副本上執行此查詢。要確定副本是否是領導者,請對system.replicas表執行SELECT查詢。或者,對所有副本進行查詢更容易- 所有副本都拋出異常,除了領導者副本(因為允許多個領導者)。DETACH

 

  DROP PARTITION|PART

ALTER TABLE table_name DROP PARTITION|PART partition_expr

 

  從表中刪除指定的分區。此查詢將分區標記為非活動並完全刪除數據,大約在 10 分鍾內。

  查詢被復制——它刪除所有副本上的數據。

  例子:

ALTER TABLE mt DROP PARTITION '2020-11-21';
ALTER TABLE mt DROP PART 'all_4_4_0';

 

 

  DROP DETACHED PARTITION|PART

ALTER TABLE table_name DROP DETACHED PARTITION|PART partition_expr

 

  從 中刪除指定分區的指定數據塊或所有數據塊detached

 

  ATTACH PARTITION|PART

ALTER TABLE table_name ATTACH PARTITION|PART partition_expr

 

  將數據從detached目錄添加到表中。可以為整個分區或單獨的數據塊添加數據。例子:

ALTER TABLE visits ATTACH PARTITION 201901;
ALTER TABLE visits ATTACH PART 201901_2_2_0;

 

  此查詢被復制。副本發起者檢查目錄中是否有數據detached如果數據存在,則查詢檢查其完整性。如果一切正確,則查詢將數據添加到表中。

  如果接收到附加命令的非發起者副本在其自己的detached文件夾中找到具有正確校驗和的數據塊,它會附加數據而不從其他副本中獲取數據。如果沒有具有正確校驗和的零件,則從具有該零件的任何副本下載數據。

  可以將數據detached放在一個副本上的目錄中,並使用ALTER ... ATTACH查詢將其添加到所有副本上的表中。

 

  ATTACH PARTITION FROM

ALTER TABLE table2 ATTACH PARTITION partition_expr FROM table1

 

  此查詢將數據分區從 復制table1table2請注意,既不會從table1也不會從中刪除數據table2

  要使查詢成功運行,必須滿足以下條件:

  • 兩個表必須具有相同的結構。
  • 兩個表必須具有相同的分區鍵。

 

  REPLACE PARTITION

ALTER TABLE table2 REPLACE PARTITION partition_expr FROM table1

 

  此查詢將數據分區從 復制table1table2並替換 中的現有分區table2請注意,數據不會從table1.

  要使查詢成功運行,必須滿足以下條件:

  • 兩個表必須具有相同的結構。
  • 兩個表必須具有相同的分區鍵。

 

  MOVE PARTITION TO TABLE

ALTER TABLE table_source MOVE PARTITION partition_expr TO TABLE table_dest

 

  此查詢將數據分區從 移動table_source到,並從 中table_dest刪除數據table_source

  要使查詢成功運行,必須滿足以下條件:

  • 兩個表必須具有相同的結構。
  • 兩個表必須具有相同的分區鍵。
  • 兩個表必須是相同的引擎系列(復制或非復制)。
  • 兩個表必須具有相同的存儲策略。

 

  CLEAR COLUMN IN PARTITION

ALTER TABLE table_name CLEAR COLUMN column_name IN PARTITION partition_expr

 

  重置分區中指定列中的所有值。如果DEFAULT在創建表時確定了該子句,則此查詢將列值設置為指定的默認值。

  例子:

ALTER TABLE visits CLEAR COLUMN hour in PARTITION 201902

 

 

  FREEZE PARTITION

ALTER TABLE table_name FREEZE [PARTITION partition_expr] [WITH NAME 'backup_name']

 

  此查詢創建指定分區的本地備份。如果PARTITION省略該子句,則查詢會立即創建所有分區的備份。

  !!!note "注意" 整個備份過程在不停止服務器的情況下執行。

  對於舊式表,可以指定分區名稱的前綴(例如,2019) - 然后查詢會為所有相應的分區創建備份。

  在執行時,對於數據快照,查詢會創建指向表數據的硬鏈接。硬鏈接放置在目錄/var/lib/clickhouse/shadow/N/...中,其中:

  • /var/lib/clickhouse/是配置中指定的工作 ClickHouse 目錄。
  • N是備份的增量數。
  • 如果WITH NAME指定了'backup_name'參數,則使用參數的值而不是增量數。

  !!!“注意” 如果使用一組磁盤存儲表中的數據,則shadow/N目錄會出現在每個磁盤上,存儲PARTITION表達式匹配的數據數據塊

  在備份內部創建與 inside 相同的目錄結構/var/lib/clickhouse/查詢chmod對所有文件執行,禁止寫入它們。

  創建備份后,可以將數據從遠程服務器復制/var/lib/clickhouse/shadow/到遠程服務器,然后將其從本地服務器中刪除。請注意,ALTER t FREEZE PARTITION查詢不會被復制。它僅在本地服務器上創建本地備份。

  該查詢幾乎立即創建備份(但首先它等待對相應表的當前查詢完成運行)。

  ALTER TABLE t FREEZE PARTITION只復制數據,不復制表元數據。要備份表元數據,請復制文件/var/lib/clickhouse/metadata/database/table.sql

  要從備份中恢復數據,請執行以下操作:

  1. 如果表不存在,則創建它。要查看查詢,請使用 .sql 文件(ATTACH在其中替換為CREATE)。
  2. data/database/table/將備份中的目錄中的數據復制到/var/lib/clickhouse/data/database/table/detached/目錄中。
  3. 運行ALTER TABLE t ATTACH PARTITION查詢以將數據添加到表中。

  從備份恢復不需要停止服務器。

 

  UNFREEZE PARTITION

ALTER TABLE 'table_name' UNFREEZE [PARTITION 'part_expr'] WITH NAME 'backup_name'

 

  從磁盤中刪除freezed具有指定名稱的分區。如果PARTITION省略該子句,則查詢會立即刪除所有分區的備份。

 

  CLEAR INDEX IN PARTITION

ALTER  TABLE table_name CLEAR INDEX index_name IN PARTITION partition_expr

 

  該查詢的工作方式類似於CLEAR COLUMN,但它重置索引而不是列數據。

 

  FETCH PARTITION|PART

ALTER TABLE table_name FETCH PARTITION|PART partition_expr FROM 'path-in-zookeeper'

 

  從另一台服務器下載分區。此查詢僅適用於復制的表。

  查詢執行以下操作:

  1. 從指定的分片下載分區|數據塊。在“path-in-zookeeper”中,必須指定 ZooKeeper 中分片的路徑。
  2. 然后查詢把下載的數據放到表的detached目錄下table_name使用ATTACH PARTITION|PART查詢將數據添加到表中。

  例如:

  1. 獲取分區
ALTER TABLE users FETCH PARTITION 201902 FROM '/clickhouse/tables/01-01/visits';
ALTER TABLE users ATTACH PARTITION 201902;

 

  1. 獲取數據塊
ALTER TABLE users FETCH PART 201901_2_2_0 FROM '/clickhouse/tables/01-01/visits';
ALTER TABLE users ATTACH PART 201901_2_2_0;

 

  注意:

  • 查詢不會被ALTER ... FETCH PARTITION|PART復制。它僅將部件或分區detached放置到本地服務器上的目錄中。
  • 查詢被ALTER TABLE ... ATTACH復制。它將數據添加到所有副本。數據從detached目錄添加到其中一個副本,並從相鄰副本添加到其他副本。

  在下載之前,系統會檢查分區是否存在以及表結構是否匹配。從健康的副本中自動選擇最合適的副本。

  雖然調用了查詢ALTER TABLE,但它不會更改表結構,也不會立即更改表中可用的數據。

 

  MOVE PARTITION|PART

  將分區或數據塊移動到另一個卷或磁盤以用於MergeTree-engine 表。

ALTER TABLE table_name MOVE PARTITION|PART partition_expr TO DISK|VOLUME 'disk_name'

 

  ALTER TABLE t MOVE查詢

  • 不復制,因為不同的副本可以有不同的存儲策略。
  • 如果未配置指定的磁盤或卷,則返回錯誤。如果存儲策略中指定的數據移動條件無法應用,查詢也會返回錯誤。
  • 在要移動的數據已被后台進程、並發ALTER TABLE t MOVE查詢或后台數據合並的結果移動的情況下,可以返回錯誤。在這種情況下,用戶不應執行任何其他操作。

  例子:

ALTER TABLE hits MOVE PART '20190301_14343_16206_438' TO VOLUME 'slow'
ALTER TABLE hits MOVE PARTITION '2019-09-01' TO DISK 'fast_ssd'

 

 

  UPDATE IN PARTITION

  操作與指定過濾表達式匹配的指定分區中的數據。作為一個突變實現。

  句法:

ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] [IN PARTITION partition_id] WHERE filter_expr

  例子

ALTER TABLE mt UPDATE x = x + 1 IN PARTITION 2 WHERE p = 2;

 

 

  DELETE IN PARTITION

  刪除與指定過濾表達式匹配的指定分區中的數據。作為一個突變實現。

  句法:

ALTER TABLE [db.]table DELETE [IN PARTITION partition_id] WHERE filter_expr

  例子

ALTER TABLE mt DELETE IN PARTITION 2 WHERE p = 2;

 

三、分區優化

  1)分區粒度根據業務特點決定,不宜過粗或過細。一般選擇按天分區,也可以指定為Tuple(),以單表一億數據為例,分區大小控制在10-30個為最佳。
  2)那些有相同分區表達式值的數據片段才會合並。這意味着 你不應該用太精細的分區方案(超過一千個分區)。否則,會因為文件系統中的文件數量過多和需要打開的文件描述符過多,導致 SELECT 查詢效率不佳。
  3)還有就是一般我們都是使用的是日期作為分區鍵,同一分區內有序,不同分區不能保證有序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM