跳转到主要内容

KeyDB 客户端 - 命令行界面

keydb-cli 是 KeyDB 的命令行界面,一个简单的程序,允许直接从终端向 KeyDB 发送命令,并读取服务器返回的响应。

它有两种主要模式:一种是交互模式,其中有一个 REPL (读取-求值-打印-循环),用户可以在其中键入命令并获得回复;另一种模式是将命令作为 keydb-cli 的参数发送,执行后打印在标准输出上。

在交互模式下,keydb-cli 具备基本的行编辑功能,以提供良好的输入体验。

然而 keydb-cli 不仅仅如此。你可以使用一些选项来启动程序,使其进入特殊模式,这样 keydb-cli 就可以完成更复杂的任务,比如模拟一个副本并打印它从主节点接收到的复制流,检查 KeyDB 服务器的延迟并显示统计数据,甚至显示延迟样本和频率的 ASCII 艺术频谱图,以及许多其他事情。

本指南将涵盖 keydb-cli 的不同方面,从最简单的开始,到更高级的结束。

如果你将要广泛使用 KeyDB,或者你已经在使用,那么你很可能会经常使用 keydb-cli。花些时间熟悉它很可能是一个非常好的主意,你会发现一旦你掌握了其命令行界面的所有技巧,你使用 KeyDB 的效率会更高。

命令行用法#

要运行一个命令并将其回复打印到标准输出,只需将要执行的命令作为 keydb-cli 的独立参数输入即可。

$ keydb-cli incr mycounter
(integer) 7

命令的回复是 "7"。由于 KeyDB 的回复是带类型的(它们可以是字符串、数组、整数、NULL、错误等),所以你会在括号里看到回复的类型。然而,当 keydb-cli 的输出需要用作另一个命令的输入时,或者当我们要将其重定向到一个文件时,这样做就不太理想了。

实际上,只有当 keydb-cli 检测到标准输出是一个 tty(基本上就是终端)时,它才会显示这些提高人类可读性的附加信息。否则,它会自动启用*原始输出模式*,如下例所示:

$ keydb-cli incr mycounter > /tmp/output.txt
$ cat /tmp/output.txt
8

这次输出中省略了 (integer),因为 CLI 检测到输出不再写入终端。你也可以使用 --raw 选项强制在终端上使用原始输出:

$ keydb-cli --raw incr mycounter
9

同样,当写入文件或通过管道传递给其他命令时,你可以使用 --no-raw 强制使用人类可读的输出。

主机、端口、密码和数据库#

默认情况下,keydb-cli 连接到 127.0.0.1 的 6379 端口。如你所料,你可以通过命令行选项轻松更改此设置。要指定不同的主机名或 IP 地址,请使用 -h。要设置不同的端口,请使用 -p

$ keydb-cli -h keydb15.localnet.org -p 6390 ping
PONG

如果你的实例受密码保护,-a <password> 选项将执行身份验证,从而无需显式使用 AUTH 命令。

$ keydb-cli -a myUnguessablePazzzzzword123 ping
PONG

或者,也可以通过 REDISCLI_AUTH 环境变量向 keydb-cli 提供密码。

最后,可以通过使用 -n <dbnum> 选项,在非默认的零号数据库上执行命令。

$ keydb-cli flushall
OK
$ keydb-cli -n 1 incr a
(integer) 1
$ keydb-cli -n 1 incr a
(整数) 2
$ keydb-cli -n 2 incr a
(integer) 1

部分或全部这些信息也可以通过使用 -u <uri> 选项和有效的 URI 来提供。

$ keydb-cli -u keydb://p%40ssw0rd@keydb-16379.hosted.com:16379/0 ping
PONG

SSL/TLS#

默认情况下,keydb-cli 使用普通的 TCP 连接来连接到 KeyDB。你可以使用 --tls 选项启用 SSL/TLS,同时使用 --cacert--cacertdir 来配置受信任的根证书包或目录。

如果目标服务器需要使用客户端证书进行身份验证,你可以使用 --cert--key 指定证书和相应的私钥。

从其他程序获取输入#

有两种方法可以使用 keydb-cli 从其他命令(基本上是从标准输入)获取输入。一种是使用从 *stdin* 读取的有效负载作为最后一个参数。例如,要将一个 KeyDB 键设置为我电脑上 /etc/services 文件的内容,我可以使用 -x 选项:

