写在最前
prometheus断定高基数的三种办法
- prometheus tsdb的统计接口
- prometheus 能够依据query_log中的queryPreparationTime来定位
- prometheus 通过count by 统计
什么是高基数 high-cardinality
基数狭义上是指汇合中值的数量
在数据库畛域,基数是指数据库的特定列或字段中蕴含的惟一值的数量。
工夫序列数据集的基数通常由每个独自的索引列的基数的叉积定义
高基数示例:工业物联网
- 设想一下一个IoT场景,其中某个采石场中有大量的重型设施在开采岩石,破碎岩石和分选岩石。
- 假如有10,000件设施,每个设施带有100个传感器,运行10个不同的固件版本,散布在100个站点中:
timestamp | temper | mem_f | equipm | senso | firmwar | sit | (lat,long) | ature | ree | ent_id | r_id | e_version | e_id |--------------------+-------+--------+-------------------+------+-----------2019-04-04 | 85.2 | 10.2 | 1 | 98 | 1.0 | 4 | (x,y) 09:00:00 | | | | | | | 2019-04-04 | 68.8 | 16.0 | 72 | 12 | 1.1 | 20 | (x1,y1)09:00:00 | | | | | | | 2019-04-04 | 100.0 | 0.0 | 34 | 58 | 2.1 | 55 | (x2,y2) 09:00:00 | | | | | | | 2019-04-04 | 84.8 | 9.8 | 12 | 75 | 1.4 | 81 | (x3,y3)09:00:00 | | | | | | | 2019-04-04 | 68.7 | 16.0 | 89 | 4 | 2.1 | 13 | (x4,y4)09:00:00 | | | | | | | ... | | | | | | |
- 而后,此数据集的最大基数变为10亿[10,000 x 100 x 10 x 100]。
- 当初,假如设施也能够挪动,并且咱们想存储准确的GPS地位(纬度,经度),并将其用作索引的元数据进行查问。因为(lat,long)是一个间断字段(与诸如equipment_id之类的离散字段绝对),所以通过在地位上建设索引,此数据集的最大基数当初无限大(无界)。
高基数查问
- 艰深的说就是返回的series或者查问到的series数量过多
- 查问体现进去返回工夫较长,对应调用服务端资源较多的查问
- 数量多少算多 10w~100w
- 个别咱们定义在1小时内的range_query 响应工夫超过
3秒
则认为较重了
prometheus断定高基数的三种办法
- prometheus tsdb的统计接口
- prometheus 能够依据query_log中的queryPreparationTime来定位
- prometheus 通过count by 统计
办法一 tsdb的统计接口
- http://192.168.43.114:9090/ts...
- 接口地址
/api/v1/status/tsdb
- 是基于内存中的倒排索引 算最大堆取 top10
10个最多的metric_name排序
seriesCountByMetricName: [{name: "namedprocess_namegroup_memory_bytes", value: 245},…]0: {name: "namedprocess_namegroup_memory_bytes", value: 245}1: {name: "namedprocess_namegroup_states", value: 245}2: {name: "mysql_global_status_commands_total", value: 148}3: {name: "namedprocess_namegroup_context_switches_total", value: 98}4: {name: "namedprocess_namegroup_cpu_seconds_total", value: 98}5: {name: "node_scrape_collector_success", value: 80}6: {name: "node_scrape_collector_duration_seconds", value: 80}7: {name: "namedprocess_namegroup_threads_wchan", value: 73}8: {name: "namedprocess_namegroup_thread_cpu_seconds_total", value: 66}9: {name: "namedprocess_namegroup_thread_io_bytes_total", value: 66}
思考采集器如果不是prometheus怎么办?
- 比方m3db没有提供高基数查问的接口
源码解析
// Stats calculates the cardinality statistics from postings.func (p *MemPostings) Stats(label string) *PostingsStats { const maxNumOfRecords = 10 var size uint64 p.mtx.RLock() metrics := &maxHeap{} labels := &maxHeap{} labelValueLength := &maxHeap{} labelValuePairs := &maxHeap{} numLabelPairs := 0 metrics.init(maxNumOfRecords) labels.init(maxNumOfRecords) labelValueLength.init(maxNumOfRecords) labelValuePairs.init(maxNumOfRecords) for n, e := range p.m { if n == "" { continue } labels.push(Stat{Name: n, Count: uint64(len(e))}) numLabelPairs += len(e) size = 0 for name, values := range e { if n == label { metrics.push(Stat{Name: name, Count: uint64(len(values))}) } labelValuePairs.push(Stat{Name: n + "=" + name, Count: uint64(len(values))}) size += uint64(len(name)) } labelValueLength.push(Stat{Name: n, Count: size}) } p.mtx.RUnlock() return &PostingsStats{ CardinalityMetricsStats: metrics.get(), CardinalityLabelStats: labels.get(), LabelValueStats: labelValueLength.get(), LabelValuePairsStats: labelValuePairs.get(), NumLabelPairs: numLabelPairs, }}
办法二 query_log
- 能够依据log中的queryPreparationTime来定位
办法三 通过count统计
topk(5,count({__name__=~".+"}) by(__name__) > 100 )
- scrape_samples_scraped 能够阐明job的instance维度sample数量,也可能定位