doc: 阅读redis script/function文档
This commit is contained in:
@@ -155,6 +155,13 @@
|
|||||||
- [TDIGEST.MERGE](#tdigestmerge)
|
- [TDIGEST.MERGE](#tdigestmerge)
|
||||||
- [Retrieving sketch information](#retrieving-sketch-information)
|
- [Retrieving sketch information](#retrieving-sketch-information)
|
||||||
- [Resetting a sketch](#resetting-a-sketch)
|
- [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
|
# redis
|
||||||
@@ -2604,3 +2611,58 @@ TDIGEST.MERGE destKey numKeys sourceKey... [COMPRESSION compression] [OVERRIDE]
|
|||||||
> TDIGEST.RESET racer_ages
|
> TDIGEST.RESET racer_ages
|
||||||
OK
|
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保存到磁盘中
|
||||||
Reference in New Issue
Block a user