Prometheus的分布式数据存储--VictoriaMetrics部署文档


背景

当前单节点Prometheus集中存储多个集群数据,数据单点且索引性能低下,官方架构问题无法横向扩展优化。

目的

  1. 需要分布式数据存储,支持并发查询,优化查询性能
  2. 可以兼容Prometheus写入或服务端中转写入
  3. 可支持数据副本(次要)

架构

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模式下有三个端口:

  1. 8482端口是API端口
  2. 8400是端口给vminsert写数据的
  3. 8401端口是给vmselect查询数据的

高可用说明:

启用复制保证了多达 N-1vmstorage 节点不可用,所有数据仍可用于查询。集群必须至少包含 2*N-1vmstorage 节点,其中 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}

http://192.168.7.33:8481/select/386383640/vmui/?g0.range_input=5m&g0.end_input=2022-09-12T15%3A53%3A49&g0.step_input=0.586&g0.relative_time=last_5_minutes&g0.tab=chart&g0.expr=up%7B%7D

写入验证

查看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 中运行,对数据节点进行磁盘性能及数据高可用优化。


相关文档


文章作者: NesTeaLin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 NesTeaLin !
  目录