善用NJet能力,优化你的数据库访问体验

🙈 By 单雷 2025-11-10

1.需求背景

  目前市场上存在多种类型的分布式数据库,出于兼容性考虑,很多数据库都提供标准的mysql的访问接口; 其基本架构都是多节点分区存储数据,有的甚至采用存储和计算节点分离的模式,但无论怎样,出于高可用性以及支撑访问量水平扩展的需要,其前端都需要部署一个负载均衡设施。以Apache Doris为例,其配置文档中明确的指出了负载均衡设施的必要性,并给出了市场上常见的4层代理软件,如NGINX,HAPROXY,或特定的proxysql的配置样例。

  Doris给出的配置样例,其仅仅采用配置文件,意味着数据库节点扩容时,必须修改配置文件,重启生效,会对业务有一定的影响,更重要的是NGINX/HAPROXY的配置,仅仅把后端的数据库节点当作一个TCP服务器,无法感知节点的状态,这样在节点状态异常时,会给客户端带来不好的访问体验。

  针对此类数据库分布式访问的场景,以NJet作为数据库前端的负载均衡,其特有能力,可以大大简化分布式数据库的运维工作,提升使用者的体验。其一是动态成员维护,可以在数据库节点扩/缩容时,通过API自动进行成员变更,而正在进行的访问不受影响; 其二是特定的sql主动健康检查,可以预先发现问题节点,自动下线,避免使用者的故障感知;其三是可以使用json格式的配置文件,便于运维操作。

2.NJet实现Doris负载均衡

以Doris为例,在192.168.1.100上部署proxy,代理访问后端三个节点(192.168.1.101,102,103)利用NJet作为负载均衡设施,其初始配置和NGINX一致,不同的是在njet.conf中

events {
worker_connections 1024;
}
stream {
  upstream mysqld {
      hash $remote_addr consistent;
      server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
      server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
      server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
  }
  server {
   # Proxy port
      listen 6030;
      proxy_connect_timeout 300s;
      proxy_timeout 300s;
      proxy_pass mysqld;
  }
}

在njet启动后,下面就可以利用NJet的特有能力,方便数据库的运维

2.1 NJet动态成员维护

OpenNJet可以通过动态api接口的方式,动态对upstream中的成员进行新增,删除,修改,查询。为支持动态成员维护,NJet.conf和njet_ctrl文件需要做相关的配置变更,如下面配置样例中标黄色部分

  • 数据面配置(njet.conf)示例
helper broker modules/njt_helper_broker_module.so conf/mqtt.conf;
helper ctrl modules/njt_helper_ctrl_module.so conf/ctrl.conf;

load_module modules/njt_http_upstream_member_module.so;

stream {

  upstream mysqld {
      zone mysqld 16k; #必须配置共享内存
      hash $remote_addr consistent;
      server 192.168.1.101:9030 weight=1 max_fails=2 fail_timeout=60s;
      server 192.168.1.102:9030 weight=1 max_fails=2 fail_timeout=60s;
      server 192.168.1.103:9030 weight=1 max_fails=2 fail_timeout=60s;
  }
  server {
   # Proxy port
      listen 6030;
      proxy_connect_timeout 300s;
      proxy_timeout 300s;
      proxy_pass mysqld;
  }
  
}
  • 控制面配置(njet_ctrl.conf)示例
load_module modules/njt_http_sendmsg_module.so;
load_module modules/njt_http_upstream_api_module.so; 
load_module modules/njt_helper_health_check_module.so;


http {
   
   server {
        listen       8081;
 
        location /api {
            dyn_module_api;
        }
    }
}

2.1.1 添加upstream成员

假设后续Doris做集群扩容,添加了节点192.168.1.104:9030,可以通过下面api进行添加:

api url: POST http://{机器ip}:8081/api/v1/upstream_api/stream/upstreams/{upstream_name}/servers/

curl -X POST http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/ -d '{
  "server": "192.168.1.104:9030",
  "weight": 2,
  "max_conns": 2,
  "max_fails": 1,
  "fail_timeout": "5s",
  "slow_start": "5s",
  "route": "",
  "backup": false,
  "down": false
}'

添加成员192.168.1.104:9030后,OpenNJet会自动给该成员按顺序分配id,可以通过该id后续对该成员进行查询,删除,修改等操作。

2.1.2 删除upstream成员

api url: DELETE http://{机器ip}:8081/api/v1/upstream_api/stream/upstreams/{upstream_name}/servers/{id}

执行后删除对应id的成员。

