一、背景
这个项目是一个监控系统,主要监控主机、网络设备、应用等。主机监控的数量有1500台左右,数量还在不断增长,加上网络设备和应用,目前总共监控的指标达到近40万个。
二、问题
一开始为了快速交付,采用的是MySQL来存储采集的指标数据,刚开始指标不是很多,采集频率也不是很高,业务还是比较稳当的。
但是随着时间的推移,接入的指标越来越多,问题开始暴露出来了,主要表现在以下几个方面:
1. MySQL的数据占用空间增长很快,一天差不多要增长2个G,不到1年时间指标历史表单表达到了500G+;
2. 数据备份变得很困难,特别是全量备份,需要花数天时间,备份的数据恢复也需要同等时间;
3. 一些统计功能出现超时,比如统计某些指标一天的最大值、最小值、平均值等;
三、改造方案
经过团队成员的初步讨论,改造方案有三个:
1. 基于mysql,进行分表;
2. 基于mongoDB,重新实现指标的存取逻辑;
3. 基于clickhouse,重写部分指标存取逻辑;
最终,我们敲定了方案3。
三、ClickHouse的特点
1. 列式数据库;
2. 稀疏索引;
3. 支持横向扩展;
4. 兼容SQL协议;
5. 支持mybatis;
6. 空间占用率低;
7. 统计效率高;
四、部署架构
采用了复制集模式,一分区,两复制集模式;
五、遇到的问题
1. 复制集、分区关系没有搞明白,导致数据混乱;
2. 清理zookeeper的数据,没有清理掉clickhouse的数据,导致数据不一致;
3. zookeeper崩溃,导致clickhouse变为只读模式,不能写入数据;
六、总结
1. clickhouse适合大批量写入的且不咋更新删除的业务;
2. 多分区会带来更复杂的配置,且对性能有较大影响;
3. 查询的时候尽量返回更少的字段,会提升性能;
4. 虽然是稀疏索引,但索引一样的尽量要有区分度才好;
5. 复制集模式,每个节点需要单独建表;
七、建表语句示例
```
CREATE TABLE demo.metric (
`id` Int64,
`instance_id` String,
`metric_id` Nullable(String),
`metric_name` String,
`type` Nullable(String),
`unit` Nullable(String),
`data` Nullable(String),
`period` Nullable(String),
`time` DateTime,
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/demo.metric ', '{replica}')
PARTITION BY toYYYYMM(time)
ORDER BY
(time,metric_name,instance_id) SETTINGS index_granularity = 8192;
```