VictoriaMetrics高性能時序數(shù)據(jù)庫:Prometheus遠(yuǎn)程存儲方案
Prometheus單機(jī)存儲在生產(chǎn)環(huán)境跑到一定規(guī)模就會碰壁——單節(jié)點磁盤容量有限,TSDB默認(rèn)保留15天數(shù)據(jù),想存半年以上的監(jiān)控數(shù)據(jù)基本不現(xiàn)實。更麻煩的是Prometheus沒有原生的高可用方案,兩個Prometheus實例各采各的,數(shù)據(jù)不一致,查詢時還得靠Thanos或者聯(lián)邦來聚合。我們團(tuán)隊在2022年從Thanos遷移到VictoriaMetrics,集群穩(wěn)定運行至今,存儲成本降了約60%,查詢延遲從秒級降到毫秒級。這篇文章把部署、對接、調(diào)優(yōu)的完整流程寫出來。
一、概述
1.1 背景介紹
Prometheus的本地TSDB設(shè)計目標(biāo)是短期存儲,官方建議保留時間不超過15-30天。一旦監(jiān)控規(guī)模上去(比如我們的場景:200+節(jié)點、5萬+活躍時間序列、每秒采集樣本數(shù)約50萬),單機(jī)Prometheus的內(nèi)存和磁盤壓力就很大。常見的解決思路有三種:
Thanos:Sidecar模式對接Prometheus,數(shù)據(jù)上傳到對象存儲。架構(gòu)復(fù)雜,組件多(Sidecar、Store Gateway、Compactor、Query),運維成本高。
Cortex/Mimir:Grafana Labs的方案,依賴Consul/etcd做服務(wù)發(fā)現(xiàn),還需要對象存儲,部署門檻不低。
VictoriaMetrics:單二進(jìn)制部署,兼容PromQL,壓縮率比Prometheus高7-10倍,查詢速度快,資源消耗低。
我們實測對比過:同樣存儲3個月的監(jiān)控數(shù)據(jù),Prometheus+Thanos占用約800GB磁盤,VictoriaMetrics只用了120GB左右。查詢30天范圍的聚合數(shù)據(jù),Thanos需要3-5秒,VictoriaMetrics在200ms內(nèi)返回。
1.2 技術(shù)特點
極高的壓縮率:VictoriaMetrics使用自研的壓縮算法,實測壓縮比在10:1到15:1之間,比Prometheus的gorilla編碼高出數(shù)倍。100萬個時間序列、每15秒采集一次、存儲1個月,磁盤占用約20-30GB。
完全兼容PromQL:支持MetricsQL(PromQL的超集),現(xiàn)有的Grafana Dashboard和告警規(guī)則可以直接遷移,不用改查詢語句。額外支持了一些實用函數(shù)如range_median()、histogram_quantile()的優(yōu)化版本。
部署運維簡單:單機(jī)版就是一個二進(jìn)制文件,啟動參數(shù)配好就能跑。集群版也只有三個組件(vminsert、vmselect、vmstorage),沒有外部依賴,不需要Consul、etcd、Kafka這些中間件。
1.3 適用場景
Prometheus長期存儲:需要保留3個月以上監(jiān)控數(shù)據(jù)的場景,直接用remote_write對接VictoriaMetrics,Prometheus只保留短期數(shù)據(jù)做熱查詢。
大規(guī)模監(jiān)控集群:單集群超過500個節(jié)點、活躍時間序列超過1000萬的場景,VictoriaMetrics集群版可以水平擴(kuò)展,實測單集群支撐過5000萬活躍序列。
多租戶監(jiān)控平臺:集群版原生支持多租戶,通過URL路徑區(qū)分租戶,不同業(yè)務(wù)線的數(shù)據(jù)隔離存儲和查詢,適合平臺化的監(jiān)控中臺。
1.4 環(huán)境要求
| 組件 | 版本要求 | 說明 |
|---|---|---|
| 操作系統(tǒng) | CentOS 7+ / Ubuntu 18.04+ / Debian 10+ | 推薦Ubuntu 22.04 LTS |
| VictoriaMetrics | v1.93.0+ | 本文基于v1.102.0,建議用最新穩(wěn)定版 |
| Prometheus | v2.40+ | 需要支持remote_write協(xié)議 |
| Grafana | v9.0+ | 用于可視化查詢,需要Prometheus數(shù)據(jù)源 |
| CPU | 單機(jī)版4核+,集群版每節(jié)點8核+ | vmstorage對CPU要求不高,vmselect查詢時CPU消耗大 |
| 內(nèi)存 | 單機(jī)版8GB+,集群版每節(jié)點16GB+ | 內(nèi)存主要用于緩存和合并寫入 |
| 磁盤 | SSD推薦,容量按壓縮后估算 | HDD也能跑,但查詢延遲會高2-3倍 |
二、詳細(xì)步驟
2.1 準(zhǔn)備工作
2.1.1 系統(tǒng)檢查
# 檢查系統(tǒng)版本 cat /etc/os-release # 檢查CPU和內(nèi)存 nproc free -h # 檢查磁盤空間,數(shù)據(jù)盤建議預(yù)留200GB以上 df -h # 檢查系統(tǒng)時間同步狀態(tài),時序數(shù)據(jù)庫對時間敏感 timedatectl status # 如果時間不同步,配置chrony sudo apt install -y chrony sudo systemctlenable--now chrony chronyc tracking
2.1.2 創(chuàng)建用戶和目錄
# 創(chuàng)建專用用戶,不給登錄shell sudo useradd -r -s /sbin/nologin victoriametrics # 創(chuàng)建數(shù)據(jù)目錄,生產(chǎn)環(huán)境建議掛載獨立磁盤 sudo mkdir -p /data/victoriametrics sudo mkdir -p /etc/victoriametrics sudo mkdir -p /var/log/victoriametrics # 設(shè)置目錄權(quán)限 sudo chown -R victoriametrics:victoriametrics /data/victoriametrics sudo chown -R victoriametrics:victoriametrics /var/log/victoriametrics
2.1.3 下載安裝
# 設(shè)置版本號 VM_VERSION="v1.102.0" # 下載單機(jī)版 cd/tmp wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz # 解壓安裝 tar xzf victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz sudo mv victoria-metrics-prod /usr/local/bin/victoria-metrics sudo chmod +x /usr/local/bin/victoria-metrics # 驗證安裝 victoria-metrics --version
如果要部署集群版,需要額外下載集群組件:
# 下載集群版組件
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/victoria-metrics-linux-amd64-${VM_VERSION}-cluster.tar.gz
tar xzf victoria-metrics-linux-amd64-${VM_VERSION}-cluster.tar.gz
sudo mv vminsert-prod /usr/local/bin/vminsert
sudo mv vmselect-prod /usr/local/bin/vmselect
sudo mv vmstorage-prod /usr/local/bin/vmstorage
sudo chmod +x /usr/local/bin/vm{insert,select,storage}
# 下載vmagent(可選,替代Prometheus做采集)
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/vmutils-linux-amd64-${VM_VERSION}.tar.gz
tar xzf vmutils-linux-amd64-${VM_VERSION}.tar.gz
sudo mv vmagent-prod /usr/local/bin/vmagent
sudo mv vmctl-prod /usr/local/bin/vmctl
sudo chmod +x /usr/local/bin/vmagent /usr/local/bin/vmctl
2.2 核心配置
2.2.1 單機(jī)版部署
單機(jī)版適合中小規(guī)模場景(活躍時間序列500萬以內(nèi)),一個進(jìn)程搞定讀寫存儲。
# 創(chuàng)建systemd服務(wù)文件 sudo tee /etc/systemd/system/victoriametrics.service > /dev/null <'EOF' [Unit] Description=VictoriaMetrics single-node After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/victoria-metrics ? ? -storageDataPath=/data/victoriametrics ? ? -retentionPeriod=6 ? ? -httpListenAddr=:8428 ? ? -maxLabelsPerTimeseries=40 ? ? -search.maxUniqueTimeseries=5000000 ? ? -search.maxQueryDuration=60s ? ? -search.maxConcurrentRequests=32 ? ? -memory.allowedPercent=60 ? ? -dedup.minScrapeInterval=15s ? ? -loggerTimezone=Asia/Shanghai ? ? -loggerOutput=stderr ExecStop=/bin/kill?-s SIGTERM?$MAINPID Restart=always RestartSec=5 LimitNOFILE=65536 LimitNPROC=32000 [Install] WantedBy=multi-user.target EOF
參數(shù)說明(這些都是踩過坑調(diào)出來的):
-retentionPeriod=6:數(shù)據(jù)保留6個月,單位是月。改成6而不是180d,因為按月計算更直觀。
-memory.allowedPercent=60:限制VictoriaMetrics使用系統(tǒng)60%的內(nèi)存。默認(rèn)不限制,在16GB內(nèi)存的機(jī)器上跑,不設(shè)這個參數(shù)會把內(nèi)存吃滿導(dǎo)致OOM Killer干掉進(jìn)程。生產(chǎn)環(huán)境必須設(shè)。
-dedup.minScrapeInterval=15s:去重間隔設(shè)為采集間隔。如果你跑了兩個Prometheus做HA,兩邊都remote_write到VM,這個參數(shù)會自動去重,只保留一份數(shù)據(jù)。
-search.maxUniqueTimeseries=5000000:單次查詢最大返回的時間序列數(shù)。默認(rèn)30萬,在大集群里查{__name__=~".+"}這種寬泛查詢會報錯,按需調(diào)大。
-maxLabelsPerTimeseries=40:每個時間序列最大標(biāo)簽數(shù)。默認(rèn)30,有些業(yè)務(wù)自定義標(biāo)簽多的會超限,40基本夠用。
2.2.2 集群版部署
集群版由三個組件組成,生產(chǎn)環(huán)境建議每個組件至少2個實例:
vmstorage:存儲節(jié)點,負(fù)責(zé)數(shù)據(jù)持久化。部署在有SSD的機(jī)器上。
vminsert:寫入網(wǎng)關(guān),接收remote_write請求,按一致性哈希分發(fā)到vmstorage。無狀態(tài),可以隨意擴(kuò)縮。
vmselect:查詢網(wǎng)關(guān),接收PromQL查詢,從所有vmstorage拉數(shù)據(jù)聚合。無狀態(tài)。
假設(shè)我們有3臺機(jī)器:
| 角色 | IP | 端口 |
|---|---|---|
| vmstorage-1 | 10.0.1.11 | 8482(http) / 8400(vminsert) / 8401(vmselect) |
| vmstorage-2 | 10.0.1.12 | 8482(http) / 8400(vminsert) / 8401(vmselect) |
| vmstorage-3 | 10.0.1.13 | 8482(http) / 8400(vminsert) / 8401(vmselect) |
| vminsert | 10.0.1.21 | 8480 |
| vmselect | 10.0.1.22 | 8481 |
vmstorage服務(wù)配置(三臺存儲節(jié)點都部署):
sudo tee /etc/systemd/system/vmstorage.service > /dev/null <'EOF' [Unit] Description=VictoriaMetrics vmstorage After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmstorage ? ? -storageDataPath=/data/vmstorage ? ? -retentionPeriod=6 ? ? -httpListenAddr=:8482 ? ? -vminsertAddr=:8400 ? ? -vmselectAddr=:8401 ? ? -dedup.minScrapeInterval=15s ? ? -memory.allowedPercent=60 ? ? -search.maxUniqueTimeseries=5000000 ? ? -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
vminsert服務(wù)配置:
sudo tee /etc/systemd/system/vminsert.service > /dev/null <'EOF' [Unit] Description=VictoriaMetrics vminsert After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vminsert ? ? -httpListenAddr=:8480 ? ? -storageNode=10.0.1.11:8400,10.0.1.12:8400,10.0.1.13:8400 ? ? -replicationFactor=2 ? ? -maxLabelsPerTimeseries=40 ? ? -maxConcurrentInserts=32 ? ? -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
-replicationFactor=2表示每條數(shù)據(jù)寫入2個存儲節(jié)點。這樣掛掉1個vmstorage不丟數(shù)據(jù)。代價是存儲空間翻倍,但數(shù)據(jù)安全比省磁盤重要。
vmselect服務(wù)配置:
sudo tee /etc/systemd/system/vmselect.service > /dev/null <'EOF' [Unit] Description=VictoriaMetrics vmselect After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmselect ? ? -httpListenAddr=:8481 ? ? -storageNode=10.0.1.11:8401,10.0.1.12:8401,10.0.1.13:8401 ? ? -dedup.minScrapeInterval=15s ? ? -search.maxQueryDuration=120s ? ? -search.maxConcurrentRequests=32 ? ? -search.maxUniqueTimeseries=5000000 ? ? -replicationFactor=2 ? ? -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
vmselect的-replicationFactor=2要和vminsert一致,這樣查詢時vmselect知道數(shù)據(jù)有副本,會自動去重。
2.2.3 Prometheus remote_write對接
在Prometheus配置文件中添加remote_write段:
# /etc/prometheus/prometheus.yml global: scrape_interval:15s evaluation_interval:15s remote_write: -url:"http://10.0.1.21:8480/insert/0/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 capacity:20000 max_shards:30 min_shards:1 batch_send_deadline:5s write_relabel_configs: -source_labels:[__name__] regex:"go_.*" action:drop # 如果是單機(jī)版VM,URL改為: # url: "http://VM_IP:8428/api/v1/write"
URL路徑中的/insert/0/prometheus/里的0是租戶ID。單租戶場景用0就行,多租戶按業(yè)務(wù)分配不同的數(shù)字。
queue_config的參數(shù)是調(diào)過的:
max_samples_per_send=10000:每批發(fā)送1萬個樣本,默認(rèn)500太小,網(wǎng)絡(luò)開銷大。
max_shards=30:最大并發(fā)發(fā)送協(xié)程數(shù)。如果Prometheus采集量大(每秒超過10萬樣本),這個值要調(diào)到50以上。
batch_send_deadline=5s:批次發(fā)送超時。默認(rèn)5s夠用,網(wǎng)絡(luò)差的環(huán)境調(diào)到10s。
write_relabel_configs用來過濾不需要遠(yuǎn)程存儲的指標(biāo)。go_*這類Go運行時指標(biāo)一般不需要長期存儲,直接drop掉能減少約10-15%的寫入量。
2.2.4 vmagent替代Prometheus采集
如果你不需要Prometheus的告警功能(告警交給VMAlert或者獨立的Alertmanager),可以用vmagent替代Prometheus做采集。vmagent內(nèi)存占用只有Prometheus的1/3左右,支持同樣的服務(wù)發(fā)現(xiàn)和relabel配置。
# vmagent配置文件
sudo tee /etc/victoriametrics/vmagent.yml > /dev/null <'EOF'
global:
? scrape_interval: 15s
? external_labels:
? ? cluster: prod-bj
? ? env: production
scrape_configs:
? - job_name:?"node-exporter"
? ? static_configs:
? ? ? - targets:
? ? ? ? ? -?"10.0.1.11:9100"
? ? ? ? ? -?"10.0.1.12:9100"
? ? ? ? ? -?"10.0.1.13:9100"
? ? relabel_configs:
? ? ? - source_labels: [__address__]
? ? ? ? regex:?"(.+):.*"
? ? ? ? target_label: instance
? ? ? ? replacement:?"${1}"
? - job_name:?"kubernetes-pods"
? ? kubernetes_sd_configs:
? ? ? - role: pod
? ? ? ? api_server:?"https://10.0.1.100:6443"
? ? ? ? tls_config:
? ? ? ? ? ca_file: /etc/victoriametrics/ca.crt
? ? ? ? ? cert_file: /etc/victoriametrics/client.crt
? ? ? ? ? key_file: /etc/victoriametrics/client.key
? ? relabel_configs:
? ? ? - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
? ? ? ? action: keep
? ? ? ? regex:?true
? ? ? - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
? ? ? ? action: replace
? ? ? ? target_label: __metrics_path__
? ? ? ? regex: (.+)
? ? ? - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
? ? ? ? action: replace
? ? ? ? regex: ([^:]+)(?::d+)?;(d+)
? ? ? ? replacement:?$1:$2
? ? ? ? target_label: __address__
EOF
# vmagent systemd服務(wù) sudo tee /etc/systemd/system/vmagent.service > /dev/null <'EOF' [Unit] Description=VictoriaMetrics vmagent After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmagent ? ? -promscrape.config=/etc/victoriametrics/vmagent.yml ? ? -remoteWrite.url=http://10.0.1.21:8480/insert/0/prometheus/api/v1/write ? ? -remoteWrite.maxDiskUsagePerURL=1GB ? ? -remoteWrite.tmpDataPath=/data/vmagent-remotewrite-data ? ? -httpListenAddr=:8429 ? ? -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
-remoteWrite.maxDiskUsagePerURL=1GB這個參數(shù)很關(guān)鍵:當(dāng)遠(yuǎn)端VM不可用時,vmagent會把數(shù)據(jù)緩存到本地磁盤,等VM恢復(fù)后自動重傳。默認(rèn)不限制,磁盤可能被寫滿。設(shè)成1GB,按每秒10萬樣本算,大約能緩存2-3小時的數(shù)據(jù),足夠覆蓋大多數(shù)故障恢復(fù)時間。
2.3 啟動和驗證
2.3.1 啟動服務(wù)
# 單機(jī)版啟動 sudo systemctl daemon-reload sudo systemctlenable--now victoriametrics sudo systemctl status victoriametrics # 集群版啟動(按順序:先storage,再insert和select) # 在三臺存儲節(jié)點上執(zhí)行 sudo systemctl daemon-reload sudo systemctlenable--now vmstorage sudo systemctl status vmstorage # 在vminsert節(jié)點執(zhí)行 sudo systemctlenable--now vminsert sudo systemctl status vminsert # 在vmselect節(jié)點執(zhí)行 sudo systemctlenable--now vmselect sudo systemctl status vmselect # 啟動vmagent(如果使用) sudo systemctlenable--now vmagent
2.3.2 功能驗證
# 1. 檢查VM單機(jī)版健康狀態(tài)
curl -s http://localhost:8428/health
# 預(yù)期輸出:空響應(yīng),HTTP 200
# 2. 檢查集群各組件
curl -s http://10.0.1.11:8482/health # vmstorage
curl -s http://10.0.1.21:8480/health # vminsert
curl -s http://10.0.1.22:8481/health # vmselect
# 3. 手動寫入測試數(shù)據(jù)(單機(jī)版)
curl -d'test_metric{job="test",instance="localhost"} 42'
http://localhost:8428/api/v1/import/prometheus
# 4. 查詢驗證
curl -s'http://localhost:8428/api/v1/query?query=test_metric'| python3 -m json.tool
# 預(yù)期看到 test_metric 值為42
# 5. 集群版寫入測試(通過vminsert)
curl -d'test_metric{job="test"} 42'
http://10.0.1.21:8480/insert/0/prometheus/api/v1/import/prometheus
# 6. 集群版查詢測試(通過vmselect)
curl -s'http://10.0.1.22:8481/select/0/prometheus/api/v1/query?query=test_metric'| python3 -m json.tool
# 7. 檢查Prometheus remote_write是否正常
# 在Prometheus的Web UI(:9090)查看 Status -> Runtime & Build Information
# 確認(rèn) remote_storage_samples_total 計數(shù)器在增長
# 8. 查看VM的內(nèi)置監(jiān)控指標(biāo)
curl -s http://localhost:8428/metrics | grep vm_rows_inserted_total
# 這個計數(shù)器應(yīng)該在持續(xù)增長
2.3.3 Grafana數(shù)據(jù)源配置
在Grafana中添加Prometheus類型的數(shù)據(jù)源:
單機(jī)版:URL填http://VM_IP:8428
集群版:URL填http://vmselect_IP:8481/select/0/prometheus
其他配置保持默認(rèn)即可。添加完數(shù)據(jù)源后,導(dǎo)入一個Dashboard驗證查詢是否正常,推薦導(dǎo)入ID為11176的VictoriaMetrics官方Dashboard。
三、示例代碼和配置
3.1 完整配置示例
3.1.1 集群版生產(chǎn)級部署配置
以下是我們線上跑了14個月的集群配置,3個vmstorage + 2個vminsert + 2個vmselect,承載約800萬活躍時間序列,每秒寫入約80萬樣本。
vmstorage啟動參數(shù)(生產(chǎn)調(diào)優(yōu)版):
# 文件路徑:/etc/systemd/system/vmstorage.service [Unit] Description=VictoriaMetrics vmstorage - production After=network.target Wants=network-online.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmstorage -storageDataPath=/data/vmstorage -retentionPeriod=6 -httpListenAddr=:8482 -vminsertAddr=:8400 -vmselectAddr=:8401 -dedup.minScrapeInterval=15s -memory.allowedPercent=60 -search.maxUniqueTimeseries=10000000 -snapshotsMaxAge=72h -finalMergeDelay=10s -bigMergeConcurrency=2 -smallMergeConcurrency=4 -loggerTimezone=Asia/Shanghai -loggerOutput=stderr -loggerLevel=INFO Restart=always RestartSec=5 LimitNOFILE=131072 LimitNPROC=32000 # 防止OOM Killer殺掉進(jìn)程 OOMScoreAdjust=-500 # 限制core dump大小 LimitCORE=0 [Install] WantedBy=multi-user.target
參數(shù)解釋:
-bigMergeConcurrency=2:大合并并發(fā)數(shù)。默認(rèn)值等于CPU核數(shù)的一半,在32核機(jī)器上會起16個合并線程,IO壓力很大。設(shè)成2,合并速度慢一點但不影響讀寫性能。
-smallMergeConcurrency=4:小合并并發(fā)數(shù)。小合并頻繁但每次數(shù)據(jù)量小,4個線程夠用。
-snapshotsMaxAge=72h:快照最大保留時間。做備份時會創(chuàng)建快照,72小時后自動清理,防止忘記刪快照撐爆磁盤。
-finalMergeDelay=10s:最終合并延遲。數(shù)據(jù)寫入后等10秒再做最終合并,減少寫放大。
vminsert生產(chǎn)配置:
# 文件路徑:/etc/systemd/system/vminsert.service [Unit] Description=VictoriaMetrics vminsert - production After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vminsert -httpListenAddr=:8480 -storageNode=10.0.1.11:8400,10.0.1.12:8400,10.0.1.13:8400 -replicationFactor=2 -maxLabelsPerTimeseries=40 -maxConcurrentInserts=64 -insert.maxQueueDuration=30s -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=131072 [Install] WantedBy=multi-user.target
vmselect生產(chǎn)配置:
# 文件路徑:/etc/systemd/system/vmselect.service [Unit] Description=VictoriaMetrics vmselect - production After=network.target [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmselect -httpListenAddr=:8481 -storageNode=10.0.1.11:8401,10.0.1.12:8401,10.0.1.13:8401 -dedup.minScrapeInterval=15s -search.maxQueryDuration=120s -search.maxConcurrentRequests=64 -search.maxUniqueTimeseries=10000000 -search.maxSamplesPerQuery=500000000 -search.cacheTimestampOffset=5m -replicationFactor=2 -selectNode=10.0.1.22:8481 -loggerTimezone=Asia/Shanghai Restart=always RestartSec=5 LimitNOFILE=131072 [Install] WantedBy=multi-user.target
-search.maxSamplesPerQuery=500000000:單次查詢最大樣本數(shù)。默認(rèn)10億,但如果有人寫了個查全量數(shù)據(jù)的PromQL,會把vmselect內(nèi)存打爆。5億是個比較安全的上限。
3.1.2 vmagent生產(chǎn)級采集配置
# 文件路徑:/etc/victoriametrics/vmagent-prod.yml
# 這個配置在我們的K8s集群上跑了10個月,采集200+節(jié)點
global:
scrape_interval:15s
scrape_timeout:10s
external_labels:
cluster:prod-bj-01
env:production
region:cn-north-1
scrape_configs:
# 節(jié)點監(jiān)控
-job_name:"node-exporter"
file_sd_configs:
-files:
-/etc/victoriametrics/targets/nodes/*.yml
refresh_interval:30s
metric_relabel_configs:
# 丟棄不需要的高基數(shù)指標(biāo)
-source_labels:[__name__]
regex:"node_scrape_collector_duration_seconds|node_scrape_collector_success"
action:drop
# 丟棄不需要的文件系統(tǒng)指標(biāo)(tmpfs等)
-source_labels:[__name__,fstype]
regex:"node_filesystem_.+;(tmpfs|devtmpfs|rootfs)"
action:drop
# Kubernetes API Server
-job_name:"kubernetes-apiservers"
kubernetes_sd_configs:
-role:endpoints
scheme:https
tls_config:
ca_file:/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file:/var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
-source_labels:[__meta_kubernetes_namespace,__meta_kubernetes_service_name,__meta_kubernetes_endpoint_port_name]
action:keep
regex:default;kubernetes;https
# kubelet和cAdvisor
-job_name:"kubelet"
kubernetes_sd_configs:
-role:node
scheme:https
tls_config:
ca_file:/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify:true
bearer_token_file:/var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
-action:labelmap
regex:__meta_kubernetes_node_label_(.+)
-job_name:"cadvisor"
kubernetes_sd_configs:
-role:node
scheme:https
tls_config:
ca_file:/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify:true
bearer_token_file:/var/run/secrets/kubernetes.io/serviceaccount/token
metrics_path:/metrics/cadvisor
metric_relabel_configs:
# cAdvisor指標(biāo)非常多,只保留核心的
-source_labels:[__name__]
regex:"container_cpu_usage_seconds_total|container_memory_working_set_bytes|container_memory_rss|container_network_receive_bytes_total|container_network_transmit_bytes_total|container_fs_usage_bytes|container_fs_limit_bytes"
action:keep
# 自動發(fā)現(xiàn)帶prometheus注解的Pod
-job_name:"kubernetes-pods"
kubernetes_sd_configs:
-role:pod
relabel_configs:
-source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action:keep
regex:true
-source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_scheme]
action:replace
target_label:__scheme__
regex:(https?)
-source_labels:[__meta_kubernetes_pod_annotation_prometheus_io_path]
action:replace
target_label:__metrics_path__
regex:(.+)
-source_labels:[__address__,__meta_kubernetes_pod_annotation_prometheus_io_port]
action:replace
regex:([^:]+)(?::d+)?;(d+)
replacement:$1:$2
target_label:__address__
-action:labelmap
regex:__meta_kubernetes_pod_label_(.+)
-source_labels:[__meta_kubernetes_namespace]
action:replace
target_label:namespace
-source_labels:[__meta_kubernetes_pod_name]
action:replace
target_label:pod
3.1.3 vmctl數(shù)據(jù)遷移腳本
從Prometheus遷移歷史數(shù)據(jù)到VictoriaMetrics:
#!/bin/bash # 文件名:migrate_prometheus_to_vm.sh # 功能:將Prometheus歷史數(shù)據(jù)遷移到VictoriaMetrics # 實測遷移200GB Prometheus數(shù)據(jù)耗時約4小時 set-euo pipefail PROM_URL="http://10.0.1.50:9090" VM_URL="http://10.0.1.21:8480/insert/0/prometheus" # 遷移時間范圍:最近90天 START_TIME=$(date -d"90 days ago"+%s) END_TIME=$(date +%s) LOG_FILE="/var/log/victoriametrics/migration_$(date +%Y%m%d_%H%M%S).log" echo"[$(date)] 開始遷移 Prometheus -> VictoriaMetrics"| tee -a"$LOG_FILE" echo"[$(date)] 時間范圍:$(date -d @$START_TIME)->$(date -d @$END_TIME)"| tee -a"$LOG_FILE" # vmctl native模式遷移,速度最快 /usr/local/bin/vmctl prometheus --prom-snapshot="/data/prometheus/snapshots/$(ls -t /data/prometheus/snapshots/ | head -1)" --vm-addr="$VM_URL" --vm-concurrency=8 --vm-batch-size=200000 2>&1 | tee -a"$LOG_FILE" # 如果沒有快照,用API模式遷移(速度慢但不需要停Prometheus) # /usr/local/bin/vmctl prometheus # --prom-addr="$PROM_URL" # --vm-addr="$VM_URL" # --prom-start="$START_TIME" # --prom-end="$END_TIME" # --vm-concurrency=4 # --prom-concurrency=4 # 2>&1 | tee -a "$LOG_FILE" EXIT_CODE=$? if[$EXIT_CODE-eq 0 ];then echo"[$(date)] 遷移完成"| tee -a"$LOG_FILE" else echo"[$(date)] 遷移失敗,退出碼:$EXIT_CODE"| tee -a"$LOG_FILE" exit$EXIT_CODE fi # 驗證遷移結(jié)果:對比源和目標(biāo)的時間序列數(shù) PROM_SERIES=$(curl -s"$PROM_URL/api/v1/label/__name__/values"| python3 -c"import sys,json; print(len(json.load(sys.stdin)['data']))") VM_SERIES=$(curl -s"http://10.0.1.22:8481/select/0/prometheus/api/v1/label/__name__/values"| python3 -c"import sys,json; print(len(json.load(sys.stdin)['data']))") echo"[$(date)] Prometheus指標(biāo)數(shù):$PROM_SERIES, VictoriaMetrics指標(biāo)數(shù):$VM_SERIES"| tee -a"$LOG_FILE"
3.2 實際應(yīng)用案例
案例一:多租戶監(jiān)控平臺
場景描述:公司有5個業(yè)務(wù)線,每個業(yè)務(wù)線有獨立的Prometheus集群,需要統(tǒng)一存儲和查詢。用VictoriaMetrics集群版的多租戶功能,每個業(yè)務(wù)線分配一個租戶ID。
實現(xiàn)配置:
# 業(yè)務(wù)線A的Prometheus配置 # 租戶ID: 1 remote_write: -url:"http://vminsert-lb:8480/insert/1/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 max_shards:20 # 業(yè)務(wù)線B的Prometheus配置 # 租戶ID: 2 remote_write: -url:"http://vminsert-lb:8480/insert/2/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 max_shards:20 # 業(yè)務(wù)線C的Prometheus配置 # 租戶ID: 3 remote_write: -url:"http://vminsert-lb:8480/insert/3/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 max_shards:15
Grafana中為每個業(yè)務(wù)線配置獨立的數(shù)據(jù)源:
業(yè)務(wù)線A數(shù)據(jù)源URL: http://vmselect-lb:8481/select/1/prometheus 業(yè)務(wù)線B數(shù)據(jù)源URL: http://vmselect-lb:8481/select/2/prometheus 業(yè)務(wù)線C數(shù)據(jù)源URL: http://vmselect-lb:8481/select/3/prometheus # 如果需要跨租戶查詢(運維團(tuán)隊全局視圖): 全局?jǐn)?shù)據(jù)源URL: http://vmselect-lb:8481/select/multitenant/prometheus
跨租戶查詢需要vmselect啟動時加-search.tenantCacheExpireDuration=10s參數(shù)。實測跨5個租戶查詢聚合數(shù)據(jù),延遲在500ms以內(nèi)。
案例二:Prometheus HA + VictoriaMetrics去重
場景描述:兩個Prometheus實例采集相同的目標(biāo)做高可用,都remote_write到VictoriaMetrics。VM自動去重,Grafana只查VM。
架構(gòu):
Prometheus-A (10.0.1.51) ──remote_write──> VictoriaMetrics
↑
Prometheus-B (10.0.1.52) ──remote_write──────┘
│
Grafana <─┘ (查詢)
Prometheus-A配置:
# /etc/prometheus/prometheus.yml (Prometheus-A) global: scrape_interval:15s external_labels: replica:prom-a cluster:prod remote_write: -url:"http://10.0.1.21:8480/insert/0/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 max_shards:30
Prometheus-B配置(只有replica標(biāo)簽不同):
# /etc/prometheus/prometheus.yml (Prometheus-B) global: scrape_interval:15s external_labels: replica:prom-b cluster:prod remote_write: -url:"http://10.0.1.21:8480/insert/0/prometheus/api/v1/write" queue_config: max_samples_per_send:10000 max_shards:30
VictoriaMetrics端配置-dedup.minScrapeInterval=15s,VM會按時間戳對齊去重,兩個Prometheus寫入的相同指標(biāo)只保留一份。去重后存儲量和單Prometheus一樣,但任何一個Prometheus掛了數(shù)據(jù)都不會斷。
我們線上用這個方案跑了一年多,中間Prometheus-A因為機(jī)器故障重啟過3次,每次都是Prometheus-B無縫接管,Grafana上看不到任何數(shù)據(jù)斷點。
四、最佳實踐和注意事項
4.1 最佳實踐
4.1.1 存儲容量規(guī)劃
容量規(guī)劃是上線前必須做的事,算錯了要么磁盤爆滿丟數(shù)據(jù),要么浪費錢買了用不上的SSD。
計算公式:
磁盤用量 = 活躍時間序列數(shù) × 每個樣本壓縮后大小 × 每天采樣次數(shù) × 保留天數(shù) × 副本數(shù) 實際例子: - 活躍時間序列:500萬 - 采集間隔:15秒(每天5760次采樣) - 每個樣本壓縮后大?。杭s0.5-1.5字節(jié)(VM的壓縮率) - 保留6個月(180天) - 副本數(shù):2 磁盤用量 = 5,000,000 × 1.0 × 5,760 × 180 × 2 = 約10.4TB
實際使用中,VM的壓縮率會隨數(shù)據(jù)特征變化。我們的經(jīng)驗值:
計數(shù)器類指標(biāo)(Counter):壓縮后每樣本約0.4字節(jié)
儀表盤類指標(biāo)(Gauge):壓縮后每樣本約1.0-1.5字節(jié)
直方圖類指標(biāo)(Histogram):壓縮后每樣本約0.8字節(jié)
# 查看當(dāng)前VM的實際壓縮率 curl -s http://localhost:8428/api/v1/status/tsdb | python3 -m json.tool # 查看磁盤使用詳情 curl -s http://localhost:8428/internal/force_flush du -sh /data/victoriametrics/data/
生產(chǎn)環(huán)境建議磁盤預(yù)留30%的余量,因為合并操作會臨時占用額外空間。
4.1.2 降采樣(Downsampling)配置
長期存儲的數(shù)據(jù)不需要保持原始精度。比如3個月前的數(shù)據(jù),1分鐘一個點就夠了,沒必要保留15秒的原始精度。VictoriaMetrics企業(yè)版支持降采樣,開源版可以用vmalert做recording rules實現(xiàn)類似效果。
# vmalert降采樣規(guī)則
# 文件路徑:/etc/victoriametrics/downsampling_rules.yml
groups:
-name:downsampling_5m
interval:5m
rules:
# 將CPU使用率降采樣為5分鐘平均值
-record:cpu_usage_avg:5m
expr:avg_over_time(node_cpu_seconds_total{mode!="idle"}[5m])
# 將內(nèi)存使用降采樣為5分鐘平均值
-record:memory_usage_avg:5m
expr:avg_over_time(node_memory_MemAvailable_bytes[5m])
# 將網(wǎng)絡(luò)流量降采樣為5分鐘速率
-record:network_receive_rate:5m
expr:rate(node_network_receive_bytes_total[5m])
-name:downsampling_1h
interval:1h
rules:
# 1小時粒度的聚合,用于月度報表
-record:cpu_usage_avg:1h
expr:avg_over_time(cpu_usage_avg:5m[1h])
-record:memory_usage_avg:1h
expr:avg_over_time(memory_usage_avg:5m[1h])
4.1.3 去重策略
跑雙Prometheus HA時,去重配置不對會導(dǎo)致數(shù)據(jù)翻倍或者查詢結(jié)果不穩(wěn)定。
# VM端去重配置(單機(jī)版或vmstorage) -dedup.minScrapeInterval=15s # vmselect端也要配(集群版) -dedup.minScrapeInterval=15s
去重的原理:VM按時間戳對齊,同一個時間序列在同一個時間窗口(15秒)內(nèi)只保留一個樣本。兩個Prometheus采集同一個target,時間戳可能差幾百毫秒,但在15秒窗口內(nèi)會被合并。
踩坑經(jīng)驗:-dedup.minScrapeInterval的值必須等于或大于Prometheus的scrape_interval。如果Prometheus是15秒采集,這里設(shè)成10秒,會導(dǎo)致部分?jǐn)?shù)據(jù)沒被去重,查詢時出現(xiàn)毛刺。
4.1.4 性能調(diào)優(yōu)
# 1. 調(diào)整系統(tǒng)參數(shù) # 增大文件描述符限制 echo"victoriametrics soft nofile 131072">> /etc/security/limits.conf echo"victoriametrics hard nofile 131072">> /etc/security/limits.conf # 調(diào)整內(nèi)核參數(shù) cat >> /etc/sysctl.conf <'EOF' # VictoriaMetrics優(yōu)化 vm.max_map_count = 262144 net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.core.netdev_max_backlog = 65535 EOF sudo sysctl -p # 2. 磁盤IO優(yōu)化(如果用的是SSD) echo?none > /sys/block/sda/queue/scheduler echo256 > /sys/block/sda/queue/nr_requests
4.1.5 安全加固
# 1. 用Nginx做反向代理,加上基礎(chǔ)認(rèn)證 sudo apt install -y nginx apache2-utils # 創(chuàng)建認(rèn)證文件 sudo htpasswd -bc /etc/nginx/.htpasswd vmuser'StrongP@ssw0rd' # Nginx配置 cat > /etc/nginx/conf.d/victoriametrics.conf <'NGINX_EOF' upstream vmselect { ? ? server 10.0.1.22:8481; ? ? keepalive 32; } upstream vminsert { ? ? server 10.0.1.21:8480; ? ? keepalive 32; } server { ? ? listen 443 ssl; ? ? server_name vm.example.com; ? ? ssl_certificate /etc/nginx/ssl/vm.crt; ? ? ssl_certificate_key /etc/nginx/ssl/vm.key; ? ??# 查詢接口 - 需要認(rèn)證 ? ? location /select/ { ? ? ? ? auth_basic?"VictoriaMetrics"; ? ? ? ? auth_basic_user_file /etc/nginx/.htpasswd; ? ? ? ? proxy_pass http://vmselect; ? ? ? ? proxy_set_header Host?$host; ? ? ? ? proxy_read_timeout 120s; ? ? } ? ??# 寫入接口 - 用IP白名單替代認(rèn)證(Prometheus不支持basic auth的remote_write) ? ? location /insert/ { ? ? ? ? allow 10.0.1.0/24; ? ? ? ? deny all; ? ? ? ? proxy_pass http://vminsert; ? ? ? ? proxy_set_header Host?$host; ? ? } ? ??# 禁止訪問管理接口 ? ? location /internal/ { ? ? ? ? deny all; ? ? } } NGINX_EOF
# 2. 限制VM的監(jiān)聽地址(不要監(jiān)聽0.0.0.0) # 在systemd服務(wù)文件中修改 -httpListenAddr=10.0.1.11:8482 # 只監(jiān)聽內(nèi)網(wǎng)IP # 3. 關(guān)閉不需要的API端點 # vmselect啟動參數(shù)加上 -search.resetCacheAuthKey=your-secret-key # 重置緩存需要密鑰 -deleteAuthKey=your-delete-key # 刪除數(shù)據(jù)需要密鑰 -snapshotAuthKey=your-snapshot-key # 創(chuàng)建快照需要密鑰
# 4. 配置防火墻規(guī)則 # 只允許特定IP訪問VM端口 sudo ufw allow from 10.0.1.0/24 to any port 8428 sudo ufw allow from 10.0.1.0/24 to any port 8480 sudo ufw allow from 10.0.1.0/24 to any port 8481 sudo ufw allow from 10.0.1.0/24 to any port 8482 sudo ufw deny 8428 sudo ufw deny 8480 sudo ufw deny 8481 sudo ufw deny 8482
4.2 注意事項
4.2.1 配置注意事項
改retentionPeriod之前先算好磁盤:把保留時間從3個月改成12個月,磁盤用量會翻4倍。改之前先用上面的公式算一下,確認(rèn)磁盤夠用再改。改完重啟VM,舊數(shù)據(jù)不會立即刪除,要等到過期時間才會清理。
-retentionPeriod改小不會立即釋放空間,VM的數(shù)據(jù)按月份分目錄存儲,只有整個月份過期后才會刪除對應(yīng)目錄。比如從6個月改成3個月,要等3個月后才能看到空間釋放。
集群版擴(kuò)容vmstorage節(jié)點后,新節(jié)點不會自動均衡舊數(shù)據(jù)。新數(shù)據(jù)會均勻分布到所有節(jié)點,但舊數(shù)據(jù)還在原來的節(jié)點上。如果需要均衡,得用vmctl做數(shù)據(jù)遷移。
vminsert的-storageNode列表順序很重要,改變順序會導(dǎo)致數(shù)據(jù)分布變化。擴(kuò)容時只在末尾追加新節(jié)點,不要調(diào)整已有節(jié)點的順序。
4.2.2 常見錯誤
| 錯誤現(xiàn)象 | 原因分析 | 解決方案 |
|---|---|---|
| cannot allocate memory VM進(jìn)程被OOM Kill | 沒設(shè)-memory.allowedPercent,VM吃滿了系統(tǒng)內(nèi)存 | 設(shè)置-memory.allowedPercent=60,同時檢查是否有大范圍查詢 |
| too many open files | 文件描述符限制太低 | systemd配置LimitNOFILE=131072,同時改/etc/security/limits.conf |
| Prometheus remote_write報context deadline exceeded | VM寫入隊列滿了或網(wǎng)絡(luò)延遲高 | 增大vminsert的-maxConcurrentInserts,檢查網(wǎng)絡(luò)延遲 |
| 查詢返回the number of unique timeseries exceeds | 查詢命中的時間序列數(shù)超過限制 | 調(diào)大-search.maxUniqueTimeseries,或優(yōu)化PromQL縮小查詢范圍 |
| 集群版查詢數(shù)據(jù)不一致 | vmselect的-replicationFactor和vminsert不一致 | 確保兩端的-replicationFactor值相同 |
| 磁盤空間持續(xù)增長不釋放 | 快照沒清理或合并操作積壓 | 檢查/data/vmstorage/snapshots/目錄,清理過期快照 |
4.2.3 兼容性問題
PromQL兼容性:VictoriaMetrics兼容99%的PromQL語法,但有少數(shù)邊界情況行為不同。比如rate()函數(shù)在數(shù)據(jù)有間斷時,VM和Prometheus的插值邏輯略有差異。遷移后建議對比關(guān)鍵告警規(guī)則的查詢結(jié)果。
remote_write協(xié)議版本:VM支持Prometheus remote_write v1和v2協(xié)議。Prometheus 2.47+默認(rèn)用v2,如果VM版本低于1.93.0不支持v2,需要在Prometheus端強(qiáng)制用v1:remote_write.protocol_version: 1。
Grafana版本:Grafana 9.x以上對VM的兼容性最好。8.x版本在使用$__rate_interval變量時可能有問題,建議升級到9.x+。
五、故障排查和監(jiān)控
5.1 故障排查
5.1.1 日志查看
# 查看VM單機(jī)版日志 sudo journalctl -u victoriametrics -f --no-pager # 查看集群各組件日志 sudo journalctl -u vmstorage -f --no-pager sudo journalctl -u vminsert -f --no-pager sudo journalctl -u vmselect -f --no-pager # 查看最近的錯誤日志 sudo journalctl -u victoriametrics --since"1 hour ago"| grep -i"error|warn|fatal" # 查看vmagent日志 sudo journalctl -u vmagent -f --no-pager # 如果配置了日志文件輸出 tail -f /var/log/victoriametrics/vm.log | grep -v"DEBUG"
5.1.2 常見問題排查
問題一:數(shù)據(jù)寫入延遲,Prometheus remote_write隊列積壓
# 在Prometheus端查看remote_write隊列狀態(tài) curl -s http://localhost:9090/api/v1/query?query=prometheus_remote_storage_pending_samples | python3 -m json.tool # 如果pending_samples持續(xù)增長,說明寫入速度跟不上 # 檢查vminsert的寫入延遲 curl -s http://10.0.1.21:8480/metrics | grep vm_http_request_duration # 檢查vmstorage的磁盤IO iostat -x 1 5 # 檢查網(wǎng)絡(luò)延遲 ping -c 10 10.0.1.21
解決方案:
增大Prometheus的max_shards(從30調(diào)到50)
檢查vmstorage所在機(jī)器的磁盤IO,如果IO util超過80%,考慮換SSD或增加存儲節(jié)點
檢查vminsert到vmstorage的網(wǎng)絡(luò)延遲,超過5ms就需要排查網(wǎng)絡(luò)問題
用write_relabel_configs過濾掉不需要的指標(biāo),減少寫入量
問題二:查詢慢,Grafana Dashboard加載超時
# 查看vmselect的查詢延遲分布 curl -s http://10.0.1.22:8481/metrics | grep vm_request_duration_seconds # 查看慢查詢?nèi)罩荆ㄐ枰獑訒r加參數(shù)) # -search.logSlowQueryDuration=5s 記錄超過5秒的查詢 sudo journalctl -u vmselect | grep"slow query" # 查看當(dāng)前正在執(zhí)行的查詢 curl -s http://10.0.1.22:8481/api/v1/status/active_queries | python3 -m json.tool
解決方案:
優(yōu)化PromQL查詢,避免{__name__=~".+"}這種全量匹配
縮小查詢時間范圍,30天的數(shù)據(jù)用step=5m而不是默認(rèn)的15s
增加vmselect實例數(shù),用Nginx做負(fù)載均衡
檢查是否有高基數(shù)標(biāo)簽(比如把request_id作為標(biāo)簽),用/api/v1/status/tsdb查看top標(biāo)簽
問題三:磁盤空間不足,VM拒絕寫入
# 查看磁盤使用 df -h /data/victoriametrics/ # 查看各月份數(shù)據(jù)目錄大小 du -sh /data/victoriametrics/data/big/*/ du -sh /data/victoriametrics/data/small/*/ # 檢查是否有未清理的快照 ls -la /data/victoriametrics/snapshots/ # 強(qiáng)制清理過期數(shù)據(jù)(謹(jǐn)慎操作) curl -s http://localhost:8428/internal/force_merge?partition_prefix=2024_01
解決方案:
清理過期快照:curl http://localhost:8428/snapshot/delete_all
縮短保留時間(臨時措施):改-retentionPeriod后重啟
擴(kuò)容磁盤或增加存儲節(jié)點
檢查是否有異常的高基數(shù)指標(biāo)占用大量空間
問題四:集群節(jié)點故障恢復(fù)
# 檢查集群狀態(tài) # vminsert會自動跳過不可用的vmstorage節(jié)點 curl -s http://10.0.1.21:8480/metrics | grep vm_rpc_connection # 查看哪些存儲節(jié)點不可用 curl -s http://10.0.1.21:8480/metrics | grep"vm_rpc_dial_errors_total" # 節(jié)點恢復(fù)后,檢查數(shù)據(jù)完整性 # 如果replicationFactor=2,單節(jié)點故障不丟數(shù)據(jù) # 節(jié)點恢復(fù)后自動重新加入集群,不需要手動操作
5.1.3 調(diào)試模式
# 開啟詳細(xì)日志 # 在systemd服務(wù)文件中修改啟動參數(shù) -loggerLevel=INFO # 改為 -loggerLevel=DEBUG(排查完記得改回來) # 開啟慢查詢?nèi)罩?-search.logSlowQueryDuration=5s # 開啟HTTP請求日志(會產(chǎn)生大量日志,只在排查時開啟) -httpLogRequests # 查看內(nèi)部狀態(tài) curl -s http://localhost:8428/api/v1/status/tsdb | python3 -m json.tool curl -s http://localhost:8428/api/v1/status/active_queries | python3 -m json.tool # 查看內(nèi)存使用詳情 curl -s http://localhost:8428/metrics | grep process_resident_memory_bytes curl -s http://localhost:8428/metrics | grep go_memstats_alloc_bytes
5.2 性能監(jiān)控
5.2.1 關(guān)鍵指標(biāo)監(jiān)控
# 寫入速率(每秒插入的行數(shù)) curl -s http://localhost:8428/metrics | grep vm_rows_inserted_total # 查詢速率 curl -s http://localhost:8428/metrics | grep vm_http_requests_total # 活躍時間序列數(shù) curl -s http://localhost:8428/metrics | grep vm_cache_entries.*metricName # 磁盤使用 curl -s http://localhost:8428/metrics | grep vm_data_size_bytes # 合并操作狀態(tài) curl -s http://localhost:8428/metrics | grep vm_merges
5.2.2 監(jiān)控指標(biāo)說明
| 指標(biāo)名稱 | 正常范圍 | 告警閾值 | 說明 |
|---|---|---|---|
| vm_rows_inserted_total rate | 根據(jù)采集量而定 | 突降50%以上 | 寫入速率突降說明數(shù)據(jù)源異常 |
| vm_slow_queries_total | 0-5/min | >10/min | 慢查詢過多說明需要優(yōu)化查詢或擴(kuò)容 |
| process_resident_memory_bytes |
|
>80%系統(tǒng)內(nèi)存 |
內(nèi)存使用過高有OOM風(fēng)險 |
|
| vm_free_disk_space_bytes | >20%總?cè)萘?/td> | <10%總?cè)萘?/td> | 磁盤空間不足會導(dǎo)致拒絕寫入 |
| vm_merge_need_free_disk_space | 0 | >0 | 合并操作因磁盤不足被阻塞 |
| vm_http_request_duration_seconds p99 | <1s | >5s | 查詢延遲過高影響用戶體驗 |
5.2.3 Prometheus監(jiān)控規(guī)則
# 文件路徑:/etc/prometheus/rules/victoriametrics.yml
groups:
-name:victoriametrics_alerts
interval:30s
rules:
# 寫入速率突降
-alert:VMWriteRateDrop
expr:|
rate(vm_rows_inserted_total[5m]) < 0.5 * rate(vm_rows_inserted_total[5m] offset 1h)
? ? ? ??for:10m
? ? ? ??labels:
? ? ? ? ??severity:warning
? ? ? ??annotations:
? ? ? ? ??summary:"VictoriaMetrics寫入速率下降超過50%"
? ? ? ? ??description:"當(dāng)前寫入速率:?{{ $value | humanize }}/s"
? ? ??# 磁盤空間不足
? ? ??-alert:VMDiskSpaceLow
? ? ? ??expr:|
? ? ? ? ? vm_free_disk_space_bytes / vm_available_disk_space_bytes < 0.15
? ? ? ??for:5m
? ? ? ??labels:
? ? ? ? ??severity:critical
? ? ? ??annotations:
? ? ? ? ??summary:"VictoriaMetrics磁盤剩余空間不足15%"
? ? ? ? ??description:"剩余空間:?{{ $value | humanize1024 }}B"
? ? ??# 查詢延遲過高
? ? ??-alert:VMSlowQueries
? ? ? ??expr:|
? ? ? ? ? histogram_quantile(0.99, rate(vm_request_duration_seconds_bucket[5m])) > 5
for:10m
labels:
severity:warning
annotations:
summary:"VictoriaMetrics P99查詢延遲超過5秒"
# 內(nèi)存使用過高
-alert:VMHighMemoryUsage
expr:|
process_resident_memory_bytes{job="victoriametrics"} / node_memory_MemTotal_bytes > 0.8
for:5m
labels:
severity:critical
annotations:
summary:"VictoriaMetrics內(nèi)存使用超過80%"
# vmstorage節(jié)點不可用(集群版)
-alert:VMStorageNodeDown
expr:|
up{job="vmstorage"} == 0
for:2m
labels:
severity:critical
annotations:
summary:"vmstorage節(jié)點{{ $labels.instance }}不可用"
# 合并操作積壓
-alert:VMMergeQueueFull
expr:|
vm_assisted_merges_total > 0
for:15m
labels:
severity:warning
annotations:
summary:"VictoriaMetrics合并操作積壓,可能影響查詢性能"
5.3 備份與恢復(fù)
5.3.1 備份策略
#!/bin/bash
# 文件名:vm_backup.sh
# VictoriaMetrics備份腳本
# 利用VM的快照功能做一致性備份
set-euo pipefail
VM_URL="http://localhost:8428"
BACKUP_DIR="/backup/victoriametrics"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="${BACKUP_DIR}/${DATE}"
RETENTION_DAYS=7
LOG_FILE="/var/log/victoriametrics/backup_${DATE}.log"
log() {
echo"[$(date '+%Y-%m-%d %H:%M:%S')]$1"| tee -a"$LOG_FILE"
}
log"開始VictoriaMetrics備份"
# 1. 創(chuàng)建快照
SNAPSHOT_RESPONSE=$(curl -s"${VM_URL}/snapshot/create")
SNAPSHOT_NAME=$(echo"$SNAPSHOT_RESPONSE"| python3 -c"import sys,json; print(json.load(sys.stdin)['snapshot'])")
log"創(chuàng)建快照:$SNAPSHOT_NAME"
SNAPSHOT_PATH="/data/victoriametrics/snapshots/${SNAPSHOT_NAME}"
# 2. 用rsync備份快照目錄
mkdir -p"$BACKUP_PATH"
rsync -a --progress"$SNAPSHOT_PATH/""$BACKUP_PATH/"2>&1 | tee -a"$LOG_FILE"
log"備份完成:$BACKUP_PATH"
# 3. 刪除快照(釋放空間)
curl -s"${VM_URL}/snapshot/delete?snapshot=${SNAPSHOT_NAME}"| tee -a"$LOG_FILE"
log"快照已刪除:$SNAPSHOT_NAME"
# 4. 清理過期備份
find"$BACKUP_DIR"-maxdepth 1 -typed -mtime +${RETENTION_DAYS}-execrm -rf {} ;
log"已清理${RETENTION_DAYS}天前的備份"
# 5. 記錄備份大小
BACKUP_SIZE=$(du -sh"$BACKUP_PATH"| awk'{print $1}')
log"備份大小:$BACKUP_SIZE"
5.3.2 恢復(fù)流程
# 1. 停止VictoriaMetrics服務(wù)
sudo systemctl stop victoriametrics
# 2. 備份當(dāng)前數(shù)據(jù)目錄(以防恢復(fù)出問題)
sudo mv /data/victoriametrics /data/victoriametrics.bak.$(date +%Y%m%d)
# 3. 恢復(fù)備份數(shù)據(jù)
sudo mkdir -p /data/victoriametrics
sudo rsync -a /backup/victoriametrics/20250115_020000/ /data/victoriametrics/
# 4. 修復(fù)權(quán)限
sudo chown -R victoriametrics:victoriametrics /data/victoriametrics
# 5. 啟動服務(wù)
sudo systemctl start victoriametrics
# 6. 驗證數(shù)據(jù)完整性
sleep 10
curl -s'http://localhost:8428/api/v1/query?query=count({__name__=~".+"})'| python3 -m json.tool
# 對比恢復(fù)前后的時間序列總數(shù)
# 7. 確認(rèn)恢復(fù)成功后刪除舊數(shù)據(jù)備份
# sudo rm -rf /data/victoriametrics.bak.*
六、總結(jié)
6.1 技術(shù)要點回顧
單機(jī)版一個二進(jìn)制搞定:中小規(guī)模(500萬活躍序列以內(nèi))用單機(jī)版就夠了,部署簡單,運維成本低。別一上來就搞集群,單機(jī)版的性能已經(jīng)超過大多數(shù)場景的需求。
集群版三組件架構(gòu):vminsert/vmselect/vmstorage各司其職,vminsert和vmselect無狀態(tài)可以隨意擴(kuò)縮,vmstorage有狀態(tài)需要謹(jǐn)慎操作。擴(kuò)容vmstorage時只在storageNode列表末尾追加,不要改變已有節(jié)點順序。
去重機(jī)制是HA的基礎(chǔ):-dedup.minScrapeInterval必須等于或大于Prometheus的采集間隔,vminsert和vmselect兩端都要配。雙Prometheus HA + VM去重的方案經(jīng)過生產(chǎn)驗證,穩(wěn)定可靠。
內(nèi)存限制必須設(shè):-memory.allowedPercent=60是生產(chǎn)環(huán)境必配參數(shù),不設(shè)的話VM會吃滿內(nèi)存被OOM Killer干掉。這個坑我們踩過兩次。
壓縮率決定存儲成本:實測壓縮比在10:1到15:1之間,同樣的數(shù)據(jù)量,VM的磁盤占用只有Prometheus的1/7到1/10。做容量規(guī)劃時按每樣本1字節(jié)估算比較安全。
remote_write調(diào)優(yōu)不能忽略:Prometheus端的queue_config參數(shù)直接影響寫入性能,max_shards和max_samples_per_send要根據(jù)實際采集量調(diào)整,默認(rèn)值在大規(guī)模場景下不夠用。
6.2 進(jìn)階學(xué)習(xí)方向
VMAlert + 告警管理:用VMAlert替代Prometheus的告警評估,支持從VictoriaMetrics直接查詢數(shù)據(jù)做告警判斷,減少對Prometheus的依賴。VMAlert支持recording rules和alerting rules,語法和Prometheus完全兼容。
學(xué)習(xí)資源:https://docs.victoriametrics.com/vmalert/
實踐建議:先把現(xiàn)有的Prometheus告警規(guī)則遷移到VMAlert,驗證告警結(jié)果一致后再下線Prometheus的告警功能
VictoriaMetrics Operator(K8s部署):如果你的基礎(chǔ)設(shè)施跑在Kubernetes上,用VM Operator可以通過CRD聲明式管理VM集群,自動處理擴(kuò)縮容、滾動更新、備份等操作。
學(xué)習(xí)資源:https://docs.victoriametrics.com/operator/
實踐建議:先在測試集群部署VMCluster CRD,熟悉各參數(shù)后再遷移生產(chǎn)環(huán)境
VictoriaLogs(日志存儲):VictoriaMetrics團(tuán)隊推出的日志存儲方案,和VictoriaMetrics指標(biāo)存儲配合使用,可以在Grafana中實現(xiàn)指標(biāo)和日志的關(guān)聯(lián)查詢。目前還在快速迭代中,適合技術(shù)預(yù)研。
學(xué)習(xí)資源:https://docs.victoriametrics.com/victorialogs/
6.3 參考資料
VictoriaMetrics官方文檔- 最權(quán)威的參考,更新及時
VictoriaMetrics GitHub- 源碼和Issue討論
Prometheus remote_write配置- remote_write協(xié)議和參數(shù)說明
VictoriaMetrics vs Thanos性能對比- 官方的Benchmark數(shù)據(jù)
附錄
A. 命令速查表
# 單機(jī)版啟停
sudo systemctl start victoriametrics
sudo systemctl stop victoriametrics
sudo systemctl restart victoriametrics
sudo systemctl status victoriametrics
# 集群版啟停(按順序)
sudo systemctl start vmstorage && sudo systemctl start vminsert && sudo systemctl start vmselect
sudo systemctl stop vmselect && sudo systemctl stop vminsert && sudo systemctl stop vmstorage
# 健康檢查
curl -s http://localhost:8428/health # 單機(jī)版
curl -s http://localhost:8480/health # vminsert
curl -s http://localhost:8481/health # vmselect
curl -s http://localhost:8482/health # vmstorage
# 查看TSDB狀態(tài)
curl -s http://localhost:8428/api/v1/status/tsdb | python3 -m json.tool
# 查看活躍查詢
curl -s http://localhost:8428/api/v1/status/active_queries | python3 -m json.tool
# 創(chuàng)建快照(備份用)
curl -s http://localhost:8428/snapshot/create
# 刪除所有快照
curl -s http://localhost:8428/snapshot/delete_all
# 強(qiáng)制合并(減少磁盤碎片)
curl -s http://localhost:8428/internal/force_merge
# 手動寫入測試數(shù)據(jù)
curl -d'test{job="test"} 123'http://localhost:8428/api/v1/import/prometheus
# 查詢測試
curl -s'http://localhost:8428/api/v1/query?query=up'| python3 -m json.tool
# 查看標(biāo)簽值
curl -s'http://localhost:8428/api/v1/label/__name__/values'| python3 -m json.tool
# 刪除時間序列(需要配置deleteAuthKey)
curl -d'match[]={job="test"}'http://localhost:8428/api/v1/admin/tsdb/delete_series
B. 配置參數(shù)詳解
| 參數(shù) | 默認(rèn)值 | 建議值 | 說明 |
|---|---|---|---|
| -retentionPeriod | 1(月) | 按需設(shè)置 | 數(shù)據(jù)保留時間,支持月(數(shù)字)和天(如180d) |
| -memory.allowedPercent | 不限制 | 60 | 內(nèi)存使用上限百分比,生產(chǎn)必設(shè) |
| -dedup.minScrapeInterval | 0(不去重) | 等于scrape_interval | HA場景必設(shè) |
| -search.maxUniqueTimeseries | 300000 | 5000000-10000000 | 單次查詢最大時間序列數(shù) |
| -search.maxQueryDuration | 30s | 60s-120s | 單次查詢最大執(zhí)行時間 |
| -search.maxConcurrentRequests | 16 | 32-64 | 最大并發(fā)查詢數(shù) |
| -maxLabelsPerTimeseries | 30 | 40 | 每個時間序列最大標(biāo)簽數(shù) |
| -replicationFactor | 1 | 2 | 集群版數(shù)據(jù)副本數(shù) |
| -bigMergeConcurrency | CPU/2 | 2 | 大合并并發(fā)數(shù),降低IO壓力 |
| -smallMergeConcurrency | CPU/2 | 4 | 小合并并發(fā)數(shù) |
| -search.logSlowQueryDuration | 5s | 5s | 慢查詢?nèi)罩鹃撝?/td> |
| -remoteWrite.maxDiskUsagePerURL | 不限制 | 1GB | vmagent本地緩存上限 |
C. 術(shù)語表
| 術(shù)語 | 英文 | 解釋 |
|---|---|---|
| 時間序列 | Time Series | 由指標(biāo)名和標(biāo)簽集唯一標(biāo)識的一組按時間排列的數(shù)據(jù)點 |
| 活躍序列 | Active Time Series | 最近一個采集周期內(nèi)有新數(shù)據(jù)寫入的時間序列 |
| 遠(yuǎn)程寫入 | Remote Write | Prometheus將采集的數(shù)據(jù)通過HTTP協(xié)議發(fā)送到遠(yuǎn)端存儲的機(jī)制 |
| 去重 | Deduplication | 多個數(shù)據(jù)源寫入相同時間序列時,只保留一份數(shù)據(jù)的機(jī)制 |
| 降采樣 | Downsampling | 將高精度數(shù)據(jù)聚合為低精度數(shù)據(jù)以節(jié)省存儲空間 |
| 高基數(shù) | High Cardinality | 某個標(biāo)簽的取值種類非常多(如用戶ID),導(dǎo)致時間序列數(shù)爆炸 |
| 合并 | Merge/Compaction | 將多個小數(shù)據(jù)塊合并為大數(shù)據(jù)塊,提高查詢效率和壓縮率 |
| 租戶 | Tenant | 集群版中用于隔離不同業(yè)務(wù)數(shù)據(jù)的邏輯單元,通過URL路徑中的數(shù)字ID區(qū)分 |
| 快照 | Snapshot | 數(shù)據(jù)目錄的只讀副本,用于一致性備份 |
| MetricsQL | MetricsQL | VictoriaMetrics擴(kuò)展的查詢語言,兼容PromQL并增加了額外函數(shù) |
-
集群
+關(guān)注
關(guān)注
0文章
142瀏覽量
17659 -
數(shù)據(jù)庫
+關(guān)注
關(guān)注
7文章
4018瀏覽量
68327 -
Prometheus
+關(guān)注
關(guān)注
0文章
36瀏覽量
2053
原文標(biāo)題:VictoriaMetrics高性能時序數(shù)據(jù)庫:Prometheus遠(yuǎn)程存儲方案
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
Prometheus的架構(gòu)原理從“監(jiān)控”談起
Prometheus的基本原理與開發(fā)指南
prometheus做監(jiān)控服務(wù)的整個流程介紹
看西部數(shù)據(jù)企業(yè)級存儲解決方案如何助力遠(yuǎn)程辦公
使用Thanos+Prometheus+Grafana構(gòu)建監(jiān)控系統(tǒng)
監(jiān)控神器:Prometheus
prometheus下載安裝教程
Prometheus存儲引擎簡析
基于Prometheus開源的完整監(jiān)控解決方案
從零入門Prometheus:構(gòu)建企業(yè)級監(jiān)控與報警系統(tǒng)的最佳實踐指南
詳解Prometheus的數(shù)據(jù)類型
使用VictoriaMetrics的Prometheus遠(yuǎn)程存儲方案
評論