redis cli的特殊用法

redis cli的特殊用法包括下面这些:

1. 查看一个redis server的运行状态,可以用在监控报警上。

2. 扫描redis数据中的very large keys

3. 带有模式匹配的键空间扫描

4. 作为订阅频道的pub/sub客户端

5. 监控在redis实例上执行的命令

6. 检查redis server的延迟

7. 检查机器的调度延迟

8. 获取远端redis server的rdb backup,并保存到本地

9. 作为redis server的一个slave,查看一个slave收到了哪些消息

10. 模拟LRU负载,查看keys的命中率

 

1. 连续状态模式

可以用来实时监控redis server实例的运行状态。用法如下:

$ redis-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

在这种模式下,每秒会打印出redis server的状态信息,以及两次打印的差值(在括号中)。但是差值信息,并不是一定准确,我测试的时候,有过如下的打印:

------- data ------ --------------------- load -------------------- - child -
keys       mem      clients blocked requests            connections
3          562.48K  1       0       0 (+0)              1
3          562.48K  1       0       1 (+0)              1
3          562.48K  1       0       2 (+1)              1
3          562.48K  1       0       3 (+1)              1
3          562.48K  1       0       4 (+1)              1
3          562.48K  1       0       5 (+1)              1
3          562.48K  1       0       6 (+1)              1
3          562.48K  1       0       7 (+1)              1
3          562.48K  1       0       8 (+1)              1
3          562.48K  1       0       9 (+1)              1

其中第二行信息的差值信息存在错误。这个算是细枝末节的东西,只是在这里说明一下。通过--stat,你可以很容易知道redis server的内存使用状态,客户连接数,每秒请求个数等信息。通过-i <interval>选择,你可以改变打印的频率。默认情况下是1秒打印一次。

 

2. 扫描 big keys

在这种模式下,redis-cli作为键空间的分析器。redis cli扫描数据中的big keys,同时也会给出数据中的类型信息。用法如下:

$ redis-cli --bigkeys

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest string found so far 'key-419' with 3 bytes
[05.14%] Biggest list   found so far 'mylist' with 100004 items
[35.77%] Biggest string found so far 'counter:__rand_int__' with 6 bytes
[73.91%] Biggest hash   found so far 'myobject' with 3 fields

-------- summary -------

Sampled 506 keys in the keyspace!
Total key length in bytes is 3452 (avg len 6.82)

Biggest string found 'counter:__rand_int__' has 6 bytes
Biggest   list found 'mylist' has 100004 items
Biggest   hash found 'myobject' has 3 fields

