为什么不应该在生产环境的Redis中使用KEYS进行验证的原因

我认为在Redis中经常使用的命令之一是KEYS。在官方文档中,它被写成以下这样,但我想具体了解为什么它不可取。

警告:请谨慎使用命令KEYS,仅在生产环境中使用。当对大型数据库执行此命令时,可能会影响性能。该命令旨在用于调试和特殊操作,例如更改键空间布局。

进行实验

    • CentOS Linux release 7.4.1708 (Core)

 

    • Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz

 

    • DDR4 16GB RAM

 

    redis-server 5.0.7

在该环境下,同时执行对于KEY和SCAN的操作,然后测量redis-benchmark的每秒请求数(RPS)。

准备好

运行redis-server

docker run --rm -it --name redis -p6379:6379 redis:5.0.7

redis-benchmark的启动方式

redis-benchmark -t get -c 1

以Rust编写的程序

包的名称是”dont-use-redis-keys”,版本是”0.1.0″,作者是”yukinarit”,适用的 Rust 版本是”2018″。该包依赖于”redis”、”structopt”、”tokio”和”futures”这些库。
main.rs使用std时间库中的Instant方法;
使用futures库中的future和prelude模块以及redis库中的Client和Commands模块;
使用structopt库的StructOpt模块;
使用tokio库的Builder模块。

#[derive(StructOpt)]宏定义一个Opt枚举,其中包含Setup、Keys、Scan、BenchKeys和BenchScan几个选项。
#[derive(StructOpt)]宏定义一个BenchOpt结构体,其中包含count和pipeline字段。

fn main()函数开始执行,获取命令行参数opt(Opt枚举类型);
创建redis客户端实例redis,并连接到本地Redis服务;
创建一个tokio运行时实例rt,并指定使用一个核心线程;
获取程序开始执行的时间start。

根据opt的取值,执行相应的逻辑:
– 如果是Setup选项,则根据count值设置一定数量的键值对;
– 如果是Keys选项,则循环执行”KEYS”命令,并输出获取到的结果;
– 如果是Scan选项,则循环执行”SCAN”命令,在匹配到指定的键时输出结果;
– 如果是BenchKeys选项,则以并行连接的方式执行一定数量的”KEYS”命令,并计算请求频率;
– 如果是BenchScan选项,则以并行连接的方式执行一定数量的”SCAN”命令,并计算请求频率。

在执行对应逻辑的过程中,根据需要进行错误处理和打印。最后输出程序的执行时间。

    テストデータ作成
cargo run -- setup -c <NUM_KEYS>
    KEYSを続けて実行し続ける
cargo run -- keys
    SCANを続けて実行し続ける
cargo run -- scan

结果 (jié guǒ)

redis-benchmark.png

当使用KEYS命令时,随着Redis的键数量增加,redis-benchmark的RPS会显著变慢。与未执行任何操作相比,SCAN命令稍微变慢,但无论键的数量增加多少,RPS都保持稳定。

以下是测量结果的原始数据。

当未执行任何操作时的结果键的数量
redis-benchmark每秒请求数(RPS)

1,000
29,638.41

10,000
29,994.00

100,000
30,165.91

500,000
29,761.91

1,000,000
29,931.16

5,000,000
29,205.61

10,000,000
28,719.13

执行KEYS的结果:键的数量
redis-benchmark的RPS

1,000
16353.23

10,000
3630.82

100,000
373.79

500,000
31.03

1,000,000
14.02

5,000,000
2.52

10,000,000
1.08

执行SCAN后的结果:键的数量
redis-benchmark的RPS

1,000
26,413.10

10,000
25,940.34

100,000
25,974.03

500,000
25,806.45

1,000,000
25,680.53

5,000,000
23,900.57

10,000,000
24,473.81

总结

KEYSはRedis全体のKeyの数に対してO(N)

Redisのメインの処理はシングスレッドで行われる
本番環境ではKEYSではなくSCANを使うこと
Redisのスレッドを完全にblockしてもいい場合のみだけKEYSを使おう
これらのことは全てドキュメントに書いてある

广告
将在 10 秒后关闭
bannerAds