• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RedisJSON存储、更新和检索JSON文档

武飞扬头像
Ethanchen's notes
帮助1

RedisJON

RedisJSON 是一个Redis模块, 提供 JavaScript 对象表示法 (JSON) 支持。它允许您在 Redis 数据库中存储、更新和检索 JSON 值,类似于任何其他 Redis 数据类型。Redis JSON 还可以与搜索和查询无缝协作,让您可以索引和查询 JSON 文档。

  • RedisJSON - a JSON data type for Redis

版本下载

本文档使用 Redis6.2.12 版本,需下载GA版本的 redisJSON 兼容版本,如:

  • 2.2 GA (v2.2.0): This is the General Availability release of RedisJSON 2.2.

  • RedisJSON 2.0-RC1 (这是RedisJSON 2.0的第一个候选版本),要求Redis版本至少要 6.0 以上(Requires Redis v6 or above)

root@ubuntu-x64_01:/opt# wget -c "https://github.com/RedisJSON/RedisJSON/archive/refs/tags/v2.2.0.tar.gz"```

# 解压 
root@ubuntu-x64_01:/opt# tar -zxvf v2.2.0.tar.gz 

# 目录结构如下

root@ubuntu-x64_01:/opt/RedisJSON-2.2.0# ls -tlh 
total 128K
drwxrwxr-x 4 root root 4.0K 7月  22  2022 benchmarks
drwxrwxr-x 3 root root 4.0K 7月  22  2022 build
-rw-rw-r-- 1 root root  639 7月  22  2022 build.rs
-rw-rw-r-- 1 root root  21K 7月  22  2022 Cargo.lock
-rw-rw-r-- 1 root root 1.1K 7月  22  2022 Cargo.toml
-rw-rw-r-- 1 root root  13K 7月  22  2022 commands.json
drwxrwxr-x 3 root root 4.0K 7月  22  2022 deps
-rw-rw-r-- 1 root root 1.3K 7月  22  2022 Dockerfile
drwxrwxr-x 4 root root 4.0K 7月  22  2022 docs
-rw-rw-r-- 1 root root 5.7K 7月  22  2022 LICENSE
-rw-rw-r-- 1 root root 7.0K 7月  22  2022 Makefile
-rw-rw-r-- 1 root root  569 7月  22  2022 ramp.yml
-rw-rw-r-- 1 root root  13K 7月  22  2022 README.md
drwxrwxr-x 2 root root 4.0K 7月  22  2022 sbin
drwxrwxr-x 3 root root 4.0K 7月  22  2022 src
drwxrwxr-x 6 root root 4.0K 7月  22  2022 tests
-rw-rw-r-- 1 root root 4.5K 7月  22  2022 TODO.md
drwxrwxr-x 3 root root 4.0K 7月  22  2022 util

安装 Rust 包

root@ubuntu-x64_01:/opt# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

.......

You can uninstall at any time with rustup self uninstall and
these changes will be reverted.

Current installation options:

   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>

info: profile set to 'default'
info: default host triple is x86_64-unknown-linux-gnu
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2023-06-01, rust version 1.70.0 (90c541806 2023-05-31)
info: downloading component 'cargo'
  6.9 MiB /   6.9 MiB (100 %)   1.9 MiB/s in  3s ETA:  0s
info: downloading component 'clippy'
  2.2 MiB /   2.2 MiB (100 %)   1.9 MiB/s in  1s ETA:  0s
info: downloading component 'rust-docs'
 13.5 MiB /  13.5 MiB (100 %)   1.7 MiB/s in  7s ETA:  0s
info: downloading component 'rust-std'
 27.3 MiB /  27.3 MiB (100 %)   1.8 MiB/s in 15s ETA:  0s
info: downloading component 'rustc'
 64.3 MiB /  64.3 MiB (100 %)   1.6 MiB/s in 36s ETA:  0s
info: downloading component 'rustfmt'
  2.2 MiB /   2.2 MiB (100 %)   1.8 MiB/s in  1s ETA:  0s
