作者:任坤
现居珠海,先后担任专职 Oracle 和 MySQL DBA,现在主要负责 MySQL、mongoDB 和 Redis 维护工作。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
1、背景
线上某clickhouse集群,最早采用SAS机器,后来因为容量不足又陆续添加了4台SATA机器。
最后的架构演变为5分片 * 2副本,包括6台SAS和4台SATA机器,导致读写延迟非常高,引发业务方频繁抱怨。
经协商后决定将硬盘升级为SSD,然而预算被卡的很紧,原本采购的4台SSD机器最终被砍成了1台,最终只能被迫采用SSD + SATA的冷热存储分离架构。
我们将新采购的机器SSD硬盘拆卸,分散部署到6台已有的SATA机器上,将SSD挂载到/data,SATA挂载到/data1。
ck最新写入的数据先落到SSD,稍后根据配置的规则自动将冷数据迁移到SATA。
2、线上实践
部署ck集群,6台机器采用3分片 * 2副本,config.xml的path变量设置为
ck默认会分别创建1个名为default的磁盘和存储策略,磁盘由config.xml的path设定,存储策略default默认选择path设置的磁盘,可通过system.disks和system.storage_policies查看。
我们要做的是手工创建1个存储策略,指定热盘和冷盘路径,让数据先落热盘,然后根据设置规则自动迁移到冷盘。
为每个ck节点新建配置文件/etc/clickhouse-server/config.d/storage.xml,为了节省篇幅直接上截图。
先为系统中的存储目录打上磁盘标签,再创建一个名为moving_from_ssd_to_hdd的存储策略,按顺序引用热盘和冷盘标签。
以上配置是先将数据写到/data/clickhouse_ssd,随后再慢慢迁移到/data1/clickhouse_hdd。
表数据以part为单位迁移,move_factor取值范围[0,1),值越大则会越快速的将part迁移到冷盘,也可以手工迁移指定part,比如alter table tab_name move part ‘xxxx_xx’ to volume cold;
创建表时加上storage_policy = 'moving_from_ssd_to_hdd’选项,就可以完成冷热存储分离设置。
线上运行了小半年,既解决了读写延迟问题,又很好的节省了硬件成本。
前几天维护需要挨个重启ck集群实例,重启第1个实例就遇到如下错误,
2022.10.31 17:32:06.569278 [ 33885 ] {} <Error> Application: DB::Exception: "default" disk path should be provided in <path> not it <storage_configuration>: Cannot attach table `system`.`query_thread_log` from metadata file /data/clickhouse_ssd/store/db1/db144952-38ab-46ee-af64-e84158d35c12/query_thread_log.sql from query ATTACH TABLE system.query_thread_log UUID '8205cfb0-ccd4-45cf-bdaa-ffce82a84a7d' (`event_date` Date, `event_time` DateTime, `event_time_microseconds` DateTime64(6), `query_start_time` DateTime, `query_start_time_microseconds` DateTime64(6), `query_duration_ms` UInt64, `read_rows`
多番尝试后最终搜索到解决方法 https://github.com/ClickHouse/ClickHouse/issues/11678,这句话点出了根本原因,
It is not allowed to use identical paths for different disks, the path for any non-default disks should not collide with the default path
config.xml的path标签已经将/data/clickhouse_ssd目录声明为default,上面的storage.xml重复声明了/data/clickhouse_ssd目录,导致重启时出现判断冲突。
解决方案:修改storage.xml配置文件,修改后内容如下,
此时的system.storage_policies表返回信息如下,
再次重启ck实例,这次成功执行。