memc: 标准 NGINX memcached 模块的扩展版本
安装
您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:
- RedHat Enterprise Linux 7、8、9 和 10
- CentOS 7、8、9
- AlmaLinux 8、9
- Rocky Linux 8、9
- Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-memc
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-memc
通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:
load_module modules/ngx_http_memc_module.so;
本文档描述了 nginx-module-memc v0.20,于 2023 年 12 月 27 日发布。
# GET /foo?key=dog
#
# POST /foo?key=cat
# Cat's value...
#
# PUT /foo?key=bird
# Bird's value...
#
# DELETE /foo?key=Tiger
location /foo {
set $memc_key $arg_key;
# $memc_cmd 默认值为 GET 的 get,
# POST 的 add,PUT 的 set,以及
# DELETE 请求方法的 delete。
memc_pass 127.0.0.1:11211;
}
# GET /bar?cmd=get&key=cat
#
# POST /bar?cmd=set&key=dog
# My value for the "dog" key...
#
# DELETE /bar?cmd=delete&key=dog
# GET /bar?cmd=delete&key=dog
location /bar {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_flags $arg_flags; # 默认值为 0
set $memc_exptime $arg_exptime; # 默认值为 0
memc_pass 127.0.0.1:11211;
}
# GET /bar?cmd=get&key=cat
# GET /bar?cmd=set&key=dog&val=animal&flags=1234&exptime=2
# GET /bar?cmd=delete&key=dog
# GET /bar?cmd=flush_all
location /bar {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
set $memc_flags $arg_flags; # 默认值为 0
set $memc_exptime $arg_exptime; # 默认值为 0
memc_cmds_allowed get set add delete flush_all;
memc_pass 127.0.0.1:11211;
}
http {
...
upstream backend {
server 127.0.0.1:11984;
server 127.0.0.1:11985;
}
server {
location /stats {
set $memc_cmd stats;
memc_pass backend;
}
...
}
}
...
# 将 memcached 标志读取到 Last-Modified 头中
# 以响应 304 条件 GET
location /memc {
set $memc_key $arg_key;
memc_pass 127.0.0.1:11984;
memc_flags_to_last_modified on;
}
location /memc {
set $memc_key foo;
set $memc_cmd get;
# 访问 memcached 监听的 unix 域套接字
memc_pass unix:/tmp/memcached.sock;
}
描述
此模块扩展了标准 memcached module,以支持几乎整个 memcached ascii protocol。
它允许您为 memcached 服务器定义自定义的 REST 接口,或通过子请求或 独立伪请求 从 nginx 服务器内部以非常高效的方式访问 memcached。
此模块不打算合并到 Nginx 核心中,因为我使用 Ragel 生成了 memcached 响应解析器(用 C 编写),这让我很高兴 :)
如果您打算使用此模块来缓存位置响应,可以尝试 srcache-nginx-module 与此模块一起使用,以实现该目标。
与 lua-nginx-module 一起使用时,建议使用 lua-resty-memcached 库,而不是此模块,因为前者更灵活且内存效率更高。
与 memcached 服务器的保持连接
您需要 HttpUpstreamKeepaliveModule 与此模块一起使用,以便与后端 memcached 服务器保持 TCP 连接。
以下是一个示例配置:
http {
upstream backend {
server 127.0.0.1:11211;
# 一个最多有 1024 个连接的池
# 并且不区分服务器:
keepalive 1024;
}
server {
...
location /memc {
set $memc_cmd get;
set $memc_key $arg_key;
memc_pass backend;
}
}
}
工作原理
它完全基于 upstream 机制实现了 memcached TCP 协议。所有涉及 I/O 的操作都是非阻塞的。
该模块本身不会在请求之间保持与上游 memcached 服务器的 TCP 连接,就像其他上游模块一样。有关有效解决方案,请参见 与 memcached 服务器的保持连接 部分。
支持的 Memcached 命令
memcached 存储命令 set、add、replace、prepend 和 append 使用 $memc_key 作为键,$memc_exptime 作为过期时间(或延迟)(默认值为 0),$memc_flags 作为标志(默认值为 0),以构建相应的 memcached 查询。
如果 $memc_value 完全未定义,则请求体将用作 $memc_value 的值,除了 incr 和 decr 命令。请注意,如果 $memc_value 被定义为空字符串(""),则该空字符串仍将作为值使用。
以下 memcached 命令已实现并经过测试(其参数由本模块定义的相应 nginx 变量标记):
get $memc_key
使用键检索值。
location /foo {
set $memc_cmd 'get';
set $memc_key 'my_key';
memc_pass 127.0.0.1:11211;
add_header X-Memc-Flags $memc_flags;
}
如果找到该键,则返回 200 OK,并将值放入响应体中;否则返回 404 Not Found。flags 数字将设置到 $memc_flags 变量中,因此通常希望通过标准 add_header directive 将该信息放入响应头中。
对于 ERROR、CLIENT_ERROR 或 SERVER_ERROR,返回 502。
set $memc_key $memc_flags $memc_exptime $memc_value
要使用请求体作为 memcached 值,只需避免设置 $memc_value 变量:
# POST /foo
# my value...
location /foo {
set $memc_cmd 'set';
set $memc_key 'my_key';
set $memc_flags 12345;
set $memc_exptime 24;
memc_pass 127.0.0.1:11211;
}
或者让 $memc_value 保存值:
location /foo {
set $memc_cmd 'set';
set $memc_key 'my_key';
set $memc_flags 12345;
set $memc_exptime 24;
set $memc_value 'my_value';
memc_pass 127.0.0.1:11211;
}
如果上游 memcached 服务器回复 STORED,则返回 201 Created;NOT_STORED 返回 200;NOT_FOUND 返回 404;ERROR、CLIENT_ERROR 或 SERVER_ERROR 返回 502。
除了 404 NOT FOUND 外,原始 memcached 响应将作为响应体返回。
add $memc_key $memc_flags $memc_exptime $memc_value
类似于 set command。
replace $memc_key $memc_flags $memc_exptime $memc_value
类似于 set command。
append $memc_key $memc_flags $memc_exptime $memc_value
类似于 set command。
请注意,至少 memcached 版本 1.2.2 不支持 "append" 和 "prepend" 命令。至少 1.2.4 及更高版本似乎支持这两个命令。
prepend $memc_key $memc_flags $memc_exptime $memc_value
类似于 append command。
delete $memc_key
使用键删除 memcached 条目。
location /foo {
set $memc_cmd delete;
set $memc_key my_key;
memc_pass 127.0.0.1:11211;
}
如果成功删除,则返回 200 OK;NOT_FOUND 返回 404;ERROR、CLIENT_ERROR 或 SERVER_ERROR 返回 502。
除了 404 NOT FOUND 外,原始 memcached 响应将作为响应体返回。
delete $memc_key $memc_exptime
类似于 delete $memc_key 命令,但接受由 $memc_exptime 变量指定的可选 expiration 时间。
此命令在最新的 memcached 版本 1.4.4 中不再可用。
incr $memc_key $memc_value
将 $memc_key 的现有值增加 $memc_value 指定的数量:
location /foo {
set $memc_cmd incr;
set $memc_key my_key;
set $memc_value 2;
memc_pass 127.0.0.1:11211;
}
在前面的示例中,每次访问 /foo 都会导致 my_key 的值增加 2。
如果成功,返回 200 OK,并将与该键关联的新值作为响应体;如果未找到该键,则返回 404 Not Found。
对于 ERROR、CLIENT_ERROR 或 SERVER_ERROR,返回 502。
decr $memc_key $memc_value
类似于 incr $memc_key $memc_value。
flush_all
将 memcached 服务器上的所有键标记为过期:
location /foo {
set $memc_cmd flush_all;
memc_pass 127.0.0.1:11211;
}
flush_all $memc_exptime
与 flush_all 类似,但还接受由 $memc_exptime 变量指定的过期时间。
stats
使 memcached 服务器输出通用统计信息和设置。
location /foo {
set $memc_cmd stats;
memc_pass 127.0.0.1:11211;
}
如果请求成功,则返回 200 OK;对于 ERROR、CLIENT_ERROR 或 SERVER_ERROR 返回 502。
来自上游 memcached 服务器的原始 stats 命令输出将放入响应体中。
指令
所有标准 memcached module 指令在 nginx 0.8.28 中直接继承,memcached_ 前缀替换为 memc_。例如,memcached_pass 指令拼写为 memc_pass。
在这里,我们仅记录两个最重要的指令(后者是本模块引入的新指令)。
memc_pass
语法: memc_pass <memcached 服务器 IP 地址>:<memcached 服务器端口>
语法: memc_pass <memcached 服务器主机名>:<memcached 服务器端口>
语法: memc_pass <upstream_backend_name>
语法: memc_pass unix:<path_to_unix_domain_socket>
默认值: 无
上下文: http, server, location, if
阶段: content
指定 memcached 服务器后端。
memc_cmds_allowed
语法: memc_cmds_allowed <cmd>...
默认值: 无
上下文: http, server, location, if
列出允许访问的 memcached 命令。默认情况下,所有本模块支持的 memcached 命令都是可访问的。 示例:
location /foo {
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
memc_pass 127.0.0.1:11211;
memc_cmds_allowed get;
}
memc_flags_to_last_modified
语法: memc_flags_to_last_modified on|off
默认值: off
上下文: http, server, location, if
将 memcached 标志作为纪元秒读取,并将其设置为 Last-Modified 头的值。对于条件 GET,它将指示 nginx 返回 304 Not Modified 响应以节省带宽。
memc_connect_timeout
语法: memc_connect_timeout <time>
默认值: 60s
上下文: http, server, location
连接到 memcached 服务器的超时时间,默认以秒为单位。
最好始终明确指定时间单位以避免混淆。支持的时间单位有 "s"(秒)、"ms"(毫秒)、"y"(年)、"M"(月)、"w"(周)、"d"(天)、"h"(小时) 和 "m"(分钟)。
此时间必须少于 597 小时。
memc_send_timeout
语法: memc_send_timeout <time>
默认值: 60s
上下文: http, server, location
向 memcached 服务器发送 TCP 请求的超时时间,默认以秒为单位。
最好始终明确指定时间单位以避免混淆。支持的时间单位有 "s"(秒)、"ms"(毫秒)、"y"(年)、"M"(月)、"w"(周)、"d"(天)、"h"(小时) 和 "m"(分钟)。
此时间必须少于 597 小时。
memc_read_timeout
语法: memc_read_timeout <time>
默认值: 60s
上下文: http, server, location
从 memcached 服务器读取 TCP 响应的超时时间,默认以秒为单位。
最好始终明确指定时间单位以避免混淆。支持的时间单位有 "s"(秒)、"ms"(毫秒)、"y"(年)、"M"(月)、"w"(周)、"d"(天)、"h"(小时) 和 "m"(分钟)。
此时间必须少于 597 小时。
memc_buffer_size
语法: memc_buffer_size <size>
默认值: 4k/8k
上下文: http, server, location
此缓冲区大小用于内存缓冲区以保存
- 除
get以外的 memcached 命令的完整响应, getmemcached 命令的完整响应头(即响应的第一行)。
此默认大小为页面大小,可以是 4k 或 8k。
memc_ignore_client_abort
语法: memc_ignore_client_abort on|off
默认值: off
上下文: location
确定当客户端在未等待响应的情况下关闭连接时,是否应关闭与 memcache 服务器的连接。
此指令在 v0.14 版本中首次添加。
变更
每个版本的更改可以从 OpenResty 包的变更日志中获得:
测试套件
此模块附带一个 Perl 驱动的测试套件。 测试用例 也是 声明式。感谢 Perl 世界中的 Test::Base 模块。
要在您的环境中运行它:
$ PATH=/path/to/your/nginx-with-memc-module:$PATH prove -r t
如果您已更改 Nginx 服务器二进制文件,则需要在运行测试套件之前终止任何 Nginx 进程。
测试框架使用 LWP::UserAgent 或 IO::Socket。
由于所有测试脚本(.t 文件)都使用单个 nginx 服务器(默认是 localhost:1984),因此在调用 prove 工具时指定 -jN 并行运行测试套件是没有意义的。
在运行测试套件之前,您还应该在本地主机上保持一个监听在 11211 端口的 memcached 服务器。
测试套件的某些部分还需要启用 rewrite 和 echo 模块。
另见
- 在 nginx 邮件列表上的原始公告邮件:ngx_memc: "一个扩展版本的 ngx_memcached,支持 set、add、delete 和更多命令"
- 我展示各种 ngx_memc 用法的幻灯片:http://agentzh.org/misc/slides/nginx-conf-scripting/nginx-conf-scripting.html#34(使用键盘上的箭头或 PageUp/PageDown 键切换页面)
- 最新的 memcached TCP 协议。
- ngx_srcache 模块
- 基于 lua-nginx-module cosocket API 的 lua-resty-memcached 库。
- 标准 memcached 模块。
- 用于 Nginx 模块自动化测试的 echo module。
- 标准 headers 模块和第三方 headers-more 模块。
GitHub
您可以在 nginx-module-memc 的 GitHub 仓库 中找到此模块的其他配置提示和文档。