info: installing component 'cargo'
  6.9 MiB /   6.9 MiB (100 %)   5.3 MiB/s in  1s ETA:  0s
info: installing component 'clippy'
info: installing component 'rust-docs'
 13.5 MiB /  13.5 MiB (100 %)   1.6 MiB/s in  6s ETA:  0s
info: installing component 'rust-std'
 27.3 MiB /  27.3 MiB (100 %)   5.9 MiB/s in  4s ETA:  0s
info: installing component 'rustc'
 64.3 MiB /  64.3 MiB (100 %)   7.1 MiB/s in  8s ETA:  0s
info: installing component 'rustfmt'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu installed - rustc 1.70.0 (90c541806 2023-05-31)


Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, run:
source "$HOME/.cargo/env"
  

Rustup元数据和工具链将被安装到Rustup中主目录,位于:/root/.rustup, 这可以用 RUSTUP_HOME 环境变量修改。

root@ubuntu-x64_01:/opt# ls -tlh   /root/.rustup
total 20K
-rw-r--r-- 1 root root  102 7月  10 13:54 settings.toml
drwxr-xr-x 2 root root 4.0K 7月  10 13:54 downloads
drwxr-xr-x 2 root root 4.0K 7月  10 13:54 update-hashes
drwxr-xr-x 2 root root 4.0K 7月  10 13:54 tmp
drwxr-xr-x 3 root root 4.0K 7月  10 13:53 toolchains

Cargo主目录位于: /root/.cargo, 这可以用 CARGO_HOME 环境变量修改。

root@ubuntu-x64_01:/opt# ls -tlh  /root/.cargo
total 8.0K
drwxr-xr-x 2 root root 4.0K 7月  10 13:53 bin
-rw-r--r-- 1 root root  300 7月  10 13:53 env

将会增加cargo, rustc, rustup等命令Cargo的bin目录,位于:

root@ubuntu-x64_01:/opt# ls -tlh   /root/.cargo/bin
total 191M
-rwxr-xr-x 14 root root 14M 7月  10 13:53 cargo
-rwxr-xr-x 14 root root 14M 7月  10 13:53 cargo-clippy
-rwxr-xr-x 14 root root 14M 7月  10 13:53 cargo-fmt
-rwxr-xr-x 14 root root 14M 7月  10 13:53 cargo-miri
-rwxr-xr-x 14 root root 14M 7月  10 13:53 clippy-driver
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rls
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rust-analyzer
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rustc
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rustdoc
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rustfmt
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rust-gdb
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rust-gdbgui
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rust-lldb
-rwxr-xr-x 14 root root 14M 7月  10 13:53 rustup

通过自动修改以下配置文件, 此路径被添加到path环境变量中:

  /root/.profile
  /root/.bash_profile
  /root/.bashrc

安装完 Rust 后, 开始构建 RedisJson , 如下报错: Unable to find libclang

root@ubuntu-x64_01:/opt/RedisJSON-2.2.0# cargo build --release
warning: the cargo feature `edition2021` has been stabilized in the 1.56 release and is no longer necessary to be listed in the 
......
......
......    
error: failed to run custom build command for `redis-module v1.0.1`