curl -X DELETE http://127.0.0.1:8081/api/v1/upstream_api/stream/upstreams/mysqld/servers/3

2.2 NJet 配置mysql健康检查

OpenNJet默认安装是启用主动健康检查的,可以直接通过控制面提供的api接口(默认启用8081端口来提供配置服务)进行配置。,api url: http://{机器ip}:8081/api/v1/hc/smysql/{upstreamname},具体样例如下:

curl -X 'POST' \
  'http://127.0.0.1:8081/api/v1/hc/smysql/mysqld' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "interval": "5s",
  "jitter": "1s",
  "timeout": "5s",
  "passes": 1,
  "fails": 1,
  "sql": {
    "select": "select 1",
    "useSsl": true,
    "user": "root",
    "password": "123456",
    "db": "db"
  }
}'

配置后就可以定期执行,并在后端服务故障时自动下线(下线后仍然会执行检查,并在检查成功后自动恢复上线)

2.2.1 健康检查配置说明

字段介绍

字段名称 必须配置 说明
interval 主动健康检查频率
visit_interval 健康检查时,如果指定的时间间隔内该server被客户端访问过,则该server跳过此次健康检查,interval > visit_interval
jitter 设置健康检查项定时器最大偏差。防止所有检查项同时触发。
timeout 超时时间
passes server_body server 块内的指令集,每条指令用分号分隔。server_body内容可以为空。
fails 连续不通过fails次检测,更新peer为unhealthy状态
port 指定健康检查的端口,如果不指定,使用upstream中设置的端口

sql块配置字段详细介绍

字段名称 子字段名称 类型 必须配置 默认值 说明
sql块 select 字符串 select 1 查询语句
useSsl bool true 是否使用ssl连接
user 字符串 - mysql数据库用户名
password 字符串 - mysql数据库密码
db 字符串 - mysql数据库名称

2.3 Json配置文件支持

目前常见的nginx,haproxy等代理设施,其配置文件,非常不方便维护,而NJet提供了json格式的配置文件,可以利用jsonpath快速定位,操作数据,方便运维。如上述的njet.conf,可以方便的转换为json格式,并把njet.conf修改为njet.json,就可以被njet使用(njet -c conf/njet.json)

[
  {
    "cmd": "events",
    "args": [],
    "block": [
      {
        "cmd": "worker_connections",
        "args": [
          "1024"
        ]
      }
    ]
  },
  {
    "cmd": "stream",
    "args": [],
    "block": [
      {
        "cmd": "upstream",
        "args": [
          "mysqld"
        ],
        "block": [
          {
            "cmd": "hash",
            "args": [
              "$remote_addr",
              "consistent"
            ]
          },
          {
            "cmd": "server",
            "args": [
              "192.168.1.101:9030",
              "weight=1",
              "max_fails=2",
              "fail_timeout=60s"
            ]
          },
          {
            "cmd": "server",
            "args": [
              "192.168.1.102:9030",
              "weight=1",
              "max_fails=2",
              "fail_timeout=60s"
            ]
          },
          {
            "cmd": "server",
            "args": [
              "192.168.1.103:9030",
              "weight=1",
              "max_fails=2",
              "fail_timeout=60s"
            ]
          }
        ]
      },
      {
        "cmd": "server",
        "args": [],
        "block": [
          {
            "cmd": "listen",
            "args": [
              "6030"
            ]
          },
          {
            "cmd": "proxy_connect_timeout",
            "args": [
              "300s"
            ]
          },
          {
            "cmd": "proxy_timeout",
            "args": [
              "300s"
            ]
          },
          {
            "cmd": "proxy_pass",
            "args": [
              "mysqld"
            ]
          }
        ]
      }
    ]
  }
]

3. 备注

Apache Doris 是一款基于 MPP 架构的高性能、实时分析型数据库。 采用 MySQL 协议,高度兼容 MySQL 语法,支持标准 SQL。在生产环境中,可以部署多个 FE 节点以实现容灾备份。FE节点主要负责接收用户请求、查询解析和规划、元数据管理以及节点管理。

FE节点前需部署负载均衡,参考https://doris.apache.org/zh-CN/docs/dev/admin-manual/cluster-management/load-balancing

  • sql的主动健康检查是NJet4.0提供的能力,目前支持mysql,后面支持pg等数据库接口
  • 出于安全考虑,自4.0起,NJet的api接口默认只能通过本机访问,如果要通过远程访问,需修改njet_ctrl.conf中的监听配置,并强烈建议—配置访问控制