504 strings with 1403 bytes (99.60% of keys, avg size 2.78)
1 lists with 100004 items (00.20% of keys, avg size 100004.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
1 hashs with 3 fields (00.20% of keys, avg size 3.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

在第一部分的输出中,同一个类型中,每个新的更加大的key会被打印出来。总结部分会给出redis实例一般的状态信息。输出信息通过scan命令获取。

 

3. 获取keys的列表

通过redis cli可以在不阻塞redis server的情况下,获取键的列表,打印出所有,或者通过特定模式过滤,只打印出符合过滤模式的键。获取键列表,也是通过SCAN命令,所以返回的键的保证和直接使用SCAN命令一致。感觉这个就只是SCAN命令的简单封装,没有特别的地方。用法如下:

$ redis-cli --scan | head -10
key-419
key-71
key-236
key-50
key-38
key-458
key-453
key-499
key-446
key-371
$ redis-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
$ redis-cli --scan --pattern 'user:*' | wc -l
3829433

 

4. Pub/sub模式

redis cli可以使用publish命令将消息发布到redis的pub/sub频道。订阅消息和发布消息有所不同,因为订阅消息需要阻塞等待消息的到达。订阅消息的用法如下:

$ redis-cli psubscribe '*'
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1

上面的打印中的“Reading messages"表示redis cli进入订阅模式。其中的"*"表示订阅任何频道,如果这时候一个client在一个channel中发布消息,例如:

redis-cli PUBLISH mychannel mymessage,

上面订阅的redis cli会打印如下信息:

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

这个对于调试pub/sub的问题很有用处。

 

5. 监控redis中执行的命令

这个命令的用法如下,进入监控模式,这个redis cli就会打印被监控的redis server收到的所有命令。

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

这个功能,同样对于调试很有用处。当你进行一个修改redis中的key的操作,发现没有按照你预料的情况变化时,这时候,你就可以使用redis的monitor模式。查看

(1)这个redis server是否收到你的修改请求

(2)这个redis server收到的修改请求是否正确

(3)这个redis server有没有收到你的查询请求

(4)这个redis server收到的查询请求是否正确

这样,你调试redis的使用就会很方便。

 

6. 监控redis实例的延迟

redis作为内存数据库,经常被用在延迟要求很高的场景,有很多因素会影响延迟,包括应用中的处理,从redis client库的网络调用,以及redis自身的延迟。

redis cli提供了很多选项用来了解一个redis实例的延迟,包括最大值,平均值和分布。有一点需要注意,这个命令可以用来查看一个远端的redis server的延迟信息,但是需要确保,本地的redis cli连接redis server可以正常发送命令,例如可以使用一个get命令,查看redis server能够给出正确的结果。

我曾经试过,对于一个远端的redis server注释了bind 127.0.0.1,这种情况下,redis cli可以连接到远端的redis server,但是不能正常执行命令。你还需要将protected-mode改为no,这样才可以正常测试延迟。这里只是用来说明latency的用法,不涉及安全问题,对于redis的安全问题,在部署上线的时候,需要认真考虑。

用来检测延迟的基本工具是--latency选项。使用这个选项,redis-cli会启动一个循环,然后记录从发送一个ping给redis server,到收到redis server响应的延迟。状态会实时显示在界面上。

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

状态信息的时间单位是毫秒。由于redis-cli的系统调度等原因,给出的值可能偏大,但是,对于要求为毫秒的应用来说,这个值已经足够精确。

有时候,我们想知道随着时间变化,延迟的变化,就可以使用--latency-history。这个选项每15秒启动一个新的测量:

$ redis-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>将15s改成其他的值。

 还有一个用于展示延迟的选项,叫做--latency-dist,可以用来展示延迟分布,比较复杂,在需要的时候,可以自己多了解。

7. 机器的调度延迟

redis-cli还可以用来测试机器的调度延迟,这个有点类似于sysbench对于mysql的用处。这个延迟,受限于底层运行的内核调度,虚拟机的管理程序等。

我们称呼这个为内在延迟,因为这个是对编程人员不可见的。如果你的redis实例延迟很高,除了其他那些明显的问题之外,你可以测试一下这个内在延迟,知道这个延迟,你就知道redis实例在这台机器上运行时,最好的可能延迟情况(当然,实际上一般达不到)。通过使用 --intrinsic-latency <test-time> 参数,测试时间单位为秒。

$ ./redis-cli --intrinsic-latency 5
Max latency so far: 1 microseconds.
Max latency so far: 7 microseconds.
Max latency so far: 9 microseconds.
Max latency so far: 11 microseconds.
Max latency so far: 13 microseconds.
Max latency so far: 15 microseconds.
Max latency so far: 34 microseconds.
Max latency so far: 82 microseconds.
Max latency so far: 586 microseconds.
Max latency so far: 739 microseconds.

65433042 total runs (avg latency: 0.0764 microseconds / 764.14 nanoseconds per run).
Worst run took 9671x longer than the average latency.

注:这个命令不依赖于redis server,需要把redis cli运行在需要测试的机器上。

在上面那个例子中,在极端情况下,系统内在延迟可达739 microseconds,可以预见,会时不时出现redis的命令执行时间接近1 millisecond。

7.1 redis的吞吐量

这是与redis的延迟相关的一个变量,对于同步调用redis命令的程序来说,受限于两个因素,一个是延迟,延迟决定着单个redis同步调用线程的最大qps,另外一个影响因素是redis server的吞吐量。这个可以使用redis-benchmark来查看。具体参考:

https://redis.io/topics/benchmarks

 

8. 获取远端redis server的rdb backup,并保存到本地

在redis server复制的开始同步阶段,主节点和从节点,通过rdb文件格式进行整个数据的同步。redis-cli实现了类似的功能,可以从远端的redis server获取rdb文件。用法如下:

$ redis-cli --rdb /tmp/dump.rdb
SYNC sent to master, writing 13256 bytes to '/tmp/dump.rdb'
Transfer finished with success.

调用完命令之后,本机的/tmp目录中就会有一个dump.rdb文件。这个是一个简单的周期性备份的方式,类似于mysqldump的功能。使用脚本或者周期任务执行这个功能时,要注意检查一下返回值,像下面这样的,表示获取rdb失败。

$ redis-cli --rdb /tmp/dump.rdb
SYNC with master failed: -ERR Can't SYNC while not connected with my master
$ echo $?
1

 

9. 作为redis server的一个slave,查看一个slave收到了哪些消息(从节点模式)

从节点模式,是redis cli的一个高级特性,对于redis开发者以及调试会很有帮助。通过从节点模式,可以查看在复制过程中,主节点发送给从节点的命令。使用方法如下:

$ redis-cli --slave
SYNC with master, discarding 13256 bytes of bulk transfer...
SYNC done. Logging commands from master.
"PING"
"SELECT","0"
"set","foo","bar"
"PING"
"incr","mycounter"

这个命令,首先会丢掉第一个同步阶段的rdb文件,然后以csv格式,记下每一个收到的命令。

 

10. 模拟LRU负载,查看keys的命中率

 redis经常作为lru (least recently used) 清理的缓存。取决于keys的数量,以及cache可以使用的内存大小(通过maxmemory命令设定),cache的命中率会产生变化。有时候,通过查看命中率和内存的关系,可以更好的设置内存的大小。

redis cli有一个特殊的模式,可以用80-20%的调用分布,来模式GET和SET操作的场景,在这种常见场景中,在80%的时间,只会使用20%的keys。

从理论上说,给定redis的内存容量,给定调用分布,可以从理论上计算出命中率。但是,redis有不同的lru设置,以及不同的lru实现,这会导致不同版本和不同设置的redis的命中率有所改变。另外,每个key在不同的redis版本的内存占用,也可能发生改变,这个也会影响命中率。通过使用这个工具,就可以真实测试一个指定版本和指定配置的redis的命中率。

为了使用这个模式,你需要指定keys的数量,你还需要设置作为第一次测试合适的maxmemory.

注:maxmemory的设置是必需的,如果没有设置设置,所有的key最终都会缓存到redis server的内存中,命中率最终会达到100%. 如果你使用了太多的keys,但是又没有设置maximum memory,那redis server所在机器的所有内存都会被占用。同时,还需要设置一个合适的maxmemory policy,例如 allkeys-lru,这个取决于你实际场景的需要。

下面这个测试中,我们配置了maxmemory为100M,keys总数为1000万。

注:这个操作对redis server影响较大,不要对正在给客户服务的redis server进行这个测试。

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

redis cli每秒打印一下当前状态。可以看出,在开始的阶段,keys不断被缓存,到后面命中率不断稳定。

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

59%的失败命中率,对我们来说是不可接受的。我们觉得100M的内存太小了,所以将maxmemory改为了0.5GB,经过几分钟后,可以看到如下稳定的命中率数据:

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

所以,我们知道,对于80-20分布,1000万条数据,500M的内存可以提供足够高的命中率。对于这种情况,也可以查看如果想要达到100%命中率,需要多少内存,来判断那种方式更加合算。

 

上述内容主要是对redis官方文档的一个简单翻译,添加了一些自己的说明,如果有兴趣可以查看官方文档:

https://redis.io/topics/rediscli

posted on 2021-01-17 18:43  月落无影  阅读(752)  评论(0编辑  收藏  举报