Caused by:
  process didn't exit successfully: `/opt/RedisJSON-2.2.0/target/release/build/redis-module-40c73addfe794448/build-script-build` (exit status: 101)
  --- stdout
  TARGET = Some("x86_64-unknown-linux-gnu")
  OPT_LEVEL = Some("3")
  HOST = Some("x86_64-unknown-linux-gnu")
  CC_x86_64-unknown-linux-gnu = None
  CC_x86_64_unknown_linux_gnu = None
  HOST_CC = None
  CC = None
  CFLAGS_x86_64-unknown-linux-gnu = None
  CFLAGS_x86_64_unknown_linux_gnu = None
  HOST_CFLAGS = None
  CFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
  running: "cc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "src/include/" "-Wall" "-Wextra" "-DREDISMODULE_EXPERIMENTAL_API" "-o" "/opt/RedisJSON-2.2.0/target/release/build/redis-module-fcfa58c3bd3a907b/out/src/redismodule.o" "-c" "src/redismodule.c"
  exit status: 0
  AR_x86_64-unknown-linux-gnu = None
  AR_x86_64_unknown_linux_gnu = None
  HOST_AR = None
  AR = None
  running: ZERO_AR_DATE="1" "ar" "cq" "/opt/RedisJSON-2.2.0/target/release/build/redis-module-fcfa58c3bd3a907b/out/libredismodule.a" "/opt/RedisJSON-2.2.0/target/release/build/redis-module-fcfa58c3bd3a907b/out/src/redismodule.o"
  exit status: 0
  running: "ar" "s" "/opt/RedisJSON-2.2.0/target/release/build/redis-module-fcfa58c3bd3a907b/out/libredismodule.a"
  exit status: 0
  cargo:rustc-link-lib=static=redismodule
  cargo:rustc-link-search=native=/opt/RedisJSON-2.2.0/target/release/build/redis-module-fcfa58c3bd3a907b/out

  --- stderr
  thread 'main' panicked at 'Unable to find libclang: "couldn't find any valid shared libraries matching: ['libclang.so', 'libclang-*.so', 'libclang.so.*', 'libclang-*.so.*'], set the `LIBCLANG_PATH` environment variable to a path where one of these files can be found (invalid: [])"', /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bindgen-0.59.2/src/lib.rs:2144:31
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...

安装 libclang 包后(安装版本要>3.9),再执行 build 操作:

# 安装 clang 包 
root@ubuntu-x64_01:/opt/RedisJSON-2.2.0# apt install -y clang-3.9
.....
将会同时安装下列软件:
  binfmt-support binutils-2.26 libclang-common-3.9-dev libclang1-3.9 libjsoncpp0 libllvm3.9v4
建议安装:
  binutils-2.26-doc gnustep gnustep-devel clang-3.9-doc
推荐安装:
  llvm-3.9-dev
下列软件包将被【卸载】:
  default-jre libgl1-mesa-dri libgl1-mesa-glx libllvm6.0 openjdk-8-jre
下列【新】软件包将被安装:
  binfmt-support binutils-2.26 clang-3.9 libclang-common-3.9-dev libclang1-3.9 libjsoncpp0 libllvm3.9v4
.......
.......

# 重新 build 
root@ubuntu-x64_01:/opt/RedisJSON-2.2.0# cargo build --release
warning: the cargo feature `edition2021` has been stabilized in the 1.56 release and is no longer necessary to be listed in the manifest
  See https://doc.rust-lang.org/cargo/reference/manifest.html#the-edition-field for more information about using this feature.
   Compiling redis-module v1.0.1
   Compiling array_tool v1.0.3
  ......
  ......
    Finished release [optimized   debuginfo] target(s) in 32.76s
