logo
企业版

技术分享

实践分享|使用 Prometheus 监控 NebulaGraph

NebulaGraph 安装

NebulaGraph 安装

本次安装选择 NebulaGraph 最新版本 v3.8.0,采用 docker-compose 的方式部署,新版本的安装要比之前顺滑很多,赞~

  1. 找一台服务器,安装好 docker 和 docker-compose

  2. 下载项目

`$ git clone -b release-3.8 https://github.com/vesoft-inc/nebula-docker-compose.git` 
  1. 安装
`mkdir -p /work/nebula

#复制docker-compose.yaml
cp ../nebula-docker-compose-3.8.0/docker-compose.yaml /work/nebula/

# 复制环境变量文件
cp ../nebula-docker-compose-3.8.0/.env /work/nebula/

# 修改.env,时区使用Asia/Shanghai
vim .env

TZ=Asia/Shanghai

# 启动
docker-compose up -d

# 查看启动结果
docker-compose ps是 git clone -b release-3.8 https://github.com/vesoft-inc/nebula-docker-compose.git

![git clone -b release-3.8](https://nebula-website-cn.oss-cn-hangzhou.aliyuncs.com/nebula-website-5.0/share/2024-06-06-2.png)

Prometheus 安装

安装过程如下:
# 创建目录
mkdir -p /work/prometheus

# 创建应用子目录
# 启动脚本路径
mkdir -p /work/prometheus/bin
# 数据文件路径
mkdir -p /work/prometheus/data/prometheus
# 配置文件路径
mkdir -p /work/prometheus/conf
# 日志文件路径
mkdir -p /work/prometheus/logs

# 创建启动脚本
cd /work/prometheus/bin
vim start.sh

#内容
docker run -d --restart=always --name=prometheus \
        -p 9090:9090 \
        --log-opt max-size=10m \
        -v /etc/localtime:/etc/localtime:ro \
        -v /etc/timezone:/etc/timezone \
        -v /work/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \
        -v /work/prometheus/data/prometheus:/prometheus \
        prom/prometheus --config.file=/etc/prometheus/prometheus.yml --web.enable-lifecycle --storage.tsdb.retention.time=7d

# 创建一个空的prometheus.yml
touch prometheus.yml

# 修改/work/prometheus/data/prometheus,目录权限
chown 65534:65534 prometheus/

# 启动
chmod 755 start.sh
./start.sh

# 查看启动日志,确认正常启动
docker logs -f prometheus`

docker logs -f prometheus

Grafana 安装

安装过程如下:

`#创建目录
mkdir -p /work/grafana

#创建应用子目录

#启动脚本路径
mkdir -p /work/grafana/bin

#数据文件路径
mkdir -p /work/grafana/data/grafana

#日志文件路径
mkdir -p /work/grafana/logs

#创建启动脚本
cd /work/grafana/bin
vim start.sh

#内容
docker run -d --restart=always --name grafana \
        -p 3000:3000 \
        --log-opt max-size=10m \
        -e GF_AUTH_PROXY_ENABLED=true \
        -e GF_AUTH_ANONYMOUS_ENABLED=true \
        -e GF_SERVER_ENABLE_LOCAL_HEALTH_CHECK=false \
        -v /etc/localtime:/etc/localtime:ro \
        -v /etc/timezone:/etc/timezone \
        -v /work//grafana/data/grafana:/var/lib/grafana \
        prom/prometheus --config.file=/etc/prometheus/prometheus.yml --web.enable-lifecycle --storage.tsdb.retention.time=7d

# 创建一个空的prometheus.yml
touch prometheus.yml

# 修改/work/prometheus/data/prometheus,目录权限
chown 65534:65534 prometheus/

# 启动
chmod 755 start.sh
./start.sh

# 查看启动日志,确认正常启动
docker logs -f prometheus
`

Grafana 安装

安装过程如下:

# 创建目录
mkdir -p /work/grafana
# 创建应用子目录
# 启动脚本路径
mkdir -p /work/grafana/bin
# 数据文件路径
mkdir -p /work/grafana/data/grafana
# 日志文件路径
mkdir -p /work/grafana/logs

# 创建启动脚本
cd /work/grafana/bin
vim start.sh

#内容
docker run -d --restart=always --name grafana \
        -p 3000:3000 \
        --log-opt max-size=10m \
        -e GF_AUTH_PROXY_ENABLED=true \
        -e GF_AUTH_ANONYMOUS_ENABLED=true \
        -e GF_SERVER_ENABLE_LOCAL_HEALTH_CHECK=false \
      -v /etc/localtime:/etc/localtime:ro \
        -v /etc/timezone:/etc/timezone \
        -v /work//grafana/data/grafana:/var/lib/grafana \
        harbor.neuqsoft.com/dockerhub/grafana/grafana

# 修改/work//grafana/data/grafana,目录权限
chown 472:472 grafana/

# 启动
chmod 755 start.sh
./start.sh

# 查看启动日志,确认正常启动
docker logs -f grafana

docker logs -f grafana

整合阶段

  1. 调整 NebulaGraph,打开监控
`docker-compose down
# 编辑docker-compose.yaml文件
vim docker-compose.yaml

# 在graphd服务后边增加 - --enable_space_level_metrics,注意我有三个节点,都需要修改
 - --enable_space_level_metrics`

