This article will take you to understand OpenNJet KV Store and its implementation

NGINX evolves to cloud native, All in OpenNJet


1. Feature introduction

OpenNJet implements a persistent key-value store function and provides corresponding APIs to operate on key values. Based on the capabilities provided by KV Store, it can be used in the following scenarios:

  • Persistence of module dynamic configuration information
  • Sharing of running status information between different modules of OpenNJet
  • Dynamic parameter adjustment of NJet running module by external system

For example, the dynamic Worker number adjustment function currently provided by OpenNJet is to trigger the management of the running Worker process by the Master process by setting a specific KEY value.

2. Implementation plan

The open source community already has a large number of middlewares, such as Redis and Etcd. These middlewares can be used as key-value storage databases. However, this not only requires corresponding modules in OpenNJet to interact with them, but also increases the dependence on external components during deployment. .

The implementation of OpenNJet KV Store uses the lightweight in-memory database LMDB. LMDB is based on memory mapping, which is highly efficient and easy to access. It does not require a separate data management process, as long as the LMDB library is referenced in the access code. The file structure of LMDB is simple, including a data file and a lock file. Transaction isolation is achieved through lock control. The LMDB file can be opened by multiple processes at the same time. Using this solution, the overall architecture is simple and clear.

Comparison of functions between OpenNJet and other load balancing products KV Store:

  OpenNJet nginx OSS nginx Plus APISIX
Whether to support support No built-in KV Store support support
Method to realize LMDB / Shared memory Etcd
Usage Restful, Lua, C API / Restful, Njs Restful, Lua
Whether to charge Open source and free / Pay to use Open source and free

3. Instructions for use

3.1 C API

When using C to develop OpenNJet extension modules, you can use the kv capability provided by OpenNJet to operate kvstore.

Taking the data plane module as an example, the module needs to include the header file in the OpenNJet source code:

#include <njt_http_kv_module.h>
The kvstore-related function prototype declaration in the header file is as follows:
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);

The calling sample code is as follows:

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 method

OpenNJet provides the encapsulated Lua kv store API. Reference the "njt.kv" Lua library in Lua, and then use Lua functions to operate the kv store. The functions include: db_kv_get, db_kv_set, db_kv_del.

The test code is as follows:

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 method

After installation using the RPM package provided by the official website, the generated control plane njet_ctrl configuration already contains a location that can be used to set the kv value.

    location /kv {
            dyn_sendmsg_kv;
        }

You can use Restful methods, GET, POST, and DELETE to operate on key values.

When setting the key value using the Restful interface provided by the control plane, the prefix "kv_http_" will be added before the key. If you use C or Lua API, and the key values ​​set by the Restful interface need to interoperate, you need to add the "kv_http_" prefix when calling the corresponding function from the C or Lua API.


OpenNJet was first based on the basic fork of NGINX1.19 and evolved independently. It has the characteristics of high performance, stability, and easy expansion. It also solves the long-standing problems of NGINX such as difficulty in dynamic configuration and management functions affecting business.

Mail group official website 

Alibaba Cloud suffered a serious failure and all products were affected (restored). Tumblr cooled down the Russian operating system Aurora OS 5.0. New UI unveiled Delphi 12 & C++ Builder 12, RAD Studio 12. Many Internet companies urgently recruit Hongmeng programmers. UNIX time is about to enter the 1.7 billion era (already entered). Meituan recruits troops and plans to develop the Hongmeng system App. Amazon develops a Linux-based operating system to get rid of Android's dependence on .NET 8 on Linux. The independent size is reduced by 50%. FFmpeg 6.1 "Heaviside" is released
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/6606114/blog/10141751