doc: 阅读redis script/function文档

This commit is contained in:
asahi
2025-09-23 16:24:43 +08:00
parent 3ed69c87a0
commit 4e3a3388d6

View File

@@ -155,6 +155,13 @@
- [TDIGEST.MERGE](#tdigestmerge)
- [Retrieving sketch information](#retrieving-sketch-information)
- [Resetting a sketch](#resetting-a-sketch)
- [Redis Programmability](#redis-programmability)
- [Introduce](#introduce)
- [Backgroud](#backgroud)
- [running scripts](#running-scripts)
- [Read-only scripts](#read-only-scripts)
- [Sandboxed script context](#sandboxed-script-context)
- [Maximum execution time](#maximum-execution-time)
# redis
@@ -2604,3 +2611,58 @@ TDIGEST.MERGE destKey numKeys sourceKey... [COMPRESSION compression] [OVERRIDE]
> TDIGEST.RESET racer_ages
OK
```
## Redis Programmability
redis提供了programming interface允许在server执行自定义的脚本。在redis 7及以上可以使用`Redis Function`来管理和运行脚本而在redis 6.2或更低的版本,则使用`lua scripting with EVAL command`。
### Introduce
#### Backgroud
在redis中`Programmability`代表`可以在server端执行任意用户定义的逻辑`,我们将该逻辑片段称之为`scripts`。通过脚本能够在server端即数据被存储的地方处理数据。在server端处理用户逻辑能够降低网络延迟并且能提高整体性能。
在redis通过一个`embedded, sandboxed scripting engine`来执行用户脚本。目前redis仅支持单一的脚本引擎即`lua 5.1 interpreter`。
#### running scripts
redis提供了两种方式来运行脚本。从`2.6.0`版本开始redis支持通过`EVAL`命令来运行server-side scripts。在使用用户脚本时`脚本逻辑中包含应用的业务逻辑`。脚本的source code必须存储在应用端redis server仅会临时存储source code。当应用的逻辑发生变动时script将变得难以维护。
在redis 7.0版本中引入了Redis Function。function能够将脚本编写与应用逻辑解耦并且支持脚本的独立开发、测试和部署。如果要使用redis function需要先对其进行导入redis function导入后对所有的connections都是可用的。
当redis执行script或function时能够保证执行过程是原子的。在脚本执行的整个过程中redis server端的所有其他活动都会被阻塞。
在脚本执行中,应当避免执行`slow script`。如果脚本执行较慢在执行脚本过程中所有其他clients都会被阻塞执行不了任何命令。
#### Read-only scripts
`read-only scipts`代表在脚本执行时并不会对redis中的任何key造成修改。可以通过两种方式来执行`read-only script`:
- 在脚本中添加`no-write flag`
- 通过`read-only script command`来执行脚本
- 常用read-only command如下
- `EVAL_RO`
- `EVALSHA_RO`
- `FCALL_RO`
`read-only script`拥有如下特性:
- read-only scripts可以在replicas上被执行
- 其总是可以被`SCRIPT_KILL`命令被killed
- 即使当redis超过内存限制其也不会`fail with OOM error`
- 当发生`write pause`时,其也不会被阻塞
- 在read-only script中不允许执行任何能对data set造成修改的命令
- `PUBLISH, SPUBLISH, PFCOUNT`目前仍然被视为write command
#### Sandboxed script context
redis将执行用户脚本的engine放在了sandbox中。sandbox主要用于防止`accidental misuse`并且降低server环境的潜在威胁。
script中永远不应该访问redis server的底层宿主机系统例如file system、network或执行不受支持的系统调用。
script仅应该操作`redis中存储的数据`和`脚本执行时传入的作为参数的数据`。
#### Maximum execution time
脚本的执行时长受限于最大执行时长(默认情况下为5s)。这个默认超时很大默认情况下脚本的运行时长应当小于1ms。该超时用于处理脚本执行时非预期的无限循环。
可以通过`修改redis.conf文件`或`使用config set命令`来修改该脚本执行时长上限。影响脚本最长执行时间上限的配置属性为`busy-reply-threshold`。
当脚本达到该超时上限时其并不会自动被redis终止。中断脚本的执行将可能导致`half-write`的问题。
故而,将脚本执行时长超过限制时,将会发生如下事件:
- redis会在日志中添加`脚本执行时间过长`
- redis开始从其他clients接收commands但是会对所有发送normal commands的clients返回`BUSY error`。在该场景下,唯一被允许的命令为`SCRIPT_KILL, FUNCTION_KILL, SHUTDOWN NOSAVE`
- 对于`read-only script`,可以使用`SCRIPT_KILL`和`FUNCTION_KILL`命令,因为该脚本未对数据造成任何修改
- 如果`script`在执行过程中哪怕执行了一个write operation那么只能使用`SHUTDOWN NOSAVE`命令其会停止server并且不会将当前的data set保存到磁盘中