一、NebulaGraph安装
本次安装选择NebulaGraph最新版本3.8.0,采用docker-compose的方式部署,官方文档,新版本的安装要比之前顺滑很多,赞~
1.1、找一台服务器,安装好docker和docker-compose
1.2、下载项目
$ git clone -b release-3.8 https://github.com/vesoft-inc/nebula-docker-compose.git
1.3、安装
# 创建安装路径
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
二、Prometheus安装
2.1、安装
# 创建目录
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安装
3.1、安装
# 创建目录
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
四、整合
4.1、调整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
- 39669:19669
- 49669:19669
# 启动NebulaGraph
docker-compose up -d
# 检查启动状态
docker-compose ps
4.2、配置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
4.3、grafana配置数源
4.4、说实话,我写文章就从来没顺利过,谁懂啊,怪不得没有《使用Prometheus监控NebulaGraph》,相关的文章。
首先,官方自带的metrics接口请求地址和Prometheus要求的不一样,通过修改metrics_path配置,指定到了/stats访问地址
其次,返回数据格式也和Prometheus要求的不一样,导致Prometheus识别节点全部都是down
最后,采集到的数据,也没有被Prometheus存储,grafana也没办法读取到
五、填坑
5.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,刚装的啥也没有。。。
5.2、调整Prometheus配置文件,就调整了一个演示一下
# # 编辑配置文件
vim prometheus.yml
scrape_configs:
- job_name: 'nebula-graph'
static_configs:
- targets:
- 127.0.0.1:8081
# 重启服务
docker restart prometheus
5.3、查看grafana数据指标,已经可以正常制作图表了
5.4、额由于原来不支持Prometheus+grafana,所以官方图表库没有能直接用的,我能力有限。。。就这样了。
六、总结
通过不断的尝试,终于实现了目标,现在运维工作看来确实需要一些开发的基础,希望这篇文章能给需要的人带来一丝丝帮助吧。
注意:全篇文章使用127.0.0.1是为了隐藏IP,各位测试的时候请使用真实IP!!!