一慰技、什么是Prometheus?
Prometheus是一套開源的監(jiān)控與告警系統(tǒng)组砚,基于Golang實(shí)現(xiàn)吻商,可用于對(duì)集群的狀態(tài)進(jìn)行實(shí)時(shí)的監(jiān)控。如今很多的公司與組織都在使用Prometheus糟红,項(xiàng)目具有非常成熟的開發(fā)者社區(qū)艾帐。
二、Prometheus的啟動(dòng)盆偿?
1柒爸、下載Prometheus,選擇合適的版本事扭,我選擇的是prometheus-2.17.0-rc.0.linux-amd64捎稚。https://prometheus.io/download/
2、配置prometheus路徑下的prometheus.yml文件求橄,我們可以在global中配置包括prometheus抓取數(shù)據(jù)今野、驗(yàn)證rule的時(shí)間間隔;在rule_files中配置rule_file的地址罐农;scrape_configs中設(shè)置數(shù)據(jù)源条霜。
global:
# How frequently to scrape targets by default.
[ scrape_interval: <duration> | default = 1m ]
# How long until a scrape request times out.
[ scrape_timeout: <duration> | default = 10s ]
# How frequently to evaluate rules.
[ evaluation_interval: <duration> | default = 1m ]
# The labels to add to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
[ <labelname>: <labelvalue> ... ]
# Rule files specifies a list of globs. Rules and alerts are read from
# all matching files.
rule_files:
[ - <filepath_glob> ... ]
# A list of scrape configurations.
scrape_configs:
[ - <scrape_config> ... ]
# Alerting specifies settings related to the Alertmanager.
alerting:
alert_relabel_configs:
[ - <relabel_config> ... ]
alertmanagers:
[ - <alertmanager_config> ... ]
# Settings related to the experimental remote write feature.
remote_write:
[ - <remote_write> ... ]
# Settings related to the experimental remote read feature.
remote_read:
[ - <remote_read> ... ]
3、輸入./prometheus啃匿,啟動(dòng)prometheus服務(wù)蛔外。prometheus的默認(rèn)端口為9090蛆楞,通過(guò)訪問(wèn)http://localhost:9090即可進(jìn)入prometheus的Web界面。
三夹厌、架構(gòu)
數(shù)據(jù)收集:
Prometheus收集方式有兩種方式豹爹,分別為pull和push。
1矛纹、若以pull的的方式臂聋,prometheus提供了Golang、Java或南、Scala孩等、Python、Ruby等語(yǔ)言的客戶端庫(kù)采够,在這里我簡(jiǎn)單介紹一下Go中的用法肄方。
package main
import (
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"math"
"math/rand"
"net/http"
"time"
)
var (
TestCounter = prometheus.NewCounter(prometheus.CounterOpts{
Name: "test_counter",
Help: "test_counter",
})
TestGauge = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "test_gauge",
Help: "test_gauge",
})
TestHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "test_histogram",
Help: "test_histogram",
Buckets: prometheus.LinearBuckets(20, 5, 5),
})
TestSummary = prometheus.NewSummary(prometheus.SummaryOpts{
Name: "test_summary",
Help: "test_summary",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
})
)
func main() {
prometheus.MustRegister(TestGauge)
prometheus.MustRegister(TestHistogram)
prometheus.MustRegister(TestSummary)
prometheus.MustRegister(TestCounter)
go func(){
i := 0.0
for {
TestGauge.Add(1)
TestCounter.Add(1)
TestHistogram.Observe(30 + math.Floor(float64(rand.Intn(120))*math.Sin(i*0.1))/10)
TestSummary.Observe(30 + math.Floor(float64(rand.Intn(120))*math.Sin(i*0.1))/10)
time.Sleep(2 * time.Second)
i += 1
}
}()
http.Handle("/metrics", promhttp.Handler())
err := http.ListenAndServe("localhost:2112", nil)
if err != nil {
fmt.Println(err)
}
}
首先我們創(chuàng)建prometheus中的數(shù)據(jù)類型,包括Counter蹬癌、Gauge权她、Histogram、Summary等逝薪,對(duì)它們感興趣的可以查看https://prometheus.io/docs/concepts/metric_types/隅要,接著將創(chuàng)建好的變量register到prometheus中并提供端口給prometheus來(lái)pull數(shù)據(jù)即可,這里需要我們?cè)谇懊嫠岬降膒rometheus.yml文件中配置好數(shù)據(jù)源董济。
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'myapp'
static_configs:
- targets: ['localhost:2112']
2步清、若以push的方式,則需要Pushgateway作為數(shù)據(jù)的收集器虏肾。首先我們需要下載Pushgateway https://prometheus.io/download/廓啊,解壓后到pushgateway的路徑下./pushgateway
啟動(dòng)服務(wù),默認(rèn)端口為9091询微。當(dāng)然崖瞭,我們需要和前面pull時(shí)一樣狂巢,在prometheus.yml文件中配置pushgateway的地址撑毛,這里不再贅述。
接著唧领,將我們想要發(fā)送到Prometheus的數(shù)據(jù)通過(guò)http的方式發(fā)送到pushgateway藻雌。
func main() {
ticker := time.NewTicker(2 * time.Second)
for range ticker.C{
for i := 1; i < 6; i++ {
cmd := exec.Command("bash", "-c",
"curl -XPOST --data-binary @job" + strconv.Itoa(i) + ".txt localhost:9091/metrics/job/" + strconv.Itoa(i))
err := cmd.Start()
if err != nil {
fmt.Println(err)
}
fmt.Println("sending data")
}
}
}
代碼使用了curl將數(shù)據(jù)發(fā)送到Pushgateway,job文件里的數(shù)據(jù)格式如下
slot{label1="xxx", label2="xxx"} 0
這是Prometheus中數(shù)據(jù)的最基本格式斩个,這樣的數(shù)據(jù)稱為一個(gè)metrics胯杭,其中“slot”是該metrics的name;{}中包括了metrics的label受啥,這些label是辨別不同metrics的標(biāo)志做个,在通過(guò)PromQL檢索時(shí)需要使用鸽心;而0則是該metrics的value,value隨時(shí)間的變化而變化居暖,metrics為時(shí)間序列數(shù)據(jù)顽频,舊數(shù)據(jù)將存儲(chǔ)在prometheus實(shí)現(xiàn)的TSDB中。
Prometheus server
這里主要介紹Prometheus的TSDB和HTTP server
TSDB
首先介紹數(shù)據(jù)在磁盤中的結(jié)構(gòu)
-bash-4.2$ tree data
data
├── 01EQWQPHYCYQV25DGKWDXX01P5 #block
│ ├── chunks
│ │ └── 000001 #compressed time series data
│ ├── index #query index
│ ├── meta.json #record block meta information
│ └── tombstones # temporarily tore deleted records
├── lock
├── queries.active
└── wal #write ahead log, prevent data loss
├── 00001561
├── 00001562
├── 00001563
├── 00001564
└── checkpoint.001560
└── 00000000
時(shí)序數(shù)據(jù)以block為單位持久化在磁盤里太闺,每個(gè)block存在chunks糯景、index、meta.json省骂、tombstones等文件蟀淮,其中
1、meta.json存儲(chǔ)了Block的元數(shù)據(jù)信息钞澳,包括Block的時(shí)間窗口怠惶、包含數(shù)據(jù)的數(shù)量、壓縮的次數(shù)等轧粟。
2甚疟、chunks包含了時(shí)間窗口內(nèi)的所有samples,是實(shí)際存儲(chǔ)數(shù)據(jù)的文件逃延。
3览妖、tombstones是暫存被刪除數(shù)據(jù)的文件,metrics被刪除時(shí)不會(huì)立刻從block中剔除揽祥,而是在tombstones中標(biāo)記讽膏,直到block中metrics全被刪除或者block被壓縮時(shí)真正刪除metrics。
4拄丰、index文件是用戶查詢數(shù)據(jù)時(shí)所依賴的索引文件府树。
5、wal的作用是防止數(shù)據(jù)丟失料按,當(dāng)prometheus意外崩潰時(shí)奄侠,重啟會(huì)首先將wal中數(shù)據(jù)讀入內(nèi)存。
每一個(gè)block可以看作一個(gè)小型數(shù)據(jù)庫(kù)载矿,其中index文件則是其索引垄潮,它使用了倒排索引,提高了Prometheus的查找效率闷盔。
┌────────────────────────────┬─────────────────────┐
│ magic(0xBAAAD700) <4b> │ version(1) <1 byte> │
├────────────────────────────┴─────────────────────┤
│ ┌──────────────────────────────────────────────┐ │
│ │ 1. Symbol Table │ │
│ ├──────────────────────────────────────────────┤ │
│ │ 2. Series │ │
│ ├──────────────────────────────────────────────┤ │
│ ├──────────────────────────────────────────────┤ │
│ │ 3. Postings 1 │ │
│ ├──────────────────────────────────────────────┤ │
│ │ ... │ │
│ ├──────────────────────────────────────────────┤ │
│ │ Postings N │ │
│ ├──────────────────────────────────────────────┤ │
│ ├──────────────────────────────────────────────┤ │
│ │ 4. Postings Table │ │
│ ├──────────────────────────────────────────────┤ │
│ │ 5. TOC │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
1弯洗、toc:index 文件中各部分的起始 offset;
2逢勾、postings offset table: 每個(gè)entry都保存了一對(duì)label的key和value以及對(duì)應(yīng)series list在posting中offset牡整;
3、posting: 每一個(gè)label pair都將對(duì)應(yīng)一個(gè)series list溺拱;(真正存儲(chǔ)series id list的地方)
4逃贝、series: 記錄了這個(gè)block里有哪些series谣辞,series的各個(gè)label(symbol table中已編號(hào)),每個(gè)series里有哪些chunk沐扳,每個(gè)chunk的開始時(shí)間和結(jié)束時(shí)間潦闲;
5、symbol table: 存儲(chǔ)block中所有series的Label key與Label value迫皱,并對(duì)它們編號(hào)歉闰,作用是壓縮index文件的大小。
HTTP Server
下面是Prometheus提供的一些HTTP API:
Instant queries: /api/v1/query?query=up&time=xxx
Range queries: /api/v1/query_range?query=up&start=xxx&end=xxx&step=xxx
Querying metadata: /api/v1/series
Getting label names: /api/v1/labels
Targets: /api/v1/targets
Rules: /api/v1/rules
Alerts: /api/v1/alerts
TSDB Admin: /api/v1/admin/tsdb (Snapshot卓起,Delete Series和敬,Clean Tombstones)
詳情可以看:https://prometheus.io/docs/prometheus/latest/querying/api/
除了在prometheus的web界面進(jìn)行操作,還可以直接通過(guò)http去調(diào)用Prometheus的API戏阅,獲取想要的數(shù)據(jù)昼弟。這里簡(jiǎn)單介紹一下這些API的用法,
1奕筐、前兩個(gè)分別是瞬時(shí)查詢舱痘、范圍查詢,通過(guò)設(shè)置metrics name和時(shí)間离赫,得到queries的結(jié)果芭逝。
2、Querying metadata返回符合label的series的信息渊胸,將metrics作為搜索條件可以查找所有對(duì)應(yīng)的series信息旬盯。
3、Getting label names可以返回所有的Label值翎猛。
4胖翰、返回所有prometheus的targets,包括prometheus自身切厘、pushgateway萨咳、node exporter等等。
5疫稿、Rules可以查看prometheus配置中的報(bào)警規(guī)則培他。使用PromQL完成報(bào)警規(guī)則的設(shè)置。
6而克、Alert可以返回所有的報(bào)警信息靶壮。
7怔毛、TSDB admin api暴露了操作數(shù)據(jù)的方法员萍,需要在prometheus中設(shè)置 —web.enable-admin-api才可以使用這些api,Snapshot的功能是為當(dāng)前的數(shù)據(jù)創(chuàng)建一個(gè)快照拣度,并返回?cái)?shù)據(jù)所在的路徑碎绎;Delete Series可以刪除指定的series螃壤,prometheus中被刪除的數(shù)據(jù)會(huì)被放在Tomstones中,直到Block被壓縮時(shí)才會(huì)刪除tomstones中的數(shù)據(jù)筋帖,當(dāng)然也可以調(diào)用clean tombstones接口來(lái)清理tomstones的數(shù)據(jù)奸晴。
PromQL
Prometheus提供了PromQL來(lái)對(duì)tsdb中的數(shù)據(jù)進(jìn)行查詢。在Prometheus的Web界面和Grafana中都能輸入PromQL進(jìn)行查詢日麸〖奶洌基礎(chǔ)的用法是輸入metrics名字與對(duì)應(yīng)想要的label,就能搜索到對(duì)應(yīng)的時(shí)序數(shù)據(jù)代箭。https://prometheus.io/docs/prometheus/latest/querying/basics/#functions