$ keydb-cli -x set foo < /etc/services
OK
$ keydb-cli getrange foo 0 50
"#\n# Network services, Internet style\n#\n# Note that "

如你在上面会话的第一行所见,SET 命令的最后一个参数没有被指定。参数只是 SET foo,没有我希望键被设置的实际值。

取而代之的是,指定了 -x 选项,并将一个文件重定向到 CLI 的标准输入。因此,输入被读取,并用作命令的最后一个参数。这对于编写脚本很有用。

另一种方法是向 keydb-cli 提供一个写在文本文件中的命令序列:

$ cat /tmp/commands.txt
set foo 100
incr foo
append foo xxx
get foo
$ cat /tmp/commands.txt | keydb-cli
OK
(integer) 101
(integer) 6
"101xxx"

commands.txt 中的所有命令都由 keydb-cli 一个接一个地执行,就好像它们是由用户在交互式模式下输入的一样。如果需要,文件中的字符串可以用引号括起来,这样就可以在单个参数中包含空格、换行符或其他特殊字符。

$ cat /tmp/commands.txt
set foo "This is a single argument"
strlen foo
$ cat /tmp/commands.txt | keydb-cli
OK
(integer) 25

连续运行同一命令#

可以按用户选择的暂停时间间隔,将同一命令执行指定的次数。这在不同情况下都很有用,例如,当我们想持续监控某些键的内容或 INFO 字段的输出时,或者当我们想模拟某些周期性的写事件(比如每 5 秒向一个列表中推入一个新项目)时。

这个功能由两个选项控制:-r <count>-i <delay>。前者指定命令运行的次数,后者配置不同命令调用之间的延迟,单位是秒(可以指定小数,如 0.1 表示 100 毫秒)。

默认情况下,间隔(或延迟)设置为 0,因此命令会尽快执行。

$ keydb-cli -r 5 incr foo
(integer) 1
(整数) 2
(整数) 3
(整数) 4
(整数) 5

要永久运行同一命令,请使用 -1 作为计数。因此,为了随时间监控 RSS 内存大小,可以使用如下命令:

$ keydb-cli -r -1 -i 1 INFO | grep rss_human
used_memory_rss_human:1.38M
used_memory_rss_human:1.38M
used_memory_rss_human:1.38M
... 每秒会打印一个新行 ...

使用 keydb-cli 进行批量数据插入#

使用 keydb-cli 进行批量插入的内容在一个单独的页面中介绍,因为它本身就是一个值得讨论的话题。请参考我们的批量插入指南

CSV 输出#

有时你可能想使用 keydb-cli 将数据从 KeyDB 快速导出到外部程序。这可以通过使用 CSV(逗号分隔值)输出功能来实现。

$ keydb-cli lpush mylist a b c d
(整数) 4
$ keydb-cli --csv lrange mylist 0 -1
"d","c","b","a"

目前还不能像这样导出整个数据库,只能运行带有 CSV 输出的单个命令。

运行 Lua 脚本#

keydb-cli 广泛支持 KeyDB 3.2 起提供的 Lua 脚本新调试功能。有关此功能,请参阅 KeyDB Lua 调试器文档

然而,即使不使用调试器,你也可以使用 keydb-cli 从文件中运行脚本,这比在 shell 中交互式地输入脚本或作为参数输入要方便得多。

$ cat /tmp/script.lua
return keydb.call('set',KEYS[1],ARGV[1])
$ keydb-cli --eval /tmp/script.lua foo , bar
OK

KeyDB 的 EVAL 命令将脚本使用的键列表和其他非键参数作为不同的数组。调用 EVAL 时,你需要提供键的数量。然而,使用 keydb-cli 和上面的 --eval 选项,就不需要显式指定键的数量。取而代之的是,它使用逗号分隔键和参数的约定。这就是为什么在上面的调用中你会看到 foo , bar 作为参数。

所以 foo 将填充 KEYS 数组,而 bar 将填充 ARGV 数组。

--eval 选项在编写简单脚本时很有用。对于更复杂的工作,使用 Lua 调试器无疑更方便。可以将这两种方法结合起来,因为调试器也支持从外部文件执行脚本。

交互模式#

到目前为止,我们探讨了如何将 KeyDB CLI 用作命令行程序。这对于脚本和某些类型的测试非常有用,但大多数人会在 keydb-cli 中花费大部分时间使用其交互模式。

