Skip to content

Nginx Cache Data via nginx link function

Taymindis Woon edited this page Nov 18, 2018 · 1 revision

Purpose

nginx-link-function is also using nginx shm to do key-value(hashing) map cache, the data is being use across the workers to ensure high available.

When to use

  • when sharing the memory with other apps under same nginx.
  • when more than 1 workers running. (If this is the case, preferred using 1 worker with multiple connections to handle the load as we don't need to share memory, normal memory allocation will do the job)
  • Cache Key is already one of the share memory key(you do not need to worry your key is stack or heap memory, system will handle it)

As you can see, there are some functionality is regarding the caching, it actually using the shared memory across the nginx-link-function apps

extern void ngx_link_func_shmtx_lock(void *shared_mem);
  • it locks the worker/thread/application process, we don't really use it if only single worker is running
extern void ngx_link_func_shmtx_unlock(void *shared_mem);
  • it locks the worker/thread/application process, we don't really use it if only single worker is running
extern void* ngx_link_func_shm_alloc(void *shared_mem, size_t size);
extern void* ngx_link_func_shm_alloc_locked(void *shared_mem, size_t size);
  • it malloc the memory from shared_mem, therefore, this memory is on cache and allow to use across the apps, _locked means it's allocating under locked condition.
extern void ngx_link_func_shm_free(void *shared_mem, void *ptr);
extern void ngx_link_func_shm_free_locked(void *shared_mem, void *ptr);
`_locked` means it's free under locked condition.
  • it free the memory from shared_mem

Wrong implementation

ngx_link_func_shmtx_lock(ctx->shared_mem); // you have locked
ngx_link_func_shm_alloc(ctx->shared_mem, sizeof(int)); // you locked again, which is wrong!!

Correct implementation

ngx_link_func_shmtx_lock(ctx->shared_mem); // you have locked
ngx_link_func_shm_alloc_locked(ctx->shared_mem, sizeof(int)); // you are allocating under locked condition which is correct
ngx_link_func_shmtx_unlock(ctx->shared_mem);
The interface below is using for cache key value concept, it cache the data across the apps if you malloc from shared_memory.
extern void* ngx_link_func_cache_get(void *shared_mem, const char* key);
extern void* ngx_link_func_cache_put(void *shared_mem, const char* key, void* value);
extern void* ngx_link_func_cache_remove(void *shared_mem, const char* key);
extern void* ngx_link_func_cache_new(void *shared_mem, const char* key, size_t size);
  • This function is auto malloc the memory from shared_mem. it is more convenient for simple data type caching.
- Be make sure that ngx_link_func_cache_new, ngx_link_func_cache_put, ngx_link_func_cache_remove are locked before use if your worker/process has more than 1.

Example Code

Specified the memory size in your nginx http block.
http {
...
ngx_link_func_shm_size 512m;
...

The code below is the sample of how you implement the cache in your apps.
static void* my_own_shared_mem = NULL;

void ngx_link_func_init(ngx_link_func_ctx_t *ctx)  {
    // this pointer is always same across 
    // all the apps and process, put it in your local usage
    my_own_shared_mem = ctx->shared_mem; 
    ngx_link_func_shmtx_lock(my_own_shared_mem);
    char* my_value = ngx_link_func_cache_new(my_own_shared_mem, "my_key", 100 * sizeof(char));
    strcpy(my_value, "This value will store in my_own_shared_mem with my_key");
    char *get_value;
    if( (get_value = ngx_link_func_cache_get(my_own_shared_mem, "my_key")) != NULL) {
      ngx_link_func_log(info, ctx,  "my_key=%s\n", get_value);
    }
    ngx_link_func_shmtx_unlock(my_own_shared_mem);

}