早期 clickhouse 僅支援單一儲存設備,19.15 版本以後支援将資料分别儲存在不同的儲存設備,且能夠自動在不同裝置間移動資料。使 clickhouse 可以實作階梯式多層存儲,即将冷熱資料分離,将冷熱資料分别儲存在不同類型的儲存設備中。
日常互動式查詢中,95% 查詢通路近幾天的資料,剩下 5% 的跑一些長周期批處理任務。我們可以通過階梯式多層存儲,将最新的熱點資料放在高性能媒體如 SSD,舊的曆史資料放在廉價的機械硬碟中。此外,将資料存在多個儲存設備中,以擴充伺服器的存儲能力,clickhouse 也能夠自動在不同儲存設備之間移動資料。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iMyQTY4MmYwMDOlJTNxIDZ5QmZzEjY5E2Y0gDNhFWO08CXwMzLcZDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL4M3Lc9CX6MHc0RHaiojIsJye.png)
每張 MergeTree 表都有一個存儲政策,用以規定該表資料如何寫入;政策将不同的磁盤分到一個或多個卷中,并規定了資料的寫入順序以及如何在磁盤之間移動資料。
如果沒有特别指定,每一個表都有一個預設的存儲政策default,該政策将資料存儲在配置檔案中path指定的路徑下。
初始狀态在clickhouse配置檔案中指定了資料存放目錄為:
/home/work/bigdata/clickhouse/data/
啟動用戶端并檢視目前clickhouse感覺到的磁盤目錄:
SELECT
name,
path,
formatReadableSize(free_space) AS free,
formatReadableSize(total_space) AS total,
formatReadableSize(keep_free_space) AS reserved
FROM system.disks
┌─name────┬─path────────────────────────────────┬─free─────┬─total────┬─reserved─┐
│ default │ /home/work/bigdata/clickhouse/data/ │ 1.16 TiB │ 3.52 TiB │ 0.00 B │
└─────────┴─────────────────────────────────────┴──────────┴──────────┴──────────┘
1 rows in set. Elapsed: 0.040 sec.
在伺服器上挂載了額外的磁盤:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 3.7T 0 disk
`-sdb1 8:17 0 3.7T 0 part /home/disk0
sdc 8:32 0 3.7T 0 disk
`-sdc1 8:33 0 3.7T 0 part /home/disk1
sdd 8:48 0 3.7T 0 disk
`-sdd1 8:49 0 3.7T 0 part /home/disk2
sde 8:64 0 3.7T 0 disk
`-sde1 8:65 0 3.7T 0 part /home/disk3
sdf 8:80 0 3.7T 0 disk
`-sdf1 8:81 0 3.7T 0 part /home/disk4
sdg 8:96 0 3.7T 0 disk
`-sdg1 8:97 0 3.7T 0 part /home/disk5
sdh 8:112 0 3.7T 0 disk
`-sdh1 8:113 0 3.7T 0 part /home/disk6
在每個磁盤中建立對應的存放clickhouse資料的目錄,并修改目錄所有者為click house使用者
mkdir -p /home/disk0/clickhouse/
chown -R clickhouse.clickhouse /home/disk0/clickhouse/
修改clickhouse服務配置檔案 /etc/clickhouse-server/config.xml增加上述磁盤
<yandex>
<storage_configuration>
<disks>
<disk_name_0> <!-- disk name -->
<path>/home/disk0/clickhouse/</path>
</disk_name_0>
<disk_name_1>
<path>/home/disk1/clickhouse/</path>
</disk_name_1>
<disk_name_2>
<path>/home/disk2/clickhouse/</path>
</disk_name_2>
<disk_name_3>
<path>/home/disk3/clickhouse/</path>
</disk_name_3>
<disk_name_4>
<path>/home/disk4/clickhouse/</path>
</disk_name_4>
<disk_name_5>
<path>/home/disk5/clickhouse/</path>
</disk_name_5>
<disk_name_6>
<path>/home/disk6/clickhouse/</path>
</disk_name_6>
</disks>
</storage_configuration>
</yandex>
重新開機clickhouse服務
service clickhouse-server stop
service clickhouse-server start
此時再檢視clickhouse感覺到的磁盤目錄
SELECT
name,
path,
formatReadableSize(free_space) AS free,
formatReadableSize(total_space) AS total,
formatReadableSize(keep_free_space) AS reserved
FROM system.disks
┌─name────────┬─path────────────────────────────────┬─free─────┬─total────┬─reserved─┐
│ default │ /home/work/bigdata/clickhouse/data/ │ 1.34 TiB │ 3.52 TiB │ 0.00 B │
│ disk_name_0 │ /home/disk0/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_1 │ /home/disk1/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_2 │ /home/disk2/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_3 │ /home/disk3/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_4 │ /home/disk4/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_5 │ /home/disk5/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
│ disk_name_6 │ /home/disk6/clickhouse/ │ 3.58 TiB │ 3.58 TiB │ 0.00 B │
└─────────────┴─────────────────────────────────────┴──────────┴──────────┴──────────┘
可以看到,除了原有的預設路徑外,新增了我們新挂載的磁盤目錄。
通過上述操作,為clickhouse配置了多個磁盤,但是僅僅這些并不能讓表中的資料存在配置的多個磁盤中,可以通過試驗觀察:
CREATE TABLE sample1
(
`id` UInt64
)
ENGINE = MergeTree
ORDER BY id
Ok.
0 rows in set. Elapsed: 2.467 sec.
INSERT INTO sample1 SELECT *
FROM numbers(1000000)
← Progress: 1.05 million rows, 8.39 MB (10.84 million rows/s., 86.74 MB/s.) 99%Ok.
0 rows in set. Elapsed: 0.097 sec. Processed 1.05 million rows, 8.39 MB (10.84 million rows/s., 86.70 MB/s.)
SELECT
name,
data_paths
FROM system.tables
WHERE name = 'sample1'
┌─name────┬─data_paths───────────────────────────────────────────────────┐
│ sample1 │ ['/home/work/bigdata/clickhouse/data/data/default/sample1/'] │
└─────────┴──────────────────────────────────────────────────────────────┘
SELECT
name,
disk_name,
path
FROM system.parts
WHERE (table = 'sample1') AND active
┌─name──────┬─disk_name─┬─path───────────────────────────────────────────────────────────────┐
│ all_1_1_0 │ default │ /home/work/bigdata/clickhouse/data/data/default/sample1/all_1_1_0/ │
└───────────┴───────────┴────────────────────────────────────────────────────────────────────┘
可以看到該表資料仍然隻儲存在一個目錄中,因為如果不加指定,clickhouse的表有一個預設的單一存儲政策default:
SELECT
policy_name,
volume_name,
disks
FROM system.storage_policies
┌─policy_name─┬─volume_name─┬─disks───────┐
│ default │ default │ ['default'] │
└─────────────┴─────────────┴─────────────┘
為了使多個磁盤生效,仍需兩個工作:
- 在配置檔案中制定存儲政策,并通過卷标簽來組織多個磁盤
- 建表時通過SETTINGS storage_policy=’’來為表指定存儲政策
JBOD(“Just a Bunch of Disks”),通過将多個磁盤配置設定在一個卷中,每次插入資料所生成的data part會以輪詢的方式依次寫入這些磁盤,該政策的優點:
- 通過直接追加磁盤的形式,可以便捷地擴充存儲能力
- 在多線程并行通路多個不同磁盤時,可以提升讀寫速度
- 由于每個磁盤上的data parts變少,可以加快表的加載速度
在配置檔案中添加如下的存儲政策配置,并重新開機clickhouse服務。
<policies>
<policy_name_1>
<volumes>
<volume_name_0>
<disk>disk_name_0</disk>
<disk>disk_name_1</disk>
<disk>disk_name_2</disk>
<disk>disk_name_3</disk>
<disk>disk_name_4</disk>
<disk>disk_name_5</disk>
<disk>disk_name_6</disk>
</volume_name_6>
</volumes>
</policy_name_1>
</policies>
SELECT policy_name,
volume_name,
disks
FROM system.storage_policies
┌─policy_name───┬─volume_name───┬─disks───────────────────────────────────────────────────────────────────────────────────────────────┐
│ default │ default │ ['default'] │
│ policy_name_1 │ volume_name_0 │ ['disk_name_0','disk_name_1','disk_name_2','disk_name_3','disk_name_4','disk_name_5','disk_name_6'] │
└───────────────┴───────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────┘
建立新表并進行測試
CREATE TABLE sample3 (id UInt64)
Engine=MergeTree
ORDER BY id
SETTINGS storage_policy = 'policy_name_1';
SELECT
name,
data_paths,
metadata_path,
storage_policy
FROM system.tables
WHERE name = 'sample3';
┌─name────┬─data_paths─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─metadata_path───────────────────────────────────────────────────┬─storage_policy─┐
│ sample3 │ ['/home/disk0/clickhouse/data/default/sample3/','/home/disk1/clickhouse/data/default/sample3/','/home/disk2/clickhouse/data/default/sample3/','/home/disk3/clickhouse/data/default/sample3/','/home/disk4/clickhouse/data/default/sample3/','/home/disk5/clickhouse/data/default/sample3/','/home/disk6/clickhouse/data/default/sample3/'] │ /home/work/bigdata/clickhouse/data/metadata/default/sample3.sql │ policy_name_1 │
└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────┴────────────────┘
insert into sample3 select * from numbers(1000000);
insert into sample3 select * from numbers(1000000);
insert into sample3 select * from numbers(1000000);
insert into sample3 select * from numbers(1000000);
select name, disk_name, path from system.parts where table = 'sample3';
┌─name──────┬─disk_name───┬─path───────────────────────────────────────────────────┐
│ all_1_1_0 │ disk_name_0 │ /home/disk0/clickhouse/data/default/sample3/all_1_1_0/ │
│ all_2_2_0 │ disk_name_1 │ /home/disk1/clickhouse/data/default/sample3/all_2_2_0/ │
│ all_3_3_0 │ disk_name_2 │ /home/disk2/clickhouse/data/default/sample3/all_3_3_0/ │
│ all_4_4_0 │ disk_name_3 │ /home/disk3/clickhouse/data/default/sample3/all_4_4_0/ │
└───────────┴─────────────┴────────────────────────────────────────────────────────┘
該表的多磁盤存儲已經生效,且插入的測試資料也依次寫入到多個磁盤中,
注意中繼資料仍然存在預設磁盤目錄中。背景的合并任務會定期合并這些小的
data parts 并生成更大的data parts,同樣采用輪詢的方式寫入這些磁盤中。
可以手動觸發合并任務的執行:
OPTIMIZE TABLE sample3
Ok. 0 rows in set. Elapsed: 0.148 sec. Processed: 0 rows, 0.0B (0 rows/s, 0.0B/s)
SELECT
name,
disk_name,
path
FROM system.parts
WHERE (table = 'sample3') AND active;
┌─name──────┬─disk_name───┬─path───────────────────────────────────────────────────┐
│ all_1_4_1 │ disk_name_4 │ /home/disk4/clickhouse/data/default/sample3/all_1_4_1/ │
└───────────┴─────────────┴────────────────────────────────────────────────────────┘