在交互模式下,用户在提示符处输入 KeyDB 命令。命令被发送到服务器,处理后,回复被解析并以更易于阅读的形式呈现。

运行 CLI 的交互模式不需要任何特殊操作——只需不带任何参数启动它,你就可以进入了:

$ keydb-cli
127.0.0.1:6379> ping
PONG

字符串 127.0.0.1:6379> 是提示符。它提醒你已连接到给定的 KeyDB 实例。

当你连接的服务器发生变化,或者当你在非零号数据库上操作时,提示符会发生变化。

127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> dbsize
(integer) 1
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> dbsize
(integer) 503

处理连接和重连#

在交互模式下使用 connect 命令,可以通过指定要连接的*主机名*和*端口*来连接到不同的实例。

127.0.0.1:6379> connect metal 6379
metal:6379> ping
PONG

如你所见,提示符也相应地改变了。如果用户尝试连接到一个无法访问的实例,keydb-cli会进入断开连接模式,并在每次新命令时尝试重新连接。

127.0.0.1:6379> connect 127.0.0.1 9999
无法连接到 keydb at 127.0.0.1:9999: Connection refused
not connected> ping
无法连接到 keydb at 127.0.0.1:9999: Connection refused
not connected> ping
无法连接到 keydb at 127.0.0.1:9999: Connection refused

通常在检测到断开连接后,CLI 总是会尝试透明地重新连接:如果尝试失败,它会显示错误并进入断开连接状态。以下是断开连接和重新连接的示例:

127.0.0.1:6379> debug restart
无法连接到 keydb at 127.0.0.1:6379: Connection refused
not connected> ping
PONG
127.0.0.1:6379> (现在我们又重新连接了)

当执行重连时,keydb-cli 会自动重新选择最后选择的数据库编号。然而,所有其他关于连接的状态都会丢失,例如如果我们正处于事务中,事务的状态会丢失。

$ keydb-cli
127.0.0.1:6379> multi
OK
127.0.0.1:6379> ping
QUEUED
( 这里服务器被手动重启 )
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI

在交互模式下使用 CLI 进行测试时,这通常不是问题,但你应该意识到这个限制。

编辑、历史、补全和提示#

你可以通过按箭头键(上和下)来访问已执行命令的历史记录,以避免一次又一次地重新输入它们。历史记录在 CLI 重启之间会被保留,保存在用户主目录下的一个名为 .keydbcli_history 的文件中,该目录由 HOME 环境变量指定。可以通过设置 keydbCLI_HISTFILE 环境变量来使用不同的历史文件名,也可以通过将其设置为 /dev/null 来禁用它。

CLI 也能够通过按 TAB 键来执行命令名补全,如下例所示:

127.0.0.1:6379> Z<TAB>
127.0.0.1:6379> ZADD<TAB>
127.0.0.1:6379> ZCARD<TAB>

一旦你在提示符处输入了一个 KeyDB 命令名,CLI 将会显示语法提示。这个行为可以通过 CLI 偏好设置来开启和关闭。

偏好设置#

有两种方法可以自定义 CLI 的行为。你主目录中的 .redisclirc 文件会在 CLI 启动时加载。你可以通过设置 REDISCLI_RCFILE 环境变量为备用路径来覆盖文件的默认位置。偏好设置也可以在 CLI 会话期间设置,这种情况下它们只会持续到会话结束。

要设置偏好,请使用特殊的 :set 命令。可以设置以下偏好,可以通过在 CLI 中键入命令或将其添加到 .redisclirc 文件中:

  • :set hints - 启用语法提示
  • :set nohints - 禁用语法提示

运行同一命令 N 次#

通过在命令名前加上一个数字,可以多次运行同一个命令。

127.0.0.1:6379> 5 incr mycounter
(integer) 1
(整数) 2
(整数) 3
(整数) 4
(整数) 5

显示关于 KeyDB 命令的帮助#

KeyDB 有许多命令,有时在测试时,你可能不记得参数的确切顺序。keydb-cli 使用 help 命令为大多数 KeyDB 命令提供在线帮助。该命令有两种使用形式:

  • help @<category> 显示关于给定类别的所有命令。类别包括:@generic, @list, @set, @sorted_set, @hash, @pubsub, @transactions, @connection, @server, @scripting, @hyperloglog
  • help <commandname> 显示作为参数给出的命令的特定帮助。