enable_space_level_metrics

 # 调整端口,将ws_http_port对应的端口映射出来
 # 使用29669,39669,49669对应graphd服务的三个节点19669
 # 以下为部分内容,注意我有三个节点,都需要修改
 - 29669:19669
 - 29669:19669
 - 29669:19669`

启动 NebulaGraph

# 启动 NebulaGraph
docker-compose up -d

# 检查启动状态
docker-compose ps
  1. 配置 Prometheus
# 编辑配置文件
vim prometheus.yml

scrape_configs:
  - job_name: nebula-graph
    metrics_path: /stats
    static_configs:
     - targets:
       - 127.0.0.1:29669
       - 127.0.0.1:39669
       - 127.0.0.1:49669

# 重启服务
docker restart prometheus
  1. Grafana 配置数源

docker restart prometheus

Grafana 配置数源

  1. 官方自带的 metrics 接口请求地址和 Prometheus 要求的不一样,通过修改 metrics_path 配置,指定到了 /stats 访问地址。

其次,返回数据格式也和 Prometheus 要求的不一样,导致 Prometheus 识别节点全部都是 down

Prometheus

5.最后,采集到的数据,也没有被 Prometheus 存储,Grafana 也没办法读取到。

 Prometheus

填坑环节

  1. 期间试过很多种方法,失败的就不说了,就说最后成功的 自己实现一个数据转换服务,将官方的 metrics 返回数据转换为Prometheus 要求的格式。

用 GO 实现了一个转换的工具,上代码:

package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
)

// 端点和端口进行变量声明
var (
    targetEndpoint string
    port           string
)

func main() {
    // 使用 flag 包解析命令行参数
    flag.StringVar(&port, "port", "8000", "HTTP server 监听端口")
    flag.StringVar(&targetEndpoint, "target", "http://nebula-graph.local:19669/metrics", "目标 metrics 端点地址")
    flag.Parse()

    // 注册 /metrics 路由
    http.HandleFunc("/metrics", handleMetrics)

    // 启动 HTTP 服务器
    fmt.Printf("服务器启动在端口 %s,抓取指标来自 %s\n", port, targetEndpoint)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
        fmt.Printf("启动服务器时遇到错误: %s\n", err)
        os.Exit(1)
    }
}

// handleMetrics 是处理指标抓取的主函数
func handleMetrics(w http.ResponseWriter, r *http.Request) {
    // 从目标端点抓取原始指标数据
    resp, err := http.Get(targetEndpoint)
    if err != nil {
        http.Error(w, "抓取指标失败", http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()

    // 读取响应体内容
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        http.Error(w, "读取指标失败", http.StatusInternalServerError)
        return
    }

    // 重格式化指标
    metrics := reformatMetrics(string(body))
    fmt.Fprint(w, metrics) // 返回格式化后的指标
}

// reformatMetrics 将原始指标重格式化为 Prometheus 兼容的格式
func reformatMetrics(rawMetrics string) string {
    var formattedLines []string
    lines := strings.Split(rawMetrics, "\n") // 按行拆分

    for _, line := range lines {
        // 跳过注释行和空行
        if strings.HasPrefix(line, "#") || line == "" {
            formattedLines = append(formattedLines, line)
            continue
        }

        // 自定义重格式化逻辑
        // 比如:num_queries_hit_memory_watermark.rate.5=0 -> num_queries_hit_memory_watermark_rate_5{interval="5"} 0
        parts := strings.Split(line, "=")
        if len(parts) != 2 {
            // 跳过无效行
            continue
        }
        metric, value := parts[0], parts[1]

        // 处理 metric 部分,将其拆分为名称和区间
        metricParts := strings.Split(metric, ".")
        if len(metricParts) < 3 {
            continue  // 不符合预期格式则跳过
        }

        // 将名称和区间拼接成 Prometheus 格式
        baseName := strings.Join(metricParts[:len(metricParts)-2], "_") // 将名称部分合并
        interval := metricParts[len(metricParts)-1]
        metricType := metricParts[len(metricParts)-2]

        // 拼接成 Prometheus 格式的字符串
        formattedMetric := fmt.Sprintf("%s_%s{interval=\"%s\"} %s", baseName, metricType, interval, value)
        formattedLines = append(formattedLines, formattedMetric)
    }

    return strings.Join(formattedLines, "\n") // 将所有行合并为一个字符串
}# 编译后得到linux服务器可执行文件metrics_converter
# 启动服务
./metrics_converter -port=8081 -target=http://127.0.0.1:29669/stats

# 测试
curl http://127.0.0.1:8081/metrics

# ok数据格式对了,不要纠结为啥全是0,刚装的啥也没有..

调整 Prometheus 配置文件

  1. 调整 Prometheus 配置文件,调整了一个演示如下
# # 编辑配置文件
vim prometheus.yml

scrape_configs:
  - job_name'nebula-graph'
    static_configs:
     - targets:
       - 127.0.0.1:

# 重启服务
docker restart prometheus

docker restart prometheus

  1. 查看 Grafana 数据指标,已经可以正常制作图表了

Grafana 数据指标

4.由于原来不支持 Prometheus + Grafana,所以官方图表库没有能直接用的

总结

通过不断的尝试,终于实现了目标,现在看来运维工作确实需要一些开发的基础,希望这篇文章能给需要的人带来一丝丝帮助吧。

注意:全篇文章使用 127.0.0.1 是为了隐藏 IP,各位测试的时候请使用真实IP!!

作者:堕落飞鸟

校对 & 编辑:Kristain#