背景
当前单节点Prometheus集中存储多个集群数据,数据单点且索引性能低下,官方架构问题无法横向扩展优化。
目的
- 需要分布式数据存储,支持并发查询,优化查询性能
- 可以兼容Prometheus写入或服务端中转写入
- 可支持数据副本(次要)
架构
VictoriaMetrics是一个快速、高效和可扩展的时序数据库,可作为Prometheus的长期存储(long-term storage)。
VictoriaMetrics支持PromQL查询语言,也支持Influxdb行协议,对当前主流的时序协议支持比较好。
单实例的victoriametric只有一个进程。
集群版的victoriametrics有3类进程,即3类微服务组成:
- vmstorage: 数据存储节点,负责存储时序数据;
- vmselect: 数据查询节点,负责接收用户查询请求,向vmstorage查询时序数据;
- vminsert: 数据插入节点,负责接收用户插入请求,向vmstorage写入时序数据;
在部署时可以按照需求,不同的微服务部署不同的副本,以应对业务需求:
- 若数据量比较大,部署较多的vmstorage副本;
- 若查询请求比较多,部署较多的vmselect副本;
- 若插入请求比较多,部署较多的vminsert副本;
集群中vmselect、vminsert节点都是无状态的,唯一有状态的是vmstorage。
部署模式
单节点版
直接运行一个二进制文件,既可以运行,官方建议采集数据点(data points)低于100w/s,推荐VM单节点版,简单好维护,但不支持告警。
集群版
支持数据水平拆分,把功能拆分为vmstorage、 vminsert、vmselect,如果要替换Prometheus,还需要vmagent、vmalert。
集群版主要特点:
- 支持单节点版本的所有功能。
- 性能和容量水平扩展。
- 支持时间序列数据的多个独立命名空间(多租户)。
- 支持多副本。
集群部署
简述
本次实验采用3台 vmstorage 作为存储集群,2台 vminsert 实现写入服务高可用,2台 vmselect 实现查询服务高可用,写入数据采用2副本分散存储;
待VM集群就绪后,将对接现有Prometheus,实现现有监控远程写入,并接入现有grafana实现数据查询。
集群信息
节点IP | 节点角色 | 备注 |
---|---|---|
192.168.7.33 | vmstorage、vminsert、vmselect | |
192.168.7.34 | vmstorage、vminsert、vmselect | |
192.168.7.35 | vmstorage | |
192.168.7.81 | prometheus、grafana | |
192.168.7.81 | nginx(写入、查询组件服务负载均衡) | 通过域名访问 |
数据路径:
/usr/local/victoria-metrics: vmstorage、vminsert、vmselect二进制目录
/data1/vmstorage_data: vmstorage数据路径
部署过程
- 以下需要在所有节点操作
目录环境准备
mkdir /usr/local/victoria-metrics
mkdir /data1/vmstorage_data
准备版本包
https://github.com/VictoriaMetrics/VictoriaMetrics/releases
cd /opt/
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.80.0/victoria-metrics-linux-amd64-v1.80.0-cluster.tar.gz
tar zxvf victoria-metrics-linux-amd64-v1.80.0-cluster.tar.gz -C /usr/local/victoria-metrics
vmstorage
首先需要把存储部署上,多个存储之间数据是不同步的,也就是说所有的storege组件之间是感知不到彼此的。
最终数据通过vmselect和vminsert采用一致性hash算法来确定读取/写入哪台节点。
vmstorage属于有状态服务,在cluster模式下有三个端口:
- 8482端口是API端口
- 8400是端口给vminsert写数据的
- 8401端口是给vmselect查询数据的
高可用说明:
启用复制保证了多达 N-1
个 vmstorage
节点不可用,所有数据仍可用于查询。集群必须至少包含 2*N-1
个 vmstorage
节点,其中 N
是复制因子,以便在 N-1
个存储节点丢失时为新摄取的数据维持指定的复制因子。
例如,当 -replicationFactor=3
传递给 vminsert
时,它将所有摄取的数据复制到 3 个不同的 vmstorage
节点,因此最多可以丢失 2 个 vmstorage
节点而不会丢失数据。vmstorage
节点的最小数量应该等于 2*3-1 = 5
,因此当 2 个 vmstorage
节点丢失时,剩余的 3 个 vmstorage
节点可以为新摄取的数据提供服务。
启动命令:
主要参数:
- -retentionPeriod # 存储时间,单位是月
- -storageDataPath # 数据存放路径
/usr/local/victoria-metrics/vmstorage-prod -httpListenAddr "0.0.0.0:8482" \ # vmstorage监听端口
-storageDataPath /data1/vmstorage_data \ # 数据存储位置
-retentionPeriod 60d \ # 数据保留多久
-vminsertAddr "0.0.0.0:8400" \ # insert服务连接的端口
-vmselectAddr "0.0.0.0:8401" \ # select服务连接的端口
-dedup.minScrapeInterval=30s \ # 和vmselect保持一致
-loggerTimezone "Asia/Shanghai" \
-loggerLevel INFO
/etc/systemd/system/vmstorage.service
[Unit]
Description=vmstorage
After=network.target
[Service]
WorkingDirectory=/usr/local/victoria-metrics
ExecStart=/usr/local/victoria-metrics/vmstorage-prod -httpListenAddr "0.0.0.0:8482" \
-storageDataPath /data1/vmstorage_data \
-retentionPeriod 60d \
-vminsertAddr "0.0.0.0:8400" \
-vmselectAddr "0.0.0.0:8401" \
-dedup.minScrapeInterval=30s \
-loggerTimezone "Asia/Shanghai" \
-loggerLevel INFO
Restart=always
RestartSec=15
LimitNOFILE=65536
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
vminsert
属于无状态服务,指向所有的 vmstorage,监听端口 8480即可。
线上可考虑将存储节点IP改为域名
启动命令:
主要参数:
- -storageNode=
:8400
/usr/local/victoria-metrics/vminsert-prod -httpListenAddr "0.0.0.0:8480" \
-storageNode 192.168.7.33:8400,192.168.7.34:8400,192.168.7.35:8400 \ # 指定所有storege节点
-replicationFactor 2 \ # 副本数2
-loggerTimezone"Asia/Shanghai" \
-loggerLevel INFO
/etc/systemd/system/vminsert.service
[Unit]
Description=vminsert
After=network.target
[Service]
WorkingDirectory=/usr/local/victoria-metrics
ExecStart=/usr/local/victoria-metrics/vminsert-prod -httpListenAddr "0.0.0.0:8480" \
-storageNode "192.168.7.33:8400,192.168.7.34:8400,192.168.7.35:8400" \
-replicationFactor 2 \
-loggerTimezone "Asia/Shanghai" \
-loggerLevel INFO
Restart=always
RestartSec=15
LimitNOFILE=65536
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
- 其中,replicationFactor代表数据副本数。
vmselect
属于无状态服务,指向所有的 vmstorage 的 8401 端口、所有 vmselect 的 8481 端口即可。
线上可考虑将存储节点、查询节点IP改为域名
启动命令:
主要参数:
- selectNode=
:8481 - storageNode=
:8401
/usr/local/victoria-metrics/vmselect-prod -httpListenAddr "0.0.0.0:8481" \
-selectNode 192.168.7.33:8481,192.168.7.34:8481 \ # select的所有节点
-storageNode 192.168.7.33:8401,192.168.7.34:8401,192.168.7.35:8401 \ # 指定所有storage节点
-dedup.minScrapeInterval=30s \ # 重复数据删除,如果是从Prometheus写入的话,必须和Prometheus的scrape_interval保持一致。
-loggerTimezone "Asia/Shanghai" \
-loggerLevel INFO
/etc/systemd/system/vmselect.service
[Unit]
Description=vmselect
After=network.target
[Service]
WorkingDirectory=/usr/local/victoria-metrics
ExecStart=/usr/local/victoria-metrics/vmselect-prod -httpListenAddr "0.0.0.0:8481" \
-selectNode 192.168.7.33:8481,192.168.7.34:8481 \
-storageNode 192.168.7.33:8401,192.168.7.34:8401,192.168.7.35:8401 \
-dedup.minScrapeInterval=30s \
-loggerTimezone "Asia/Shanghai" \
-loggerLevel INFO
Restart=always
RestartSec=15
LimitNOFILE=65536
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
使用systemd托管应用,执行启动
cp *.service /etc/systemd/system/
systemctl daemon-reload
service vmstorage start
service vminsert start
service vmselect start
service vmstorage status
service vminsert status
service vmselect status
验证服务端口
# vmstorage
curl http://192.168.7.33:8482/metrics
curl http://192.168.7.34:8482/metrics
curl http://192.168.7.35:8482/metrics
# vminsert
curl http://192.168.7.33:8480/metrics
curl http://192.168.7.34:8480/metrics
# vmselect
curl http://192.168.7.33:8481/metrics
curl http://192.168.7.34:8481/metrics
配置负载均衡
- 写入地址格式:
http://<vminsert>:8480/insert/<accountID>/<suffix>"
- 例如:
http://<vminsert>:8480/insert/11542/prom1-online"
- 例如:
- 查询地址格式:
http://<vmselect>:8481/select/<accountID>/<suffix>"
- 例如:
http://<vminsert>:8481/select/11542/prom1-online"
- 例如:
此时 accountID
必须与 prometheus.yml
中配置的 accountID
一致.
- suffix 后面可以是下面的字符串,和 prometheus 的 api 对应:
/api/v1/query :performs PromQL instant query
/api/v1/query_range :performs PromQL range query
/api/v1/series :performs series query
/api/v1/labels :returns a list of label names
/api/v1/label/<label_name>/values :returns values for the given <label_name> according to API
/federate :returns federated metrics
/api/v1/export
通过 Prometheus 的 API 查询:
$ curl -g 'http://localhost:19522/api/v1/series' --data-urlencode 'match[]=up{}' | jq
{
"status": "success",
"data": [
...
{
"__name__": "up",
"hostname": "homelab_k8s_03",
"idc": "homelab",
"instance": "192.168.7.33:19523",
"ip": "192.168.7.33:19523",
"job": "host_node_exporter"
},
{
"__name__": "up",
"hostname": "homelab_k8s_04",
"idc": "homelab",
"instance": "192.168.7.34:19523",
"ip": "192.168.7.34:19523",
"job": "host_node_exporter"
},
{
"__name__": "up",
"hostname": "homelab_k8s_05",
"idc": "homelab",
"instance": "192.168.7.35:19523",
"ip": "192.168.7.35:19523",
"job": "host_node_exporter"
}
...
]
}
通过 VictoriaMetrics 的 API 查询:
此时还没对接监控写入,可以后续再来查询
$ curl 'http://127.0.0.1:8481/select/386383640/prometheus/api/v1/series' --data-urlencode 'match[]=up{}' |jq
{
"status": "success",
"data": [
...
{
"__name__": "up",
"hostname": "homelab_k8s_03",
"idc": "homelab",
"instance": "192.168.7.33:19523",
"ip": "192.168.7.33:19523",
"job": "host_node_exporter"
},
{
"__name__": "up",
"hostname": "homelab_k8s_04",
"idc": "homelab",
"instance": "192.168.7.34:19523",
"ip": "192.168.7.34:19523",
"job": "host_node_exporter"
},
{
"__name__": "up",
"hostname": "homelab_k8s_05",
"idc": "homelab",
"instance": "192.168.7.35:19523",
"ip": "192.168.7.35:19523",
"job": "host_node_exporter"
}
...
]
}
- 每个 accountID 和 projectID 由范围 [0 … 2^32) 中的任意 32 位整数标识。如果不指定,则默自动分配为 0.
- 当第一个数据点写入给定租户时,会自动创建租户
- 所有租户的数据均匀分布在可用的 vmstorage 节点中。这保证了当不同租户具有不同的数据量和不同的查询负载时,vmstorage 节点之间的负载均匀
- 数据库性能依赖于租户的数量,主要取决于所有租户中活动的时间序列的总数.
- VictoriaMetrics 不支持在单个请求中查询多个租户
vm-components.nestealin.com.conf
upstream vmselect {
server 192.168.7.33:8481 weight=5 ;
server 192.168.7.34:8481 weight=5 ;
}
upstream vminsert {
server 192.168.7.33:8480 weight=5 ;
server 192.168.7.34:8480 weight=5 ;
}
server {
listen 80;
server_name vm-select.nestealin.com;
#auth_basic "authentication"; # 开启基本认证
#auth_basic_user_file conf.d/.htpasswd; # 密码文件
include firewall.conf;
location / {
proxy_pass http://vmselect/select/386383640/prometheus/;
}
}
server {
listen 80;
server_name vm-insert.nestealin.com;
#auth_basic "authentication"; # 开启基本认证
#auth_basic_user_file conf.d/.htpasswd; # 密码文件
include firewall.conf;
location / {
proxy_pass http://vminsert/insert/386383640/prometheus/;
}
}
监控对接
Prometheus通过remote_write写入vm集群
官方文档:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write
remote_write:
# 通过负载均衡地址
- url: "http://vm-insert.nestealin.com/api/v1/write"
# 直接连接vminsert组件
# - url: "http://192.168.7.33:8480/insert/386383640/prometheus/api/v1/write"
# basic_auth:
# username: admin
# password: 123456
remote_timeout: 30s
tls_config:
insecure_skip_verify: true
queue_config:
capacity: 2500
max_shards: 200
min_shards: 1
max_samples_per_send: 500
batch_send_deadline: 5s
min_backoff: 30ms
max_backoff: 5s
UI验证
使用PromQL语法查询,地址格式:
http://${vmselect服务IP}:${vmselect服务端口}/select/${accountID}/${suffix}
写入验证
查看vmstorage日志验证写入信息
Sep 12 23:43:35 homelab-k8s-03 vmstorage-prod[27403]: 2022-09-12T23:43:35.759+0800 info VictoriaMetrics/lib/storage/partition.go:211 creating a partition "2022_09" with smallPartsPath="/data1/vmstorage_data/data/small/2022_09", bigPartsPath="/data1/vmstorage_data/data/big/2022_09"
Sep 12 23:43:35 homelab-k8s-03 vmstorage-prod[27403]: 2022-09-12T23:43:35.769+0800 info VictoriaMetrics/lib/storage/partition.go:227 partition "2022_09" has been created
Sep 12 23:43:41 homelab-k8s-03 vmstorage-prod[27403]: 2022-09-12T23:43:41.787+0800 info VictoriaMetrics/lib/vmselectapi/server.go:132 accepted vmselect conn from 192.168.7.33:51060
Sep 12 23:43:41 homelab-k8s-03 vmstorage-prod[27403]: 2022-09-12T23:43:41.793+0800 info VictoriaMetrics/lib/vmselectapi/server.go:175 processing vmselect conn from 192.168.7.33:51060
Grafana配置数据源
如果有配置HTTP用户认证,请开启
Basic auth
选项。
填入查询URL: http://vm-select.nestealin.com ,其余保持默认即可。
查询相关监控指标
至此,已完成基本的 VM 分布式数据集群部署。
如有生产要求的,可根据模块拆分,将无状态的服务放到 K8S 中运行,对数据节点进行磁盘性能及数据高可用优化。
相关文档
- 官网:https://victoriametrics.com
- 官方文档:https://docs.victoriametrics.com
- GitHub:https://github.com/VictoriaMetrics/VictoriaMetrics
- 集群模式详细文档:https://p8s.io/docs/victoriametrics/cluster/
- 基于VictoriaMetrics的大规模监控实战: https://zahui.fan/posts/e59d8e32/
- Victoria Metrics 学习: https://www.lijiaocn.com/项目/2020/02/24/prometheus-scale-out-2.html