例如,要显示 PFADD 命令的帮助,请使用:

127.0.0.1:6379> help PFADD
PFADD key element [element ...]

摘要:将指定的元素添加到指定的 HyperLogLog 中。

请注意,help 也支持 TAB 补全。

清空终端屏幕#

在交互模式下使用 clear 命令可以清空终端屏幕。

特殊操作模式#

到目前为止,我们看到了 keydb-cli 的两种主要模式。

  • KeyDB 命令的命令行执行。
  • 交互式“类 REPL”用法。

然而,CLI 还执行与 KeyDB 相关的其他辅助任务,这些任务将在下一节中解释。

  • 用于显示 KeyDB 服务器连续统计信息的监控工具。
  • 扫描 KeyDB 数据库以查找非常大的键。
  • 带模式匹配的键空间扫描器。
  • 作为发布/订阅客户端订阅频道。
  • 监控在 KeyDB 实例中执行的命令。
  • 以不同方式检查 KeyDB 服务器的延迟
  • 检查本地计算机的调度程序延迟。
  • 从远程 KeyDB 服务器本地传输 RDB 备份。
  • 充当 KeyDB 副本,以显示副本接收到的内容。
  • 模拟LRU工作负载以显示关于键命中的统计信息。
  • Lua 调试器的客户端。

连续统计模式#

这可能是 keydb-cli 鲜为人知的功能之一,也是实时监控 KeyDB 实例非常有用的功能。要启用此模式,请使用 --stat 选项。输出非常清晰地说明了 CLI 在此模式下的行为:

$ keydb-cli --stat
------- data ------ --------------------- load -------------------- - child -
keys mem clients blocked requests connections
506 1015.00K 1 0 24 (+0) 7
506 1015.00K 1 0 25 (+1) 7
506 3.40M 51 0 60461 (+60436) 57
506 3.40M 51 0 146425 (+85964) 107
507 3.40M 51 0 233844 (+87419) 157
507 3.40M 51 0 321715 (+87871) 207
508 3.40M 51 0 408642 (+86927) 257
508 3.40M 51 0 497038 (+88396) 257

在这种模式下,每秒都会打印一行新数据,其中包含有用的信息以及与旧数据点的差异。你可以轻松了解内存使用情况、连接的客户端等情况。

在这种情况下,-i <interval> 选项作为一个修饰符,用于更改新行发出的频率。默认值为一秒。

扫描大键#

在这种特殊模式下,`keydb-cli` 作为一个键空间分析器。它扫描数据集以查找大键,并提供有关数据集所包含的数据类型的信息。此模式通过 `--bigkeys` 选项启用,并产生相当详细的输出:

$ keydb-cli --bigkeys
# 正在扫描整个键空间以查找最大的键以及
# 每种键类型的平均大小。你可以使用 -i 0.1 来在每 100 个 SCAN 命令之间休眠 0.1 秒
#(通常不需要)。
[00.00%] 到目前为止找到的最大的字符串是 'key-419',大小为 3 字节
[05.14%] 到目前为止找到的最大的列表是 'mylist',有 100004 个项目
[35.77%] 到目前为止找到的最大的字符串是 'counter:__rand_int__',大小为 6 字节
[73.91%] 到目前为止找到的最大的哈希是 'myobject',有 3 个字段
-------- 摘要 -------
在键空间中抽样了 506 个键!
总键长为 3452 字节(平均长度 6.82)
找到的最大的字符串 'counter:__rand_int__' 有 6 字节
找到的最大的列表 'mylist' 有 100004 个项目
找到的最大的哈希 'myobject' 有 3 个字段
504 个字符串,共 1403 字节 (占键的 99.60%,平均大小 2.78)
1 个列表,有 100004 个项目 (占键的 00.20%,平均大小 100004.00)
0 个集合,有 0 个成员 (占键的 00.00%,平均大小 0.00)
1 个哈希,有 3 个字段 (占键的 00.20%,平均大小 3.00)
0 个有序集合,有 0 个成员 (占键的 00.00%,平均大小 0.00)

在输出的第一部分,每个比之前遇到的同类型最大键还要大的新键都会被报告。摘要部分提供了关于 KeyDB 实例内部数据的一般统计信息。

