列数据库或者“分析型数据库”已经不是什么新鲜的事物了,比如AWS的Redshift,比如今天要谈到的Clickhouse。由于其数据存储方法专注于“列”,因此其先天就具有“统计快”的特点。
当然这篇博并不会展开说列数据库的优劣,那可能一写就得几万字…这篇博主要说明我在使用Clickhouse的时候发现的一个问题:硬盘使用率。
在基本同样的使用环境下,我发现mysql数据库和clickhouse数据的硬盘占用空间差距非常大,大约是1:3。我一度怀疑是不是因为列存储占用的空间就是大于行存储,但是转念一想,数据都那么多,只是链接方式不用罢了,不应该会有那么大的空间区别。
于是第一个操作就是要找出哪些table占用了大量的空间:(参考Altinity Knowledge Base的文章)
SELECT database, table, formatReadableSize(sum(data_compressed_bytes) AS size) AS compressed, formatReadableSize(sum(data_uncompressed_bytes) AS usize) AS uncompressed, round(usize / size, 2) AS compr_rate, sum(rows) AS rows, count() AS part_count FROM system.parts WHERE (active = 1) AND (database LIKE '%') AND (table LIKE '%') GROUP BY database, table ORDER BY size DESC;
运行后发现,真正存储数据的table并没有占用太大的空间,相反地,system下的query_thread_log, query_log, trace_log, metric_log占用了非常大的空间,尤其是query_thread_log,1个TB。
参考Clickhouse的官方文档解释,这些log都是各有各的用途,默认也都是开启的。而且Clickhouse并不会自动地删除这些数据。所以在不调优的情况下,这些表是越来越大的,而且请求得越快,硬盘涨得也就越快。
所以必须对这些参数进行调优。主要思路有如下三种:
第一种,狠一点,直接掐断这个功能,即连表都不创建。
第二种,保留表,通过用户配置文件控制是否启用。
第三种,保留表并且持续启用,但是修改表的TTL值,让其周期性地过期。
我个人觉得混合使用这三种策略比较适合:
- 对于没什么必要的表,直接掐断,比如metric_log, text_log, part_log之类,当然这里的“非必要”是因使用情况而异的,有些对debug要求非常大的使用场景下,很多表都是有价值表里的。
- 对于query_log这个表,我认为很有必要保留。通过这个表可以很容易写一写query来判断数据库使用中的查询速度和具体使用情况。所以我建议对于query_log这个表,使用增加TTL的方法。
- 对于query_thread_log这个“重度使用”的表,我建议保留其表的创建,但是默认disable。这个表提供了比query_log更详细的信息,如果需要特别debug时,可以通过配置文件打开。
具体的写法请参照Altinity Knowledge Base的这篇文章,我觉得写的非常清晰,这里就不再赘述了。
