一 概述
shdict api
实现了共享内存的操作接口,在 lua-nginx
模块中将所有的共享内存(shm_zone
)存储在一个 Table
中,每个 shm_zone
使用红黑树存储操作的 key-value
。刚才说所有的共享内存,准确的说应该是所有使用 lua_shared_dict
指令创建的共享内存。
lua-nginx
模块中每个 shm_zone
用 Table
表示,在表中使用 SHDICT_USERDATA_INDEX
索引每个共享内存的 zone
。
1 | void |
二 接口
1. get|get_stale
1 | value, flags = ngx.shared.DICT:get(key) |
get
函数用来从共享内存中获得 key
对应的值,如果 key
不存在或者已经过期则返回 nil
。出错时返回 nil
以及错误描述字符串。
get_stale
函数与 get
相同,唯一不同点在于使用 get_stale
函数访问过期的 key-value
时返回其原始值,而非 nil
。同时,返回值中 stale
标识 key
是否已经过期。
**key
必须为字符串类型,value
可以为字符串、数值、布尔或者 NIL
**。
get
、get_stale
函数最终都是有 ngx_http_lua_shdict_get_helper
实现,只是 get
调用时 get_stale
为 0,get_stale
调用时值为 1。ngx_http_lua_shdict_get_helper
函数实现:
1 | static int |
2. set
1 | success, err, forcible = ngx.shared.DICT:set(key, value, exptime?, flags?) |
无条件的向共享内存中添加一条 key-value
。返回值 success
用以标明添加是否成功,err
为错误描述字符串,布尔类型的 forcible
用来标明为了保存本条记录是否将其他合法的 key-value
删除。
参数 key
、value
是要保存的 key-value
,可选的数值参数 exptime
指定 key
的过期时间,单位为秒但是可以使用小数精确到毫秒级别。exptime
默认为 0,不过期。可选的参数 flag
为 key
的“用户”表示,在使用 get|get_stale
获取 key
时会返回 flag
。flag
是 32 为的整数。
在调用 set
时,如果共享内存已经无可用空间,会使用 LRU
策略,从 lru_queue
中删除 key-value
(仍然有可能无法满足 set
调用使用的空间)。set
实现函数为 ngx_http_lua_shdict_set_helper
,实现函数:
1 | // flag 控制 set 的行为,以实现 set、safe_set 功能 |
ngx_http_lua_shdict_set_helper
函数实现了新增、更新、删除功能,逻辑非常复杂。
3. safe_set
1 | ok, err = ngx.shared.DICT:safe_set(key, value, exptime?, flags?) |
与 set
方法相同,只不过不会删除未过期 key-value
以满足保存操作。
4. add
1 | success, err, forcible = ngx.shared.DICT:add(key, value, exptime?, flags?) |
与 set
方法相似,不过只会在共享内存中不存在 key
时才会保存设置的 key-value
。如果 key
已经在共享内存中,success
为 false
,err
为 exists
。有可能会删除未过期 key-value
,以满足存储需求。
5. safe_add
1 | ok, err = ngx.shared.DICT:safe_add(key, value, exptime?, flags?) |
与 add
方法类似,不过不会删除未过期的 key-value
以满足存储需求。
6. replace
1 | success, err, forcible = ngx.shared.DICT:replace(key, value, exptime?, flags?) |
与 set
方法类似,不过仅当 key
已经存在于共享内存时才会进行保存操作。如果 key
不存在时会返回 not found
错误描述字符串。
7. incr
1 | newval, err, forcible? = ngx.shared.DICT:incr(key, value, init?, init_ttl?) |
将 key
指定的数值类型值增加 value
步长,返回增加后的 value
。如果 key
在共享内存中未找到,init
可选参数影响其行为:
init
为nil
,函数返回nil
,并且错误描述为not found
。init
为数值参数,函数返回init + value
。
与 add
函数类似,如果存储空间不足,会删除未过期 key-value
。
可选参数 init_ttl
控制 key
的超时时间(仅在初始化时参数有效),以秒为单位,支持浮点数可以精确到毫秒。
8. delete
1 | ngx.shared.DICT:delete(key) |
无条件的删除 key
指定的 key-value
,等价于调用 set(key, nil)
函数。
9. lpush
1 | length, err = ngx.shared.DICT:lpush(key, value) |
将指定的数值或字符串 value
插入基于共享内存的列表头,返回 list
中的元素数量。如果 key
不存在,则在执行当前函后会创建一个新的列表,当 key
已经存在但是非列表类型,错误提示为 value not a list
。
**lpush
不会删除未过期 key-value
**。
10. rpush
1 | length, err = ngx.shared.DICT:rpush(key, value) |
与 lpush
相似,只不过 rpush
在队列尾插入值。
11. lpop
1 | val, err = ngx.shared.DICT:lpop(key) |
从 list
中返回并删除首个元素,如果 key
不存在返回 nil
,如果 key
相应的 value
非 list
类型,返回 value not a list
。
12. rpop
1 | val, err = ngx.shared.DICT:rpop(key) |
从 list
中返回并删除末尾元素,如果 key
不存在返回 nil
,如果 key
相应的 value
非 list
类型,返回 value not a list
。
13. llen
1 | len, err = ngx.shared.DICT:llen(key) |
计算 list
中元素数量,如果 key
不存在代表是空列表,返回 0。如果 key
的值非列表类型,返回 nil
以及相应错误描述。
14. ttl
1 | ttl, err = ngx.shared.DICT:ttl(key) |
返回 key
剩余的 TTL
时间,以秒为单位,精确到毫秒。失败返回 nil
以及错误描述字符串。如果返回 ttl
为零,说明未设置超时时间。
15. expire
1 | success, err = ngx.shared.DICT:expire(key, exptime) |
更新 key
的超时时间,返回布尔类型状态信息以及错误描述。参数 exptime
以秒为单位精确到毫秒。
16. flush_all|flush_expired
1 | ngx.shared.DICT:flush_all() |
删除所有的 key-value
或者过期的 key-value
。flush_expired
函数接受一个可选的 max_count
参数,用来控制删除过期 key
数量。默认为 0,会删除所有的过期 key
。同时,flush_expired
函数会返回删除的 key
数量。
17. get_keys
1 | keys = ngx.shared.DICT:get_keys(max_count?) |
返回一个包含共享内存(shm_zone)所有 keys
的 Array Table
。可选数值参数 max_count
可以控制返回的 key
数量,默认为 1024 个。