Skip to content

Commit

Permalink
memcached: add an API method that shows slab info
Browse files Browse the repository at this point in the history
Before switching to our own slab arena user can control usage and
information about slab arena using Tarantool Lua API (specifically
box.slab.{check,info,stat}() functions), see [1]. Example of output
box.slab.info() is below:

tarantool> box.slab.info()
---
- items_size: 146896
  items_used_ratio: 26.05%
  quota_size: 268435456
  quota_used_ratio: 12.50%
  arena_used_ratio: 3.7%
  items_used: 38264
  quota_used: 33554432
  arena_size: 33554432
  arena_used: 1234296
...

With our own slab arena we need a way to obtain information about arena.
It's a reason why new method slab() was introduced. Output of slab() is
similar to output from `box.slab.info()`, but without items_size,
items_used, items_used_ratio and arena_used is not implemented.

tarantool> require('memcached'):slab()
---
- info:
    quota_used: 4194304
    arena_used_ratio: 0
    quota_used_ratio: 0.097656249999998
    arena_size: 4194304
    quota_size: 4294967296
    arena_used: 0
...

1. https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_slab/slab_info/

Follows up #96
  • Loading branch information
ligurio committed Feb 10, 2022
1 parent dda6a77 commit f15c399
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ END
- `name` - a string with instance name
- `uri` - a string with uri to bind to, for example: `0.0.0.0:11211` (only TCP is supported now)
- `opts` - a table with options, the list of possible options is described in the configuration section
* `local slab = memcached.slab()` - show information about slab arena and quota.
* `local instance = instance:cfg(<opts>)` - (re)configure an existing instance.
`opts` - a table with options, same as in `create`
* `local instance = instance:start()` - start an instance
Expand Down
37 changes: 37 additions & 0 deletions memcached/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ struct memcached_stat {
uint64_t auth_errors;
};

struct slab_arena_info {
size_t arena_size;
size_t arena_used;
double arena_used_ratio;

size_t quota_size;
size_t quota_used;
double quota_used_ratio;
};

void
memcached_set_opt (struct memcached_service *srv, int opt, ...);

Expand Down Expand Up @@ -82,6 +92,9 @@ memcached_get_stat (struct memcached_service *);
struct memcached_service *
memcached_create(const char *, uint32_t);

struct slab_arena_info *
memcached_slab_arena_info();

int memcached_start (struct memcached_service *);
void memcached_stop (struct memcached_service *);
void memcached_free (struct memcached_service *);
Expand Down Expand Up @@ -233,6 +246,17 @@ local RUNNING = 'r'
local STOPPED = 's'
local ERRORED = 'e'


local slab_arena_info_table = {
'arena_size',
'arena_used',
'arena_used_ratio',

'quota_size',
'quota_used',
'quota_used_ratio',
}

local stat_table = {
'total_items', 'curr_items',
'curr_conns', 'total_conns',
Expand Down Expand Up @@ -386,7 +410,20 @@ local function memcached_get(name)
return memcached_services[name]
end

local function memcached_slab()
local slab_arena_info = memcached_internal.memcached_slab_arena_info()
local slab = {
info = {}
}
for _, v in pairs(slab_arena_info_table) do
slab.info[v] = slab_arena_info[0][v]
end

return slab
end

return {
slab = memcached_slab,
create = memcached_init,
get = memcached_get,
server = setmetatable({}, {
Expand Down
14 changes: 14 additions & 0 deletions memcached/internal/memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@
__thread struct slab_cache slabc;
struct quota quota;
struct slab_arena arena;
struct slab_arena_info slab_info;

struct slab_arena_info *
memcached_slab_arena_info()
{
slab_info.arena_size = arena.used;

slab_info.quota_used = quota_used(arena.quota);
slab_info.quota_size = quota_total(arena.quota);
slab_info.quota_used_ratio = 100 * ((double) slab_info.quota_used /
((double) slab_info.quota_size + 0.0001));

return &slab_info;
}

void
memcached_slab_arena_create()
Expand Down
10 changes: 10 additions & 0 deletions memcached/internal/memcached.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ enum memcached_proto_type {
MEMCACHED_PROTO_MAX
};

struct slab_arena_info {
size_t arena_size;
size_t arena_used;
double arena_used_ratio;

size_t quota_size;
size_t quota_used;
double quota_used_ratio;
};

struct memcached_stat {
/* connection informations */
unsigned int curr_items;
Expand Down
16 changes: 16 additions & 0 deletions test/common/instance_api.test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,19 @@ local self_instance = mc:grant('Vera')
test:isnt(self_instance, nil, 'instance:grant() returns self object')

os.exit(test:check() and 0 or 1)

-- instance:slab()

local slab = mc:slab()
test:istable(slab, 'instance:slab() returns a table')
test:istable(slab.info, 'instance:slab().info returns a table')
test:isnumber(slab.info.arena_size, 'instance:slab().info.arena_size returns a number')
test:isnumber(slab.info.arena_used, 'instance:slab().info.arena_used returns a number')
test:isnumber(slab.info.arena_used_ratio, 'instance:slab().info.arena_used_ratio returns a number')
test:isnumber(slab.info.quota_size, 'instance:slab().info.quota_size returns a number')
test:isnumber(slab.info.quota_used, 'instance:slab().info.quota_used returns a number')
test:isnumber(slab.info.quota_used_ratio, 'instance:slab().info.quota_used_ratio returns a number')
local quota_used_ratio = 100 * slab.info.quota_used / slab.info.quota_used
test:is(slab.info.quota_used_ratio, quota_used_ratio, 'instance:slab().info.quota_used_ratio is correct')

os.exit(test:check() and 0 or 1)

0 comments on commit f15c399

Please sign in to comment.