clickhouse多磁盘存储

早期 clickhouse 仅支持单一存储设备,19.15 版本以后支持将数据分别保存在不同的存储设备,且能够自动在不同设备间移动数据。使 clickhouse 可以实现阶梯式多层存储,即将冷热数据分离,将冷热数据分别保存在不同类型的存储设备中。

日常交互式查询中,95% 查询访问近几天的数据,剩下 5% 的跑一些长周期批处理任务。我们可以通过阶梯式多层存储,将最新的热点数据放在高性能介质如 SSD,旧的历史数据放在廉价的机械硬盘中。此外,将数据存在多个存储设备中,以扩展服务器的存储能力,clickhouse 也能够自动在不同存储设备之间移动数据。

架构

img

每张 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'] │
└─────────────┴─────────────┴─────────────┘

为了使多个磁盘生效,仍需两个工作:

  1. 在配置文件中制定存储策略,并通过卷标签来组织多个磁盘
  2. 建表时通过SETTINGS storage_policy=’’来为表指定存储策略

JBOD:单层多磁盘存储

JBOD(“Just a Bunch of Disks”),通过将多个磁盘分配在一个卷中,每次插入数据所生成的data part会以轮询的方式依次写入这些磁盘,该策略的优点:

  1. 通过直接追加磁盘的形式,可以便捷地扩展存储能力
  2. 在多线程并行访问多个不同磁盘时,可以提升读写速度
  3. 由于每个磁盘上的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/ │
└───────────┴─────────────┴────────────────────────────────────────────────────────┘
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335