warning: the following packages contain code that will be rejected by a future version of Rust: bson v0.14.1
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 1`

# 编译成功后,生成 so 文件 :
root@ubuntu-x64_01:/opt/RedisJSON-2.2.0# ls -tlh target/release/librejson.so 
-rwxr-xr-x 2 root root 22M 7月  10 16:18 target/release/librejson.so

或者,您可以从预编译的二进制文件下载并运行 Redis:

从Redis 下载中心下载 RedisJSON 的预编译版本。

启动redis server , 命令行参数 --loadmodule ./target/release/librejson.so , 这里使用Sentinel 模式,我们直接写在三个节点的配置文件中,如下:

chown redis:redis /usr/local/redisjson/librejson.so 

echo "loadmodule /usr/local/redisjson/librejson.so" >> /etc/redis6390.conf
echo "loadmodule /usr/local/redisjson/librejson.so" >> /etc/redis6391.conf
echo "loadmodule /usr/local/redisjson/librejson.so" >> /etc/redis6392.conf

启动Sentinel集群,检查 MODULE 加载情况,如下: 版本显示 20200

192.168.88.11:6390> MODULE LIST
1) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) (integer) 20200
192.168.88.11:6390> 
192.168.88.11:6390> INFO MODULES 
# Modules
module:name=ReJSON,ver=20200,api=1,filters=0,usedby=[],using=[],options=[handle-io-errors]
192.168.88.11:6390> 

使用 RedisJSON

使用 redis-cli 工具来使用尝试的第一个 JSON 命令是: JSON.SET,它使用 JSON 值设置 Redis 键。

JSON.SET接受所有 JSON 值类型。JSON.GET 获取JSON值, JSON.TYPE 判断值类型.

$符号表示JSON文档路径,这里指向根。

此示例创建一个 JSON 字符串:

192.168.88.11:6390> JSON.SET fruit $ '"apple"'
OK
192.168.88.11:6390> JSON.GET fruit $ 
"[\"apple\"]"
192.168.88.11:6390> JSON.TYPE fruit $
1) "string"

这里还有一些字符串操作。JSON.STRLEN 告诉您字符串的长度,您可以使用向其附加另一个字符串 JSON.STRAPPEND

192.168.88.11:6390> JSON.STRLEN fruit $ 
1) (integer) 5
192.168.88.11:6390> JSON.STRAPPEND  fruit $  '"(this is an apple)"'
1) (integer) 23
192.168.88.11:6390> 
192.168.88.11:6390> JSON.GET fruit $ 
"[\"apple(this is an apple)\"]"

删除操作,使用DEL命令

192.168.88.11:6390> JSON.DEL fruit $
(integer) 1
192.168.88.11:6390> JSON.GET fruit $ 
(nil)

使用整型类似,实现递增递减(NUMINCRBY )、次幂(NUMPOWBY)、NUMMULTBY(相乘) 操作

192.168.88.11:6390> JSON.GET int $ 
"[0]"
192.168.88.11:6390> JSON.NUMINCRBY int $ 1 
"[1]"
192.168.88.11:6390> JSON.NUMINCRBY int $ 1.5
"[2.5]"
192.168.88.11:6390> JSON.NUMINCRBY int $ -0.5
"[2.0]"
192.168.88.11:6390> JSON.NUMINCRBY int $ 10
"[12.0]"
192.168.88.11:6390> JSON.GET int $ 
"[12.0]"

# 如: 以2为底的2次幂操作
192.168.88.11:6390> JSON.SET int $ 2
OK
192.168.88.11:6390> JSON.NUMPOWBY int $ 2
"[4]"
192.168.88.11:6390> JSON.NUMPOWBY int $ 2
"[16]"
192.168.88.11:6390> JSON.NUMPOWBY int $ 2
"[256]"

# 如: 以2为底的3次幂操作
192.168.88.11:6390> JSON.SET int $ 2
OK
192.168.88.11:6390> JSON.NUMPOWBY int $ 3 
"[8]"
192.168.88.11:6390> JSON.NUMPOWBY int $ 3 
"[512]"

# 如, 以2为基数,每次操作乘以 2 
192.168.88.11:6390> JSON.SET int $ 2
OK
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[4]"
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[8]"
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[16]"
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[32]"
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[64]"
192.168.88.11:6390> JSON.NUMMULTBY int $ 2
"[128]"

使用JSON数组,对数据元素操作,插入、删除等操作

# 初始化数组
192.168.88.11:6390> JSON.SET myarr $ '[ true, "name", { "age": 18 }, null ]'
OK

# 获取数组所有元素
192.168.88.11:6390> JSON.GET myarr $ 
"[[true,\"name\",{\"age\":18},null]]"

# 获取数组第二个元素,注意数组下标从零开始
192.168.88.11:6390> JSON.GET myarr $[1] 
"[\"name\"]"

# 获取数组第三个元素中的age字段
192.168.88.11:6390> JSON.GET myarr $[2].age 
"[18]"

# 获取数组,最后一个元素
192.168.88.11:6390> JSON.GET myarr $[-1] 
"[null]"

# 删除数组最后一个元素
192.168.88.11:6390> JSON.DEL myarr $[-1] 
(integer) 1

# 删除数组最后一个元素, 可以使用专用的 JSON 命令子集 ARRPOP 
192.168.88.11:6390> JSON.ARRPOP myarr $ 
1) "null"

# 往数组加入元素,返回元素的下标
192.168.88.11:6390> JSON.ARRAPPEND myarr $ 1
1) (integer) 4

192.168.88.11:6390>  JSON.GET myarr $
"[[true,\"name\",{\"age\":18},1]]"

192.168.88.11:6390> JSON.ARRAPPEND myarr $ '"address"'
1) (integer) 5

192.168.88.11:6390> JSON.GET myarr $
"[[true,\"name\",{\"age\":18},1,\"address\"]]"


# 往数组的头部,插入: one、two 两个元素
192.168.88.11:6390> JSON.ARRINSERT myarr $ 0 '"one"' '"two"'
1) (integer) 7

192.168.88.11:6390> JSON.GET myarr $
"[[\"one\",\"two\",true,\"name\",{\"age\":18},1,\"address\"]]"

# 数组修剪,保留 下标为 2 ~ 4 的元素,其它删除
192.168.88.11:6390> JSON.ARRTRIM myarr $ 2 4 
1) (integer) 3
192.168.88.11:6390> JSON.GET myarr $
"[[true,\"name\",{\"age\":18}]]"

使用JSON 对象操作


# 初始化JSON对象
192.168.88.11:6390> JSON.SET myobj $ '{"name":"chen","age":18, "updatetime":1689238068,"enable": true}'
OK

# 获取json对象长度
192.168.88.11:6390> JSON.OBJLEN myobj $
1) (integer) 4

# 获取json对象键值
192.168.88.11:6390> JSON.OBJKEYS myobj $
1) 1) "name"
   2) "age"
   3) "updatetime"
   4) "enable"

# 获取 json 单个元素
192.168.88.11:6390> JSON.GET myobj $.name
"[\"chen\"]"
192.168.88.11:6390> JSON.GET myobj $.age
"[18]"

获取多个键操作

192.168.88.11:6390> JSON.MGET myobj myarr $ 
1) "[{\"name\":\"chen\",\"age\":18,\"updatetime\":1689238068,\"enable\":true}]"
2) "[[true,\"name\",{\"age\":18}]]"

要以更易于理解的格式返回 JSON 响应,请在原始输出模式下运行 --raw

/usr/local/redis/bin/redis-cli -h 192.168.88.11 -p 6390  -a "******" --raw 

192.168.88.11:6390> JSON.GET myobj INDENT "\t" NEWLINE "\n" SPACE " " $
[
        {
                "name": "chen",
                "age": 18,
                "updatetime": 1689238068,
                "enable": true
        }
]

Python

使用 PYTHON 操作 Redis JSON 示例如下 :


import json
from redis.sentinel import Sentinel

# 定义函数,传入 redis 对象
def redis_json(redis_server):
    data = {
                "name": "chen",
                "age": 20,
                "updatetime": 1689238068,
                "enable": True
    }
    redis_server.json().set('doc', '$', data)
    doc = redis_server.json().get('doc', '$')
    name = redis_server.json().get('doc', '$.name')
    age = redis_server.json().get('doc', '$.age')
    print(f"doc: {json.dumps(doc, indent=4)}")

# 输出如下
doc: [
    {
        "name": "chen",
        "age": 20,
        "updatetime": 1689238068,
        "enable": true
    }
]

总结

  • 局限性
    传递给命令的 JSON 值的深度最多可达 128。如果传递给命令的 JSON 值包含嵌套级别超过 128 的对象或数组,则该命令将返回错误。
  • RAM
    在使用Redis JSON 时,要关注下 RAM 使用情况, Redis JSON 在反序列化后将 JSON 值存储为二进制数据。就尺寸而言,这种表示形式通常比序列化形式更昂贵。JSON 数据类型的每个值至少使用 24 个字节(在 64 位架构上)。可以做一些基准测试,以评估是否投入业务使用。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbhbgf
系列文章
更多 icon
同类精品
更多 icon
继续加载