Redis里头怎么整自定义函数,弄起来其实没那么难,也挺实用的
- 问答
- 2026-01-09 10:24:45
- 2
行,那咱们就直接开整,Redis 自己确实不带“自定义函数”这个说法,但你想在里头实现类似的效果——比如把一些复杂的操作打包成一个命令,或者让一系列操作能原子性地执行——其实有挺实在的路子,最常用的就是 Lua 脚本,还有就是 Redis 模块,咱们就聊这两样,怎么弄,用起来啥感觉。
先说 Lua 脚本,这是 Redis 内置的功能,也是最接地气、最常用的实现“自定义逻辑”的方法,你可能会想,为啥 Redis 要用 Lua 这种外部语言?主要是因为 Lua 特别轻量,嵌入起来方便,Redis 保证了一个 Lua 脚本在执行的时候是原子性的(来自 Redis 官方文档的解释),啥叫原子性?就是说这个脚本在执行过程中,不会被其他客户端的命令插队,它像一条单挑命令一样,一口气干完活,这对于需要连续操作多个键、又要保证数据一致性的场景特别有用。

比如你有个常见的需求:要在一个文章阅读系统里,记录某篇文章的阅读次数,同时把这篇文章 ID 放到一个“最热文章”的排序集合里,并且给这个排序集合的分数加一,如果不用脚本,你得先 INCR 一下阅读数,再 ZINCRBY 一下排序集合,这两个命令是分开的,万一在它们执行中间,别的客户端插进来修改了数据,就可能出乱子,但如果你用 Lua 脚本把这两个操作写在一起,Redis 就保证它俩一口气执行完,中间谁也不准打扰。
那具体怎么写呢?很简单,你用 EVAL 命令就行,比如下面这个简单的例子(例子结构参考了 Redis 在实际应用中的常见模式):

EVAL "redis.call('INCR', KEYS[1]) redis.call('ZINCRBY', KEYS[2], 1, ARGV[1])" 2 article:123:reads hot_articles 123
我来拆解一下这个命令:
EVAL是告诉 Redis 我要执行一段 Lua 脚本。- 双引号里面就是 Lua 脚本代码。
redis.call()是你在 Lua 里调用 Redis 命令的方法。 KEYS[1]和KEYS[2]是你传进去的键,后面的2表示我传了两个键。ARGV[1]是额外的参数,这里我们传了文章 ID '123'。
这样,你就相当于自己“定义”了一个组合命令,你甚至可以把它存成一个 .lua 文件,然后用 redis-cli 工具直接加载执行,或者用 SCRIPT LOAD 命令先把脚本载入到 Redis 里,得到一个 SHA1 校验和,以后就用 EVALSHA 加上这个校验和来执行,这样还能节省网络带宽(这个优化技巧在 Redis 实战中很常见)。

再来说说 Redis 模块,这个就比 Lua 脚本更进阶了,功能也强大得多,如果说 Lua 脚本是在 Redis 现有的命令基础上进行“组合”和“粘合”,那模块就是让你用 C 语言(或者其他能导出 C 兼容符号的语言)来创造全新的 Redis 命令(根据 Redis 官方对模块系统的说明),你可以实现复杂的数据结构,添加全新的功能,Redis 里著名的搜索模块 RediSearch、图数据库模块 RedisGraph,都是通过模块机制实现的。
那模块怎么弄呢?这就比写 Lua 脚本麻烦点了,你得会点 C 编程,然后下载 Redis 的模块开发工具包,照着它的 API 写代码,比如你想创建一个叫 MYCOMMAND 的命令,你大概需要:
- 写一个 C 函数来实现这个命令的逻辑。
- 在模块的初始化函数里,用
RedisModule_CreateCommand把这个函数注册成一个新的 Redis 命令。 - 把代码编译成一个动态链接库(
.so文件)。 - 在 Redis 的配置文件
redis.conf里加上loadmodule /path/to/mymodule.so,或者启动 Redis 服务器时用--loadmodule参数加载。
这样一来,Redis 启动后,你就可以像使用 SET、GET 这些内置命令一样,直接使用你自己写的 MYCOMMAND 了,这绝对是最高级别的“自定义函数”了,除非你有非常特殊的、用 Lua 脚本也搞不定的性能需求或者复杂逻辑,一般的小需求用 Lua 脚本就足够了。
总结一下,在 Redis 里“整自定义函数”:
- 图省事、要原子性:就用 Lua 脚本,它是内置的,写起来快,能完美解决大部分需要组合命令的场景。
- 要极限性能、要造轮子:就上 Redis 模块,它能让你扩展 Redis 本身,但需要一定的开发门槛。
所以你看,这事儿其实没那么神秘,也没想象中那么难,Lua 脚本上手非常快,你稍微试一下就能感受到它的实用性,尤其是当你厌倦了在客户端代码里写一堆 Redis 调用、还要担心网络往返时间和原子性问题的时候,把它打包成一个 Lua 脚本,整个世界都清净了。
本文由凤伟才于2026-01-09发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/77383.html
