每分钟写入6亿条数据,携程监控系统Dashboard存储升级实践
一、 背景概述
框架Dashboard是一款携程内部历史悠久的自研监控产品,其定位是企业级Metrics监控场景,主要提供用户自定义Metrics接入,并基于此提供实时数据分析和视图展现的面板服务,提供可定制的基于时间序列的各类系统级性能数据和业务指标数据的看板。还可以提供灵活的数据收集接口、分布式的大容量存储和灵活的展现方式。
由于时间较早,那时候业界还没有像样的TSDB产品,类似Prometheus,InfluxDB都是后起之秀,所以Dashboard选型主要使用了HBase来存储Metrics数据。并且基于HBase来实现了TSDB,解决了一些HBase热点问题,同时将部分查询聚合下放到HBase,目的是优化其查询性能,目前看来总体方案依赖HBase/HDFS还是有点重。
近些年,随着携程监控All-in-One产品的提出。对于内部的Metrics存储统一也提出了新的要求。由于Dashboard查询目前存在的诸多问题以及Metrics统一的目标,我们决定替换升级Dashboard现有的HBase存储方案,并且在Metrics场景提供统一的查询层API。
二、 整体架构
Dashboard产品主要分了6个组件,包括dashboard-engine,dashboard-gateway,dashboard-writer,dashboard-HBase存储,dashboard-collector,dashboard-agent。目前实时写入数据行数6亿条/分钟,架构图如下:
- dashboard-engine是查询引擎。
- dashboard-gateway是提供给用户的查询界面。
- dashboard-writer是数据写入HBase的组件。
- dashboard-collector是基于Netty实现的Metrics数据收集的服务端。
- dashboard-agent是用户打点的客户端,支持sum,avg,max,min这几种聚合方式。
- dashboard-HBase是基于HBase实现的Metrics存储组件。
产品主要特性如下:
- 支持存储到分钟级的基于时间序列的数据。
- 单个指标数据可支持多个tag。
- 展现提供任意形式的视图同时可灵活基于tag进行分组。
三、 目前的存在问题
基于HBase的Metrics存储方案虽然具有良好的扩展性,比较高的吞吐,但是随着时间发展,已经不是优的TSDB方案了,可以归纳总结为如下几个痛点。
- 在TSDB场景查询慢,整体表现不如专业的TSDB。
- HBase热点问题,容易影响数据写入。
- HBase技术栈运维操作很重。
- 采用自研协议,不支持业界标准的Prometheus协议,无法和内部All-in-one监控产品较好的融合。
四、 替换难点
- 系统写入数据量大,6亿条/分钟。
- Dashboard数据缺乏治理,很多不合理高维的metrics数据,日志型数据,经过统计,整体基数达上千亿,这对TSDB不友好,这部分需要写入程序做治理。如图2所示是top20基数统计,有很多Metric基数已经上亿。
- Dashboard系统存在时间久,内部有很多程序调用,替换需要做到对用户透明。
五、 替换升级方案
从上面的架构来看,目前我们替换的主要是dashboard-writer和dashboard-HBase这两个核心的组件。为了对用户的平滑迁移,其他组件稍作改动,在dashboard-engine组件上对接新的查询API即可替换升级成功。对于用户侧,查询的界面dashboard-gateway和打点的客户端dashboard-agent还是原有的模式不变,因此整个的替换方案对用户透明。具体如下:
1.1 dashboard-HBase升级为dashboard-vm
存储从HBase方案替换成VictoriaMetrics+ClickHouse 混合存储方案:
- VictoriaMetrics是兼容主流Prometheus协议的TSDB,在TSDB场景下查询效果好,所以会接入绝大多数TSDB数据。
- 基于ClickHouse提供元数据服务,主要为界面的adhoc查询服务,原来这部分元数据是存储在HBase里面,新的方案采用ClickHouse来存储。元数据主要存储了measurement列表,measurement-tagKey列表,measurement-tagKey-tagValue列表这三种结构,目前在ClickHouse创建了一张表来存这些元数据。
本地表结构为:
CREATE TABLE hickwall.downsample_mtv
(`timestamp` DateTime,
`metricName` String,
`tagKey` String,
`tagValue` String,
`datasourceId` UInt8 DEFAULT 40)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/hickwall_cluster-{shard}/downsample_mtv', '{replica}')
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (timestamp, metricName, tagKey)
TTL timestamp + toIntervalDay(7)
SETTINGS index_granularity = 8192
相关文章