写点什么

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

作者:通明湖
  • 2025-11-19
    北京
  • 本文字数:3231 字

    阅读完需:约 11 分钟

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 健康检查配置说明

字段介绍


sql 块配置字段详细介绍

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"            ]          }        ]      }    ]  }]
复制代码


发布于: 11 小时前阅读数: 13
用户头像

通明湖

关注

让应用永远在线! 2022-10-13 加入

持续科技创新,信创应用交付领域的排头兵

评论

发布
暂无评论
善用NJet能力,优化你的数据库访问体验_通明湖_InfoQ写作社区