该程序使用 `SCAN` 命令,因此可以在繁忙的服务器上执行而不会影响操作,但是可以使用 `-i` 选项来为每请求 100 个键而将扫描过程节流指定的秒数。例如,`-i 0.1` 会大大减慢程序的执行速度,但也会将服务器上的负载降低到极小的量。

请注意,摘要还以更清晰的形式报告了每次找到的最大键。初始输出只是为了在针对非常大的数据集运行时尽快提供一些有趣的信息。

获取键列表#

也可以扫描键空间,同样以不阻塞 KeyDB 服务器的方式(这在使用像 KEYS * 这样的命令时会发生),并打印所有的键名,或者根据特定模式进行过滤。这种模式,就像 --bigkeys 选项一样,使用 SCAN 命令,所以如果数据集正在改变,键可能会被多次报告,但如果某个键从迭代开始就存在,那么它绝不会被遗漏。由于它使用的命令,这个选项被称为 --scan

$ keydb-cli --scan | head -10
key-419
key-71
key-236
key-50
key-38
key-458
key-453
key-499
key-446
key-371

注意,使用 head -10 是为了只打印输出的前几行。

扫描能够使用 SCAN 命令底层的模式匹配功能,配合 --pattern 选项。

$ keydb-cli --scan --pattern '*-11*'
key-114
key-117
key-118
key-113
key-115
key-112
key-119
key-11
key-111
key-110
key-116

通过管道将输出传递给 `wc` 命令,可以按键名计算特定类型的对象数量。

$ keydb-cli --scan --pattern 'user:*' | wc -l
3829433

发布/订阅模式#

CLI 能够仅使用 `PUBLISH` 命令在 KeyDB 的发布/订阅频道中发布消息。这是意料之中的,因为 `PUBLISH` 命令与任何其他命令非常相似。订阅频道以接收消息则不同——在这种情况下,我们需要阻塞并等待消息,因此这在 `keydb-cli` 中被实现为一种特殊模式。与其他特殊模式不同,此模式不是通过使用特殊选项启用的,而是简单地在交互式或非交互式模式下使用 `SUBSCRIBE` 或 `PSUBSCRIBE` 命令。

$ keydb-cli psubscribe '*'
正在读取消息... (按 Ctrl-C 退出)
1) "psubscribe"
2) "*"
3) (integer) 1

“正在读取消息”的信息表明我们进入了发布/订阅模式。当另一个客户端在某个频道发布消息时,比如你可以使用 `keydb-cli PUBLISH mychannel mymessage`,处于发布/订阅模式的 CLI 将会显示如下内容:

1) "pmessage"
2) "*"
3) "mychannel"
4) "mymessage"

这对于调试发布/订阅问题非常有用。要退出发布/订阅模式,只需按 `CTRL-C`。

监控在 KeyDB 中执行的命令#

与发布/订阅模式类似,一旦您使用 `MONITOR` 模式,监控模式就会自动进入。它将打印出 KeyDB 实例接收到的所有命令。

$ keydb-cli monitor
OK
1460100081.165665 [0 127.0.0.1:51706] "set" "foo" "bar"
1460100083.053365 [0 127.0.0.1:51707] "get" "foo"

请注意,可以使用管道输出来重定向输出,因此您可以使用 `grep` 等工具来监控特定模式。

监控 KeyDB 实例的延迟#

KeyDB 经常用于延迟非常关键的场景。延迟涉及应用程序中的多个活动部分,从客户端库到网络堆栈,再到 KeyDB 实例本身。

CLI 有多种工具用于研究 KeyDB 实例的延迟,并了解延迟的最大值、平均值和分布情况。

基本的延迟检查工具是 `--latency` 选项。使用此选项,CLI 会运行一个循环,其中 `PING` 命令被发送到 KeyDB 实例,并测量获取回复的时间。这个过程每秒发生 100 次,统计数据会在控制台中实时更新。

$ keydb-cli --latency
min: 0, max: 1, avg: 0.19 (427 samples)

统计数据以毫秒为单位提供。通常,一个非常快的实例的平均延迟往往会因为运行 `keydb-cli` 的系统内核调度器的延迟而被高估一些,所以上面 0.19 的平均延迟很可能实际上是 0.01 或更少。然而,这通常不是一个大问题,因为我们关心的是几毫秒或更长时间的事件。

