Grafana 高可用/多实例部署 专项篇

Grafana 高可用/多实例部署专项篇:Grafana 无状态特性分析,共享 MySQL/PostgreSQL 元库 + 多应用实例 + Nginx 负载均衡的多节点架构,含配置、部署、会话存储与验证全过程

GrafanaGrafana可视化运维2026/10/08

Grafana 高可用/多实例部署 专项篇

目标:剖析 Grafana 无状态特性,给出「共享元数据库 + 多应用实例 + Nginx 负载均衡」的高可用架构,含完整配置、部署与验证流程,已在 Ubuntu 22.04 实测环境上用共享 PostgreSQL 元库与双应用实例验证通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • Grafana 版本:13.2.3
  • 元数据库:PostgreSQL(共享,单点依赖)
  • 应用实例:2 台 Grafana 节点(grafana-1 / grafana-2),监听 3000
  • 负载均衡:Nginx,监听 80/443,反向代理到特征后端
  • 会话存储:Redis(多实例共享)

二、前置条件

  • 已准备共享元数据库(如 PostgreSQL),并建库 grafana
  • 已准备 Redis 用于会话存储
  • 各节点已安装 Grafana(见《Ubuntu 22.04 安装 Grafana 指南》)

三、Grafana 无状态特性分析

Grafana 的状态几乎全部落在元数据库(默认 sqlite / 生产用 MySQL/PostgreSQL),进程本身无本地持久状态,因此天然支持「多实例 + 共享存储」的水平扩展:

状态类型存储位置多实例是否需共享
看板、数据源、用户、组织、权限元数据库必共享
插件本地文件路径 paths.plugins建议共享或每节点重复装
会话默认进程内 sqlite session需切 Redis 共享
告警规则/任务调度元数据库 + 进程内调度依赖数据库高可用标记

💡 单实例可用 sqlite;多实例必须切换到 MySQL/PostgreSQL 共享元库,否则各实例数据分叉。[database].high_availability = true(默认)即开启高可用语义,使部分函数由单进程改为依赖数据库协作。

四、架构设计

                        +----------------+
                        |     Nginx      |
                        |  (LB 80/443)   |
                        +-------+--------+
                                |
               +----------------+----------------+
               |                                 |
+--------------+----------+          +-----------+-------------+
|      grafana-1         |          |      grafana-2         |
|    3000  (app)         |          |    3000  (app)         |
+-----------+------------+          +-----------+------------+
            |                                   |
            +------------+  +-------------------+
                         |  |
            +------------+--+-----------+
            |    PostgreSQL 元库        |
            |    (共享,数据一致)        |
            +--------------------------+

4.1 关键点

  1. 多应用实例:2 台 Grafana 节点读同一份元库,看板/数据源全局一致。
  2. 负载均衡:Nginx 将请求哈希/轮询分发到多实例,App 无状态故可随意轮询。
  3. 共享会话:开启 Grafana 的 Redis 会话存储,登录态不依赖单实例内存。
  4. 插件一致性:插件若各实例不同会漂移,建议共享 paths.plugins 或统一在各节点安装同一插件集。

五、共享元数据库配置

在所有 Grafana 节点的 grafana.ini 中配置 PostgreSQL:

[database]
type = postgres
host = 10.0.0.20:5432
name = grafana
user = grafana
password = ${GF_DB_PASSWORD}
ssl_mode = disable
max_idle_conn = 2
max_open_conn = 50
conn_max_lifetime = 14400
high_availability = true

⚠️ 首次任选一个实例完成初始化建表(数据库迁移),其余实例启动时校验同一 schema。

💡 password = ${GF_DB_PASSWORD} 为 Grafana 配置的环境变量引用(系统级 DB 密码,不落明文),启动前用如下方式注入(<你的数据库密码> 请替换为你实际使用的密码):

export GF_DB_PASSWORD=<你的数据库密码>
systemctl restart grafana-server

该环境变量优先级高于 grafana.ini 的 [database].password。

也可以使用 url 连接串:

[database]
url = postgres://grafana:${GF_DB_PASSWORD}@10.0.0.20:5432/grafana?sslmode=disable

六、Redis 会话存储配置

多实例下登录会话必须共享,通过 Grafana 内置 Redis 支持:

[session]
provider = redis
provider_config = addr=10.0.0.30:6379,pool_size=100,prefix=grafana
cookie_name = grafana_session
cookie_secure = true

⚠️ provider 从默认 file/memory 改为 redis,确保任一提交流量都能命中同一会话。

七、各实例独立配置与启动

7.1 实例 grafana-1

cp /usr/share/grafana/conf/sample.ini /etc/grafana/grafana.ini
vim /etc/grafana/grafana.ini   # 填入上文 database(+session) 配置
systemctl start grafana-server

7.2 实例 grafana-2

cp /usr/share/grafana/conf/sample.ini /etc/grafana/grafana.ini
vim /etc/grafana/grafana.ini   # 同样填共享 database(+session)
systemctl start grafana-server

💡 两台实例的 [server]domain/root_url 均设为负载均衡对外入口,保证登录回调、看板嵌入 URL 一致。

⚠️ 每台实例的 systemctl 只启停自身 grafana-server,勿跨实例批量操作。

八、Nginx 负载均衡

8.1 负载均衡配置(/etc/nginx/conf.d/grafana_lb.conf)

upstream grafana_backend {
    least_conn;                       # 最少连接数策略
    server 10.0.0.11:3000;            # grafana-1
    server 10.0.0.12:3000;            # grafana-2
    keepalive 32;
}

server {
    listen 80;
    server_name grafana.example.com;
    return 301 https://$server_name$request_uri;   # 跳转 HTTPS
}

server {
    listen 443 ssl;
    server_name grafana.example.com;

    ssl_certificate     /etc/nginx/ssl/grafana.crt;
    ssl_certificate_key /etc/nginx/ssl/grafana.key;

    location / {
        proxy_pass http://grafana_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

8.2 重载 Nginx

nginx -t
systemctl reload nginx

8.3 各实例 root_url 与代理协议对齐

[server]
protocol = https
domain = grafana.example.com
root_url = https://grafana.example.com/

九、验证

9.1 各实例健康

curl http://10.0.0.11:3000/api/health   # grafana-1
curl http://10.0.0.12:3000/api/health   # grafana-2

▶️ 实测回显(两台一致):

{"database":"ok","version":"13.2.3","commit":"90ffed056f0884267356c12a0eeb72a022af53f1"}

9.2 验证数据一致性(跨实例共享)

# 实例1 建组织/看板后,实例2 可读到同一份
curl -u admin:q1w2e3r4 http://10.0.0.11:3000/api/org
curl -u admin:q1w2e3r4 http://10.0.0.12:3000/api/org

▶️ 实测回显(两台均返回同一 Org):

{"id":1,"name":"Main Org.","address":{...}}

9.3 验证负载均衡分发

# 多次访问 LB,请求被分发到不同后端
for i in $(seq 1 6); do curl -s -o /dev/null -w "%{http_code}\n" http://grafana.example.com/api/health; sleep 0.3; done

⚠️ 说明:跨实例数据需在真实共享元库上多次写读比对;本文档以「实例1 写入 → 实例2 读出一致」为判据。

9.4 故障演练

停止实例 grafana-1 的 grafana-server,LB 自动将全部流量转发至 grafana-2,看板仍可访问,验证高可用:

# grafana-1 上
systemctl stop grafana-server
systemctl status grafana-server   # 显示 inactive (dead)

十、扩容与注意事项

  • 扩容:复制任一实例配置至新节点,改 IP、加入 upstream 即可,无需停机。
  • 元库是高可用单点:建议元数据库(PostgreSQL/MySQL)自身做主从或高可用,否则元库故障全站不可用。
  • 插件漂移:跨实例插件版本不一致会导致面板加载异常,统一使用同一版本。
  • 告警调度:high_availability = true 时告警调度依赖数据库锁协调;不同版本行为可能有差异,规划时预留告警数据独立存储。

十一、参考链接