您现在的位置是:首页 > 文章详情

一文带你了解 OpenNJet KV Store及实现

日期:2023-11-09点击:90

NGINX 向云原生演进,All inOpenNJet


1. 特性介绍

OpenNJet 实现了可持久化的键值存储(key-value store)功能,并提供了相应的API对键值进行操作。基于KV Store提供的能力,可以用于如下场景:

  • 模块动态配置信息的持久化
  • OpenNJet不同模块间运行状态信息的共享
  • 外部系统对NJet运行模块的动态参数调整

例如OpenNJet 目前提供的动态Worker数目调整功能,就是通过设置特定的KEY值,以此来触发Master 进程对运行Worker进程的管理。

2. 实现方案

开源社区已经有大量的中间件,如Redis, Etcd,这些中间件都可以用来做键值存储的数据库, 但这样不仅需要OpenNJet中有相应模块与其进行交互,并且部署时增加了外部组件的依赖。

OpenNJet KV Store 的实现上,使用了轻量级的内存数据库 LMDB。LMDB是基于内存映射的,效率高,并且访问简单,不需要单独的数据管理进程,只要在访问代码里引用LMDB库。LMDB的文件结构简单,包含一个数据文件和一个锁文件,通过锁控制来实现事务隔离,LMDB文件可以同时由多个进程打开。使用该方案,整体架构简单清晰。

OpenNJet 与其它负载均衡产品KV Store 功能的比较:

  OpenNJet nginx OSS nginx Plus APISIX
是否支持 支持 无内置KV Store 支持 支持
实现方式 LMDB / 共享内存 Etcd
使用方式 Restful, Lua, C API / Restful, Njs Restful, Lua
是否收费 开源免费 / 付费使用 开源免费

3. 使用说明

3.1 C API

使用C开发OpenNJet的扩展模块时,可以使用OpenNJet提供的kv 能力,对kvstore进行操作。

以数据面的模块为例,模块中需要包含OpenNJet源码中的头文件:

#include <njt_http_kv_module.h>
该头文件中kvstore相关的函数原型声明如下:
int njt_db_kv_get(njt_str_t *key, njt_str_t *value); int njt_db_kv_set(njt_str_t *key, njt_str_t *value); int njt_db_kv_del(njt_str_t *key);

调用样例代码如下:

static int kv_get_example() { njt_str_t lmdb_key = njt_string("test_key"); njt_str_t lmdb_value; njt_int_t ok; lmdb_value.len=0; lmdb_value.data=NULL; ok = njt_db_kv_get(&lmdb_key, &lmdb_value); if (ok == NJT_OK) { ... } return NJT_OK; }

3.2 Lua 方式

OpenNJet 提供了封装后的Lua kv store API,在Lua 中引用"njt.kv" Lua 库, 之后使用Lua 函数对kv store 进行操作,函数包括:db_kv_get, db_kv_set, db_kv_del。

测试代码如下:

location /lua_kv_test { content_by_lua_block { local kv = require("njt.kv") local args, err = njt.req.get_uri_args() local key = args["key"] local rc,msg = kv.db_kv_get(key) if rc == 0 then njt.say("old value is: "..msg) else njt.say("there is no such key in kv") end local newValue = key .."_"..tostring(os.time()) rc = kv.db_kv_set(key, newValue) if rc == 0 then njt.say("set to new value: "..newValue) else njt.say("error occuried") end } } location /lua_kv_del { content_by_lua_block { local kv=require("njt.kv") local args, err= njt.req.get_uri_args() local key=args["key"] local _, msg= kv.db_kv_del(key) njt.say(msg) } } 

3.3 Restful 方式

使用官网提供的RPM 包安装后,生成的控制面njet_ctrl配置中,已包含一个可以用来设置kv值的location

 location /kv { dyn_sendmsg_kv; } 

可以使用Restful 的方式,GET,POST, DELETE 来对键值进行操作。

使用控制面提供的Restful 接口在设置键值时,将在key前添加 "kv_http_" 的前缀。如果使用C或Lua API,与Restful 接口设置的键值需要互操作的场景下, 在C或Lua API调用对应函数时,需要自行添加"kv_http_" 的前缀。


OpenNJet 最早是基于 NGINX1.19 基础 fork 并独立演进,具有高性能、稳定、易扩展的特点,同时也解决了 NGINX 长期存在的难于动态配置、管理功能影响业务等问题。

邮件组 官网

原文链接:https://my.oschina.net/u/6606114/blog/10141751
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章