有时,研究最大和平均延迟如何随时间演变会很有用。`--latency-history` 选项就是为此目的而设计的:它的工作方式与 `--latency` 完全相同,但默认情况下每 15 秒就会从头开始一个新的采样会话。

$ keydb-cli --latency-history
min: 0, max: 1, avg: 0.14 (1314 samples) -- 15.01 seconds range
min: 0, max: 1, avg: 0.18 (1299 samples) -- 15.00 seconds range
min: 0, max: 1, avg: 0.20 (113 samples)^C

您可以使用 `-i <interval>` 选项更改采样会话的长度。

最先进的延迟研究工具,但对于没有经验的用户来说也更难解释,是使用彩色终端显示延迟频谱的能力。你会看到一个彩色的输出,指示不同百分比的样本,以及不同的 ASCII 字符指示不同的延迟数字。此模式通过使用 `--latency-dist` 选项启用。

$ keydb-cli --latency-dist
(输出未显示,需要彩色终端,试试看!)

在 `keydb-cli` 中还实现了一个相当不寻常的延迟工具。它不检查 KeyDB 实例的延迟,而是检查你正在运行 `keydb-cli` 的计算机的延迟。你可能会问,是什么延迟?是内核调度器、虚拟机管理程序(如果是虚拟化实例)等固有的延迟。

我们称之为*固有延迟*,因为它对程序员来说大多是不透明的。如果你的 KeyDB 实例延迟很差,并且排除了所有明显的可能原因,那么值得通过直接在运行 KeyDB 服务器的系统上以这种特殊模式运行 `keydb-cli` 来检查你的系统能达到的最佳性能。

通过测量固有延迟,你就知道了这是基线,KeyDB 不可能超越你的系统。要以这种模式运行 CLI,请使用 `--intrinsic-latency <test-time>`。测试时间以秒为单位,指定 `keydb-cli` 应该检查其当前运行系统的延迟多少秒。

$ ./keydb-cli --intrinsic-latency 5
到目前为止的最大延迟:1 微秒。
到目前为止的最大延迟:7 微秒。
到目前为止的最大延迟:9 微秒。
到目前为止的最大延迟:11 微秒。
到目前为止的最大延迟:13 微秒。
到目前为止的最大延迟:15 微秒。
到目前为止的最大延迟:34 微秒。
到目前为止的最大延迟:82 微秒。
到目前为止的最大延迟:586 微秒。
到目前为止的最大延迟:739 微秒。
总共运行 65433042 次 (平均延迟: 0.0764 微秒 / 每次运行 764.14 纳秒)。
最差的运行比平均延迟长 9671 倍。

重要提示:此命令必须在您要运行 KeyDB 服务器的计算机上执行,而不是在其他主机上。它甚至不会连接到 KeyDB 实例,只在本地执行测试。

在上述情况下,我的系统的最坏情况延迟不能好于 739 微秒,所以我可以预期某些查询会不时地在略低于 1 毫秒的时间内运行。

RDB 文件的远程备份#

在 KeyDB 复制的第一次同步期间,主节点和副本以 RDB 文件的形式交换整个数据集。`keydb-cli` 利用此功能提供远程备份工具,允许将 RDB 文件从任何 KeyDB 实例传输到运行 `keydb-cli` 的本地计算机。要使用此模式,请使用 `--rdb <dest-filename>` 选项调用 CLI。

$ keydb-cli --rdb /tmp/dump.rdb
SYNC 已发送到主服务器,正在将 13256 字节写入 '/tmp/dump.rdb'
传输成功完成。

这是一种简单而有效的方法,可以确保您拥有 KeyDB 实例的灾难恢复 RDB 备份。但是,在脚本或 `cron` 作业中使用此选项时,请务必检查命令的返回值。如果非零,则表示发生了错误,如下例所示:

$ keydb-cli --rdb /tmp/dump.rdb
与主服务器的 SYNC 失败:-ERR 在未与我的主服务器连接时无法 SYNC
$ echo $?
1

副本模式#

CLI 的副本模式是一项高级功能,对 KeyDB 开发人员和调试操作很有用。它允许检查主服务器在复制流中发送给其副本的内容,以将写入操作传播到其副本。选项名称很简单,就是 `--replica`。以下是它的工作原理:

$ keydb-cli --replica
与主服务器同步,丢弃 13256 字节的批量传输...
同步完成。正在记录来自主服务器的命令。
"PING"
"SELECT","0"
"set","foo","bar"
"PING"
"incr","mycounter"

该命令首先丢弃第一次同步的 RDB 文件,然后以 CSV 格式记录接收到的每个命令。

如果你认为某些命令在你的副本中没有被正确复制,这是一个很好的检查方式,也是为了改进错误报告而提供的有用信息。

执行 LRU 模拟#

KeyDB 经常被用作带有 LRU 驱逐策略的缓存。根据键的数量和为缓存分配的内存量(通过 `maxmemory` 指令指定),缓存命中和未命中的数量会发生变化。有时,模拟命中率对于正确配置缓存非常有用。

CLI 有一种特殊模式,可以模拟 GET 和 SET 操作,请求模式使用 80-20% 的幂律分布。这意味着 20% 的键将被请求 80% 的次数,这在缓存场景中是一种常见的分布。

理论上,给定请求的分布和 KeyDB 的内存开销,应该可以用数学公式来分析计算命中率。然而,KeyDB 可以配置不同的 LRU 设置(样本数量),并且 KeyDB 中的 LRU 实现是近似的,不同版本之间有很大差异。同样,每个键的内存量也可能在不同版本之间发生变化。这就是为什么这个工具被构建出来的原因:它的主要动机是测试 KeyDB LRU 实现的质量,但现在它也对测试特定版本在你部署时所设想的设置下的行为很有用。

要使用此模式,您需要指定测试中的键数。您还需要配置一个合理的 `maxmemory` 设置作为初步尝试。

重要提示:在 KeyDB 配置中配置 `maxmemory` 设置至关重要:如果对最大内存使用没有上限,命中率最终将达到 100%,因为所有键都可以存储在内存中。或者,如果您指定了太多的键而没有最大内存限制,最终所有计算机的 RAM 都会被用完。还需要配置适当的*maxmemory 策略*,大多数情况下您想要的是 `allkeys-lru`。

在下面的例子中,我配置了一个 100MB 的内存限制,并使用 1000 万个键进行 LRU 模拟。

警告:该测试使用流水线技术,会给服务器带来压力,请勿在生产实例上使用。

$ ./keydb-cli --lru-test 10000000
156000 Gets/sec | 命中: 4552 (2.92%) | 未命中: 151448 (97.08%)
153750 Gets/sec | 命中: 12906 (8.39%) | 未命中: 140844 (91.61%)
159250 Gets/sec | 命中: 21811 (13.70%) | 未命中: 137439 (86.30%)
151000 Gets/sec | 命中: 27615 (18.29%) | 未命中: 123385 (81.71%)
145000 Gets/sec | 命中: 32791 (22.61%) | 未命中: 112209 (77.39%)
157750 Gets/sec | 命中: 42178 (26.74%) | 未命中: 115572 (73.26%)
154500 Gets/sec | 命中: 47418 (30.69%) | 未命中: 107082 (69.31%)
151250 Gets/sec | 命中: 51636 (34.14%) | 未命中: 99614 (65.86%)

程序每秒显示统计数据。如你所见,在最初几秒钟,缓存开始被填充。未命中率随后会稳定在我们可以长期预期的实际数字上。

120750 Gets/sec | 命中: 48774 (40.39%) | 未命中: 71976 (59.61%)
122500 Gets/sec | 命中: 49052 (40.04%) | 未命中: 73448 (59.96%)
127000 Gets/sec | 命中: 50870 (40.06%) | 未命中: 76130 (59.94%)
124250 Gets/sec | 命中: 50147 (40.36%) | 未命中: 74103 (59.64%)

59% 的未命中率对于我们的用例来说可能无法接受。所以我们知道 100MB 的内存是不够的。让我们试试半千兆字节。几分钟后,我们会看到输出稳定到以下数字:

140000 Gets/sec | 命中: 135376 (96.70%) | 未命中: 4624 (3.30%)
141250 Gets/sec | 命中: 136523 (96.65%) | 未命中: 4727 (3.35%)
140250 Gets/sec | 命中: 135457 (96.58%) | 未命中: 4793 (3.42%)
140500 Gets/sec | 命中: 135947 (96.76%) | 未命中: 4553 (3.24%)

因此,我们知道对于我们的键数量(1000 万)和分布(80-20 风格),500MB 的内存是足够好的。