From 39f792e9111ec909af1a75ee606b9877a05ff334 Mon Sep 17 00:00:00 2001 From: asahi Date: Fri, 5 Sep 2025 11:14:22 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E9=98=85=E8=AF=BBRedisJSON=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 中间件/redis/redis.md | 214 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index e08e6ad..dbe2d91 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -22,6 +22,24 @@ - [WATCH](#watch) - [UNWATCH](#unwatch) - [Using WATCH to implement ZPOP](#using-watch-to-implement-zpop) + - [Data Types](#data-types) + - [Redis Strings](#redis-strings) + - [SET / GET](#set--get) + - [set with additional arguments](#set-with-additional-arguments) + - [GETSET](#getset) + - [MSET / MGET](#mset--mget) + - [strings as counters](#strings-as-counters) + - [Limits](#limits) + - [JSON](#json) + - [`JSON.SET`](#jsonset) + - [json数值操作](#json数值操作) + - [json数组操作](#json数组操作) + - [`JSON.DEL`](#jsondel) + - [`JSON.ARRAPPEND`](#jsonarrappend) + - [`JSON.ARRTRIM`](#jsonarrtrim) + - [json object操作](#json-object操作) + - [format output](#format-output) + - [Limitation](#limitation) # redis @@ -357,6 +375,8 @@ EXEC 在`EXEC`命令被调用后,所有的watched keys都会被`unwatched`,不管事务是否被aborted。并且,当client连接关闭后,所有keys都会被unwatched。 +对于`discard`命令,其在调用后所有watched keys也会自动被`unwatched`。 + #### UNWATCH 可以通过`UNWATCH`命令(无参数)来清空所有的watched keys。 @@ -375,3 +395,197 @@ MULTI ZREM zset element EXEC ``` + +> 如果`EXEC失败,那么其将返回Null`,所以仅需对之前操作进行重试即可 + +## Data Types +### Redis Strings +Redis strings存储字节序列,包含文本、serialized objects、binary array。strings通常被用于缓存,但是支持额外的功能,例如counters和位操作。 + +redis keys也为strings。 + +string data type可用于诸多用例,例如对html fragement/html page的缓存。 + +#### SET / GET +通过set和get命令,可以对string value进行设置和获取。 +```redis-cli + > SET bike:1 Deimos + OK + > GET bike:1 + "Deimos" +``` + +在使用`SET`命令时,如果key已存在对应的值,那么set指定的value将会对已经存在的值进行替换。`即使key对应的旧值并不是strings类型,set也会对其进行替换`。 + +values可以是`strings of every kind`(包含binary data),故而支持在value中存储jpeg image。value的值不能超过512MB. + +#### set with additional arguments +在使用`set`命令时,可以为其提供额外的参数,例如`NX | XX`. + +- `NX`: 仅当redis不存在对应的key时才进行设置,否则失败(返回nil) +- `XX`: 仅当redis存在对应的key时的才进行设置,否则失败(返回nil) + +#### GETSET +GETSET命令将会将key设置为指定的new value,并且返回oldvalue的值。 + +```redis-cli +127.0.0.1:6379> get bike:1 +(nil) +127.0.0.1:6379> GETSET bike:1 3 +(nil) +127.0.0.1:6379> GET bike:1 +"3" +``` + +#### MSET / MGET +strings类型支持通过`mset, mget`命令来一次性获取和设置多个keys,这将能降低RTT带来的延迟。 +```redis-cli + > mset bike:1 "Deimos" bike:2 "Ares" bike:3 "Vanth" + OK + > mget bike:1 bike:2 bike:3 + 1) "Deimos" + 2) "Ares" + 3) "Vanth" +``` + +#### strings as counters +strings类型支持atomic increment: +```redis-cli + > set total_crashes 0 + OK + > incr total_crashes + (integer) 1 + > incrby total_crashes 10 + (integer) 11 +``` +`incr`命令会将string value转化为integer,并且对其进行加一操作。类似命令还有`incrby, decr, drcrby`。 + +#### Limits +默认情况下,单个redis string的最大限制为`512MB`。 + +### JSON +redis支持对json值的存储、更新和获取。redis json可以和redis query engine进行协作,从而允许`index and query json documents`。 + +> 在redis 8中内置支持了RedisJSON,否则需要手动安装RedisJSON module。 + +#### `JSON.SET` +`JSON.SET`命令支持将redis的key设置为JSON value,示例如下: +```redis-cli +127.0.0.1:6379> JSON.SET bike $ '"Hyperion"' +OK +127.0.0.1:6379> JSON.GET bike $ +"[\"Hyperion\"]" +127.0.0.1:6379> type bike +ReJSON-RL +127.0.0.1:6379> JSON.TYPE bike $ +1) "string" +``` + +在上述示例中,`$`代表的是指向json document中value的`path`: +- 在上述示例中,`$`代表root + +除此之外,JSON还支持其他string operation。`JSON.STRLNE`支持获取string长度,并且可以通过`JSON.STRAPPEND`来在当前字符串后追加其他字符串: +```redis-cli +> JSON.STRLEN bike $ +1) (integer) 8 +> JSON.STRAPPEND bike $ '" (Enduro bikes)"' +1) (integer) 23 +> JSON.GET bike $ +"[\"Hyperion (Enduro bikes)\"]" +``` + +#### json数值操作 +RedisJSON支持`increment`和`multiply`操作: +```redis-cli +> JSON.SET crashes $ 0 +OK +> JSON.NUMINCRBY crashes $ 1 +"[1]" +> JSON.NUMINCRBY crashes $ 1.5 +"[2.5]" +> JSON.NUMINCRBY crashes $ -0.75 +"[1.75]" +> JSON.NUMMULTBY crashes $ 24 +"[42]" +``` + +#### json数组操作 +RedisJSON支持通过`JSON.SET`将值赋值为数组,`path expression`支持数组操作 +```redis-cli +> JSON.SET newbike $ '["Deimos", {"crashes": 0}, null]' +OK +> JSON.GET newbike $ +"[[\"Deimos\",{\"crashes\":0},null]]" +> JSON.GET newbike $[1].crashes +"[0]" +> JSON.DEL newbike $[-1] +(integer) 1 +> JSON.GET newbike $ +"[[\"Deimos\",{\"crashes\":0}]]" +``` + +##### `JSON.DEL` +`JSON.DEL`支持通过`path`对json值进行删除。 + +##### `JSON.ARRAPPEND` +支持向json array中追加值。 + +##### `JSON.ARRTRIM` +支持对json array进行裁剪。 + +```redis-cli +> JSON.SET riders $ [] +OK +> JSON.ARRAPPEND riders $ '"Norem"' +1) (integer) 1 +> JSON.GET riders $ +"[[\"Norem\"]]" +> JSON.ARRINSERT riders $ 1 '"Prickett"' '"Royce"' '"Castilla"' +1) (integer) 4 +> JSON.GET riders $ +"[[\"Norem\",\"Prickett\",\"Royce\",\"Castilla\"]]" +> JSON.ARRTRIM riders $ 1 1 +1) (integer) 1 +> JSON.GET riders $ +"[[\"Prickett\"]]" +> JSON.ARRPOP riders $ +1) "\"Prickett\"" +> JSON.ARRPOP riders $ +1) (nil) +``` + +#### json object操作 +json oject操作同样有其自己的命令,示例如下: +```redis-cli +> JSON.SET bike:1 $ '{"model": "Deimos", "brand": "Ergonom", "price": 4972}' +OK +> JSON.OBJLEN bike:1 $ +1) (integer) 3 +> JSON.OBJKEYS bike:1 $ +1) 1) "model" + 2) "brand" + 3) "price"> JSON.SET bike:1 $ '{"model": "Deimos", "brand": "Ergonom", "price": 4972}' +``` +#### format output +redis-cli支持对json内容的输出进行格式化,步骤如下: +- 在执行`redis-cli`时指定`--raw`选项 +- 通过formatting keywords来进行格式化 + - `INDENT` + - `NEWLINE` + - `SPACE` + +```bash +$ redis-cli --raw +> JSON.GET obj INDENT "\t" NEWLINE "\n" SPACE " " $ +[ + { + "name": "Leonard Cohen", + "lastSeen": 1478476800, + "loggedOut": true + } +] +``` + +#### Limitation +传递给command的json值最大深度只能为128,如果嵌套深度大于128,那么command将返回错误。 +