标题:【Redis10】Redis基础:客户端操作
Redis基础学习:客户端操作
今天我们学习的内容是一些普通的客户端操作,这些内容有的可能你天天都会用到,而有的可能根本都没听说过。好吧,说得就是我,没有系统的学习之前真的很多命令都不清楚,甚至完全就是不知道的状态。当然,无知者无畏,这个无畏就是要面对学习无所畏惧。
一般操作
AUTH
想必 AUTH 这个命令应该是大家比较常用的,我之前是吃过这个亏的。怎么说呢?就是在安全性方面,开放了端口,同时也没有设置密码,结果导致被大佬们从 Redis 入侵了,整了个挖矿的程序,天天把 CPU 跑满.....
好吧,往事不提了,安全使用 Redis 肯定是要绑定好 IP ,并且设置好密码的。设置密码就直接在配置文件中进行设置就好了。
requirepass aabbcc
然后我们在客户端连接中就可以通过 AUTH 命令来验证密码并登录。
127.0.0.1:6379> auth aa
(error) WRONGPASS invalid username-password pair or user is disabled.
127.0.0.1:6379> auth aabbcc
OK
ECHO
这个命令没啥说的,就是你输入什么,它给你输出什么,就是个打印工具。
127.0.0.1:6379> ECHO Hello
"Hello"
HELLO
这个命令的名字有点诡异吧,HELLO?你好?打招呼?
它呀,是 Redis6.0 新出的一个命令。其实对应的就是我们可以设置不同的 Redis 通信协议,在 6.0 版本之后,Redis 支持了 RESP3 这种协议,它的输出格式和我们之前的有点不一样。之前和大部分情况下其实我们使用的是 RESP2 这种协议。RESP3 的格式更加语义化,但是,默认情况下,即使是最新的 Redis7 ,默认也仍然是 RESP2 协议。毕竟协议切换是最麻烦的事,大家的系统框架以及客户端工具大部分还是只支持 RESP2 格式的。
说了半天还是看实际例子,这个命令不加参数的话,返回的是当前的协议格式。
127.0.0.1:6379> HELLO
1) "server"
2) "redis"
3) "version"
4) "6.2.6"
5) "proto"
6) (integer) 2
7) "id"
8) (integer) 3
9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
127.0.0.1:6379> hset a K1 111 K2 222
(integer) 2
127.0.0.1:6379> HGETALL a
1) "K1"
2) "111"
3) "K2"
4) "222"
它会打印当前的 server、version、proto、id(客户端id)、mode、role、modules 等信息。注意,格式体现在我们返回数据的形式,比如默认情况下 Hash 结构返回的数据是一行 key ,一行 value。
那么接下来我们就将它换成 RESP3 的格式看看,直接在 HELLO 后面加上版本号就行了。
127.0.0.1:6379> HELLO 3
1# "server" => "redis"
2# "version" => "6.2.6"
3# "proto" => (integer) 3
4# "id" => (integer) 3
5# "mode" => "standalone"
6# "role" => "master"
7# "modules" => (empty array)
127.0.0.1:6379> HGETALL a
1# "K1" => "111"
2# "K2" => "222"
看出来不同了吧。是不是像我们在 PHP 中定义数组的那种 k/v 数据的感觉。因此,RESP3 的数据可读性更好,是更加语义化的格式。另外注意到,proto 这个数据也变成 3 了,它就是 RESP 版本的标识。
SELECT
这个命令想必也是不少同学会经常使用的一个命令。我们都知道,一个 Redis 实例会默认有 16 个库,正常情况下我们连接上来都是走的 0 库,库与库之间的数据不是在一起(但实际存储还是在一起,相当于系统提供了一个 Scheme)。使用 SELECT 命令就是用于切换当前使用的库的。
想要修改默认库的数量,看下 redis.conf 中的 databases 属性吧~!
这个命令比较简单,大家应该也都用过。
127.0.0.1:6379[10]> select 15
OK
127.0.0.1:6379[15]> select 16
(error) ERR DB index is out of range
127.0.0.1:6379[15]> HGETALL a
(empty array)
127.0.0.1:6379[15]> select 0
OK
127.0.0.1:6379> HGETALL a
1) "K1"
2) "111"
3) "K2"
4) "222"
RESET
RESET 这个命令从名字就能看出,是重置的意思。重置啥呢?就是我们的客户端连接信息。在官方文档中有一个说明:
丢弃当前多事务块(如果存在)
取消监听
禁用客户端跟踪
将连接设置为读写模式
取消连接的 ACK 模式
设置客户端回复为已打开
设置协议版本为 RESP2
选择数据库 0
退出监控模式
在适当时候中止 Pub/Sub 状态
取消 AUTH 验证
看出来没,感觉就像是我们重新连接一次客户端了。那么我们就拿上面的 HELLO 来作为例子,看看 RESET 的效果。
127.0.0.1:6379> hello 3
1# "server" => "redis"
2# "version" => "6.2.6"
3# "proto" => (integer) 3
4# "id" => (integer) 5
5# "mode" => "standalone"
6# "role" => "master"
7# "modules" => (empty array)
127.0.0.1:6379> hello
1# "server" => "redis"
2# "version" => "6.2.6"
3# "proto" => (integer) 3
4# "id" => (integer) 5
5# "mode" => "standalone"
6# "role" => "master"
7# "modules" => (empty array)
127.0.0.1:6379> reset
RESET
127.0.0.1:6379> hello
1) "server"
2) "redis"
3) "version"
4) "6.2.6"
5) "proto"
6) (integer) 2
7) "id"
8) (integer) 5
9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
首先我们将当前的协议设置为 RESP3 ,然后 RESET 一下,再查看 HELLO 就会发现又回到 RESP2 了。其它的重置项你也可以自己试试哦,比如说 SELECT 到别的库,然后 RESET 一下又会回到 0 库。
QUIT
退出连接,这个没啥多说的,不过我经常用的是 EXIT ,为啥呢?因为 MySQL 也是用这个命令退出呀,好记点,哈哈哈哈。
127.0.0.1:6379> quit
➜ ~
PING
这个命令就是用来测试服务器连通情况的。比如直接 PING 一下,返回一个 PONG 。如果给一个参数的话,则是原样打印这个字符内容。
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> PING hello
hello
CLIENT
CLIENT 是一套客户端命令,也就是说它是由多个二级命令组成的,具体的内容包括下面这些。
127.0.0.1:6379> CLIENT HELP
1) CLIENT <subcommand> [<arg> [value] [opt] ...]. Subcommands are:
2) CACHING (YES|NO)
3) Enable/disable tracking of the keys for next command in OPTIN/OPTOUT modes.
4) GETREDIR
5) Return the client ID we are redirecting to when tracking is enabled.
6) GETNAME
7) Return the name of the current connection.
8) ID
9) Return the ID of the current connection.
10) INFO
11) Return information about the current client connection.
12) KILL <ip:port>
13) Kill connection made from <ip:port>.
14) KILL <option> <value> [<option> <value> [...]]
15) Kill connections. Options are:
16) * ADDR (<ip:port>|<unixsocket>:0)
17) Kill connections made from the specified address
18) * LADDR (<ip:port>|<unixsocket>:0)
19) Kill connections made to specified local address
20) * TYPE (normal|master|replica|pubsub)
21) Kill connections by type.
22) * USER <username>
23) Kill connections authenticated by <username>.
24) * SKIPME (YES|NO)
25) Skip killing current connection (default: yes).
26) LIST [options ...]
27) Return information about client connections. Options:
28) * TYPE (NORMAL|MASTER|REPLICA|PUBSUB)
29) Return clients of specified type.
30) UNPAUSE
31) Stop the current client pause, resuming traffic.
32) PAUSE <timeout> [WRITE|ALL]
33) Suspend all, or just write, clients for <timout> milliseconds.
34) REPLY (ON|OFF|SKIP)
35) Control the replies sent to the current connection.
36) SETNAME <name>
37) Assign the name <name> to the current connection.
38) UNBLOCK <clientid> [TIMEOUT|ERROR]
39) Unblock the specified blocked client.
40) TRACKING (ON|OFF) [REDIRECT <id>] [BCAST] [PREFIX <prefix> [...]]
41) [OPTIN] [OPTOUT]
42) Control server assisted client side caching.
43) TRACKINGINFO
44) Report tracking status for the current connection.
45) HELP
46) Prints this help.
非常多吧,我们就挑一部分来学习一下吧。
CLIENT ID
这个返回的就是客户端的 ID ,可以想像成是 Socket 连接时获取的那个 fd 。
// 客户端1
127.0.0.1:6379> CLIENT ID
(integer) 5
// 客户端2
127.0.0.1:6379> CLIENT ID
(integer) 6
需要注意的一点是,这个 ID 是在服务端程序运行之后,就一直递增的。
// 客户端2
127.0.0.1:6379> exit
➜ ~ redis-cli
127.0.0.1:6379> CLIENT ID
(integer) 7
解除阻塞
有了客户端的 ID 之后,我们可以做些什么呢?比如解除某一个客户端的阻塞。
// 客户端1
127.0.0.1:6379> CLIENT ID
(integer) 10
127.0.0.1:6379> brpop aa 0
// 客户端2
127.0.0.1:6379> CLIENT UNBLOCK 10
(integer) 1
// 客户端1
(nil)
(4.13s)
在客户端1,我们使用 BRPOP 阻塞读取队列中的数据,然后使用 CLIENT UNBLOCK 命令,指定客户端1的 CLIENT ID 就可以解除它的阻塞。
设置连接名
除了客户端 ID 之外,我们还可以给客户端设置一个 名称 。
127.0.0.1:6379> CLIENT SETNAME lianjie1
OK
127.0.0.1:6379> CLIENT GETNAME
"lianjie1"
连接信息查看
又有 ID ,又有名称,那么能不能查看一个客户端连接的具体信息呢?当然可以,使用 CLIENT LIST 可以查看全部连接过来的客户端信息。
127.0.0.1:6379> CLIENT LIST
id=8 addr=127.0.0.1:54537 laddr=127.0.0.1:6379 fd=8 name=lianjie1 age=253 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=45024 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=62490 events=r cmd=client user=default redir=-1
id=10 addr=127.0.0.1:54548 laddr=127.0.0.1:6379 fd=9 name= age=163 idle=136 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=0 omem=0 tot-mem=17456 events=r cmd=brpop user=default redir=-1
这些信息是一行一行的键值对,其中就能发现 id 、name 这些上面已经学习过的内容,其它比较有用的还有 addr、db、cmd 等信息,分别代表的是 连接地址+端口、当前正在操作的库、上一条执行过的命令等。其中 qbuf 很大,但 qbuf-free 很小,则要小心缓冲区溢出的问题(通常是短时间内添加几百万数据的大 Key ,或者大量命令涌入)。剩下的字段大家可以去官方文档查阅一下是什么意思哦。
除了列表返回所有的,还可以返回当前的这一个连接的信息。
127.0.0.1:6379> CLIENT INFO
id=8 addr=127.0.0.1:54537 laddr=127.0.0.1:6379 fd=8 name=lianjie1 age=415 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=45024 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=62490 events=r cmd=client user=default redir=-1
暂停连接操作
这个功能有点像是上锁,文档中也说了,像是主从同步的时候,可以使用 CLIENT PAUSE 暂停操作,然后待从库同步完成后再打开。
127.0.0.1:6379> CLIENT PAUSE 20000 WRITE
OK
127.0.0.1:6379> set b 111
// 阻塞
OK
(14.87s)
最后的 WRITE 操作就像是写锁,当然也可以设置成 ALL 表示所有操作都暂停。
KILL
最后就是 KILL 操作啦,直接 KILL 掉另一个客户端的连接就可以使用这个 CLIENT KILL ID xxx 命令。除了使用 ID 之外 ,还有很多别的方式,比如根据 ADDR 之类的,大家可以自己尝试下哦。
// CLIENT ID 8
127.0.0.1:6379> CLIENT KILL ID 10
(integer) 1
// CLIENT ID 10
127.0.0.1:6379> client id
Error: Server closed the connection
总结
好了,知识面是不是感觉又扩展了?反正我是感觉又学习到了不少新东西。当然,这些命令其实对于运维更有用,毕竟我们也不会闲着没事在业务代码客户端中去强制 KILL 掉别的客户端,往往是因为出现了某些问题可能才会从命令行登录上来去进行一些查询及操作。
接下来,我们再学习服务端相关的一些命令操作。
视频链接
微信文章地址:https://mp.weixin.qq.com/s/TEjwPuP3tPYwOprkg7FcPQ