技术分享
实践分享|使用 Prometheus 监控 NebulaGraph
NebulaGraph 安装
本次安装选择 NebulaGraph 最新版本 v3.8.0,采用 docker-compose 的方式部署,新版本的安装要比之前顺滑很多,赞~
找一台服务器,安装好 docker 和 docker-compose
下载项目
`$ git clone -b release-3.8 https://github.com/vesoft-inc/nebula-docker-compose.git`
- 安装
`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`
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
整合阶段
- 调整 NebulaGraph,打开监控
`docker-compose down
# 编辑docker-compose.yaml文件
vim docker-compose.yaml
# 在graphd服务后边增加 - --enable_space_level_metrics,注意我有三个节点,都需要修改
- --enable_space_level_metrics`
# 调整端口,将ws_http_port对应的端口映射出来
# 使用29669,39669,49669对应graphd服务的三个节点19669
# 以下为部分内容,注意我有三个节点,都需要修改
- 29669:19669
- 29669:19669
- 29669:19669`
# 启动 NebulaGraph
docker-compose up -d
# 检查启动状态
docker-compose ps
- 配置 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
- Grafana 配置数源
- 官方自带的 metrics 接口请求地址和 Prometheus 要求的不一样,通过修改 metrics_path 配置,指定到了 /stats 访问地址。
其次,返回数据格式也和 Prometheus 要求的不一样,导致 Prometheus 识别节点全部都是 down
5.最后,采集到的数据,也没有被 Prometheus 存储,Grafana 也没办法读取到。
填坑环节
- 期间试过很多种方法,失败的就不说了,就说最后成功的 自己实现一个数据转换服务,将官方的 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 配置文件,调整了一个演示如下
# # 编辑配置文件
vim prometheus.yml
scrape_configs:
- job_name'nebula-graph'
static_configs:
- targets:
- 127.0.0.1:
# 重启服务
docker restart prometheus
- 查看 Grafana 数据指标,已经可以正常制作图表了
4.由于原来不支持 Prometheus + Grafana,所以官方图表库没有能直接用的
总结
通过不断的尝试,终于实现了目标,现在看来运维工作确实需要一些开发的基础,希望这篇文章能给需要的人带来一丝丝帮助吧。
注意:全篇文章使用 127.0.0.1 是为了隐藏 IP,各位测试的时候请使用真实IP!!
作者:堕落飞鸟
校对 & 编辑:Kristain#