自2.4.0可用。git
时间复杂度:O(N) N是客户端链接数量。redis
Redis CLIENT LIST
命令用于返回全部链接到服务器的客户端信息和统计数据。shell
一个独特的字符串,格式以下:数据库
每一个已链接客户端对应一行(以 LF 分割)express
每行字符串由一系列 属性=值(property=value
) 形式的域组成,每一个域之间以空格分开。segmentfault
下面是各字段的含义:windows
客户端标识api
CLIENT LIST
命令中相关字段:数组
id
: 惟一的64位的客户端1ID(Redis 2.8.12加入)。缓存
addr
: 客户端的地址和端口
fd
: 套接字所使用的文件描述符
name
:客户端的名字,后面的 CLIENT SETNAME
和 CLIENT GETNAME
两个命令会对其进行说明。
输入缓冲区
Redis 为每一个客户端分配有输入缓存区,用于将客户端发送的命令临时保存。Redis 会从缓存区中拉取命令并执行。输入缓冲区会根据输入内容大小的不一样动态调整,只是要求每一个客户端缓冲区的大小不能超过 1G ,超事后客户端将被关闭。
输入缓冲区不受 maxmemory
控制,假设一个 Redis 实例设置了 maxmemory
为4G,已经存储了2G数据,可是若是此时输入缓冲区使用了 3G,已经超过 maxmemory
限制,可能会产生数据丢失、键值淘汰、Out Of Memory 等状况。这种状况在正常使用过程当中出现较少,可是须要注意防范 Redis 使用不规范致使出现这种状况
形成缓冲区过大的缘由是 输入命令过多,Redis 没法及时处理,可能的状况:
a) 客户端过多,命令输入过多。
b) 因为命令使用的不恰当(key过大,或运行时间复杂度较高的命令)等缘由形成 Redis 阻塞没法处理新的命令,从而致使客户端输入的命令积压在输入缓冲区,形成了输入缓冲区过大。
监控输入缓冲区异常的方法有两种:
a) 经过按期执行 `CLIENT LIST` 命令,收集 `qbuf` 和 `qbuf-free` 找到异常的链接记录并分析,最终找到可能出问题的客户端。该方法能够精准的监控每一个客户端,但执行较慢,在链接数较多时可能会阻塞 Redis。 b) 经过 `INFO CLIENTS` 命令,找到最大的输入缓冲区(`client_biggest_input_buf`),该命令相较于 `CLIENT LIST` 执行较快,结果一目了然,但没法精准到具体客户端,没法查看缓存区大小等信息。
CLIENT LIST
命令中相关字段:
qbuf
: 查询缓冲区的总容量(字节为单位, 0 表示没有分配查询缓冲区)
qbuf-free
: 查询缓冲区剩余容量(字节为单位, 0 表示没有剩余空间)
输出缓冲区
Redis为每一个客户端分配了输出缓冲区,它的做用是保存命令执行的结果返回给客户端,为Redis和客户端交互返回结果提供缓冲。与输入缓冲区不一样的是,输出缓冲区的容量能够经过参数 client-outputbuffer-limit
来进行设置,而且输出缓冲区作得更加细致,按照客户端的不一样分为三种:普通客户端、发布订阅客户端、slave客户端,不一样类型的客户端的输出缓冲区不一样能够分别进行设置。
在 Redis 配置文件中能够配置:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
其中:
<class>
:客户端类型,分为三种。
a)normal:普通客户端;
b)slave:slave客户端,用于复制;
c)pubsub:发布订阅客户端。
<hard limit>
:若是客户端使用的输出缓冲区大于<hard limit>
,客户端会被当即关闭。
<soft limit>
和 <soft seconds>
:若是客户端使用的输出缓冲区超过了 <soft limit>
而且持续了 <soft limit>
秒,客户端会被当即关闭。
Redis 中对应的默认配置:
client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60
输出缓冲区一样存在内存溢出的问题。(见 输入缓冲区相关内容)
输出缓冲区由两部分组成:响应缓冲区(16KB)和回复列表,其中响应缓冲区返回比较小的执行结果,而回复列表返回比较大的结果,例如大的字符串、HGEtALL
、SMEMBERS
命令的结果等。
响应缓冲区使用的是字节数组,回复列表使用的是列表。当响应缓冲区存满后会将 Redis 新的返回结果存放在回复列表的队列中,队列中的每一个对象就是每一个返回结果。
监控输出缓冲区异常的方法有两种:
a) 经过按期执行 `CLIENT LIST` 命令,收集 `obl`、`oll` 和 `omem` 找到异常的链接记录并分析,最终找到可能出问题的客户端。该方法能够精准的监控每一个客户端,但执行较慢,在链接数较多时可能会阻塞 Redis。 b) 经过 `INFO CLIENTS` 命令,找到最大的回复列表(`client_longest_output_list`),该命令相较于 `CLIENT LIST` 执行较快,结果一目了然,但没法精准到具体客户端,没法查看缓存区大小等信息。
相比于输入缓冲区,输出缓冲区出现异常的几率相对会比较大,预防出现问题的方法:
经过上面两中方法进行监控,设置阈值,超阈值后及时处理。
显示普通客户端的输出缓存区:
client-output-buffer-limit normal 20mb 10mb 120
适当增大 slave 的输出缓冲区的,若是 master 节点写入较大,slave 客户端的输出缓冲区可能会比较大,一旦 slave 客户端链接由于输出缓冲区溢出被 kill ,会形成复制重连。
限制容易让输出缓冲区增大的命令,例如,高并发下的 MONITOR
命令就是一个危险的命令。
及时监控内存,一旦发现内存抖动频繁,可能就是输出缓冲区过大。
CLIENT LIST
命令中相关字段:
obl
: 输出缓冲区的长度(字节为单位, 0 表示没有分配输出缓冲区)
oll
: 输出列表包含的对象数量(当输出缓冲区没有剩余空间时,命令回复会以字符串对象的形式被入队到这个队列里)
omem
: 输出缓冲区和输出列表占用的内存总量
客户端的存活状态
age
: 以秒计算的已链接时长
idle
: 最近一次(100ms 或者更长时间)以秒计算的空闲时长
客户端类型
flags
: 客户端 flag
客户端 flag 能够由如下部分组成:
O: 客户端是 MONITOR 模式下的附属节点(slave)
S: 客户端是通常模式下(normal)的附属节点
M: 客户端是主节点(master)
x: 客户端正在执行事务
b: 客户端正在等待阻塞事件
i: 客户端正在等待 VM I/O 操做(已废弃)
d: 一个受监视(watched)的键已被修改, EXEC 命令将失败
c: 在将回复完整地写出以后,关闭连接
u: 客户端未被阻塞(unblocked)
U: 经过Unix套接字链接的客户端
r: 客户端是只读模式的集群节点
A: 尽量快地关闭链接
N: 未设置任何 flag,普通客户端
db
: 该客户端正在使用的数据库 ID
sub
: 已订阅频道的数量
psub
: 已订阅模式的数量
multi
: 在事务中被执行的命令数量
events
: 文件描述符事件
cmd
: 最近一次执行的命令
文件描述符事件能够是:
r: 客户端套接字(在事件 loop 中)是可读的(readable)
w: 客户端套接字(在事件 loop 中)是可写的(writeable)
为了 debug 的须要,常常会对域进行添加和删除。一个版本安全的 Redis 客户端使用这个命令时应该根据字段解析相应内容。(好比:处理未知的字段,应跳过该字段)。
coderknock> CLIENT LIST # 链接时间 87 秒 空闲 87 秒 说明该链接一直处于空闲状态 id=3 addr=127.0.0.1:55773 fd=8 name= age=87 idle=87 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=command id=4 addr=127.0.0.1:55795 fd=7 name= age=58 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client #响应缓冲区的长度为0,回复列表有4869个对象,两个部分共使用了133081288字节=126M id=7 addr=127.0.0.1:56358 fd=6 name= age=91 idle=0 flags=O db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=4869 omem=133081288 events=rw cmd=monitor
自2.6.9可用。
时间复杂度:O(1)。
CLIENT GETNAME
返回当前链接由CLIENT SETNAME
设置的名字。若是没有用CLIENT SETNAME
设置名字,将返回一个空的回复。
返回链接名字或者空(没有设置名字时)
coderknock> CLIENT GETNAME (nil) # 只针对当前客户端 coderknock> CLIENT SETNAME coderknock OK coderknock> CLIENT GETNAME "coderknock"
自2.6.9可用。
时间复杂度:O(1)。
为当前链接分配一个名字。
这个名字会显示在 CLIENT LIST
命令的结果中, 用于识别当前正在与服务器进行链接的客户端。
举个例子, 在使用 Redis 构建队列(queue)时, 能够根据链接负责的任务(role), 为信息生产者(producer)和信息消费者(consumer)分别设置不一样的名字。
名字使用 Redis 的字符串类型来保存, 最大能够占用 512 MB 。 另外, 为了不和 CLIENT LIST
命令的输出格式发生冲突, 名字里不容许使用空格。
要移除一个链接的名字, 能够将链接的名字设为空字符串 ""
。
使用 CLIENT GETNAME
命令能够取出链接的名字。
新建立的链接默认是没有名字的。
在 Redis 应用程序发生链接泄漏时,为链接设置名字是一种很好的 debug 手段。
设置成功时返回 OK
。
# 新链接默认没有名字 coderknock> CLIENT GETNAME (nil) # 设置名字 coderknock> CLIENT SETNAME coderknock OK # 返回名字 coderknock> CLIENT GETNAME "coderknock" # 在客户端列表中查看 coderknock> CLIENT LIST id=5 addr=127.0.0.1:49298 fd=8 name=coderknock age=173 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client # 清除名字 coderknock> CLIENT SETNAME # 只用空格是不行的! (error) ERR Syntax error, try CLIENT (LIST | KILL ip:port) coderknock> CLIENT SETNAME "" # 必须双引号显示包围 OK coderknock> CLIENT GETNAME (nil) coderknock> CLIENT LIST id=5 addr=127.0.0.1:49298 fd=8 name= age=203 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client #别的客户端一样能够取名为 coderknock coderknock> CLIENT LIST id=6 addr=127.0.0.1:49438 fd=7 name=coderknock age=67 idle=32 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client id=7 addr=127.0.0.1:49454 fd=9 name=coderknock age=25 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
在 Redis 只有一个应用方使用的状况下,IP和端口做为标识会更加清晰。当多个应用方共同使用一个Redis,那么此时 CLIENT SETNAME
能够做为标识客户端的一个依据。
在以前的 《Redis 配置》一文中咱们讲过 CONFIG GET CONFIG_SETTING_NAME
、CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
,命令,其中CONFIG GET/SET maxclients
用于获取/设置客户端最大链接数,一旦链接数超过 maxclients 新的链接将被拒绝,maxclients 默认值是10000,能够经过 INFO clients
来查询当前Redis的链接数:
# 查询最大链接数 coderknock> CONFIG GET maxclients 1) "maxclients" 2) "10000" coderknock> INFO clients # Clients connected_clients:1 #当前链接客户端数 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0
能够经过 CONFIG SET maxclients
对最大客户端链接数进行动态设置:
# 咱们将 maxclients 设置小些 coderknock> CONFIG SET maxclients 2 OK coderknock> CONFIG GET maxclients 1) "maxclients" 2) "2" # 咱们启动再启动两个客户端此时在第一个或第二个客户端上执行 coderknock> CLIENT LIST id=2 addr=127.0.0.1:51010 fd=7 name= age=386 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client id=3 addr=127.0.0.1:51091 fd=8 name= age=154 idle=126 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=keys # 在第三个启动的客户端上进行操做(命令窗口并无关闭因此仍是能够执行的) coderknock> keys * Error: 远程主机强迫关闭了一个现有的链接。 # 能够看到这个客户端不能正常使用
通常状况下 maxclients 默认的 10000 大小已经作够使用了,可是有时因为使用不当可能致使存在大量空闲链接(idle 较大的链接),不管是从网络链接的成本仍是超过maxclients的后果来讲都不是什么好事,所以 Redis 提供了 timeout (单位为秒)参数限制链接的最大空闲时间,一旦客户端空闲时间超过了 timeout 设置,链接将会被关闭。使用 CONFIG GET/SET timeout
能够获取设置 timeout:
# #Redis默认的 timeout 是0,也就是没有超时时间 coderknock> CONFIG GET timeout 1) "timeout" 2) "0"
Redis的默认配置给出的 timeout=0 ,在这种状况下客户端基本不会出现上面的异常,这是基于对客户端开发的一种保护。若是客户端设置了超时,可能就会出现链接超时的异常,对应用业务形成必定影响,可是若是 Redis 的客户端使用不当或者客户端自己的一些问题,形成没有及时释放客户端链接,可能会形成大量的空闲链接占据着不少链接资源,一旦超过 maxclients;后果也是不堪设想。所在在实际开发和运维中,须要将 timeout 设置成大于0 且较大的数字,例如能够设置为300秒,同时在客户端使用上添加空闲检测和验证等等措施。
自2.4.0可用。
时间复杂度:O(N) N是客户端链接数量。
CLIENT KILL
关闭一个指定的链接。在 Redis2.8.11 时能够根据客户端地址关闭指定链接,关闭方式以下:
CLIENT KILL addr:port
addr:port
应该是 CLIENT LIST
命令里面列出的客户端链接之一。
然而,从Redis 2.8.12开始,这个命令改成以下格式:
CLIENT KILL <filter> <value> ... ... <filter> <value>
新的格式能够根据不一样属性杀死客户端而不是只按地址杀死。他们有如下一些格式:
CLIENT KILL ADDR ip:port
: 和旧版的三个参数时的行为彻底同样。
CLIENT KILL ID client-id
: 能够经过惟一 ID
字段杀死一个客户端,惟一 ID
能够经过 Redis 2.8.12 开始的 CLIENT LIST
命令查询(以前版本可能没有 ID
字段)。
CLIENT KILL TYPE type
: 这里的 type 能够是 normal
, slave
, pubsub
(Redis 3.2 版本以后增长了 master
类型的支持)。 这将关闭全部特殊类的客户端。 请注意被认为是属于正常类的客户端将会被MONITOR
命令监视到。
CLIENT KILL SKIPME yes/no
:默认状况下,该选项设置为yes
,即调用过该命令的客户端将不会被杀死,将该选项设置为 no
即也会杀死调用过该命令的客户端。
该命令支持同时使用多个过滤器,或杀死多个过滤器的合集。
因为Redis的单线程特性,在执行命令时没法终止客户端链接。从客户端的角度来看,在执行命令的过程当中,链接永远不会被关闭。可是,只有当下一个命令发送(并致使网络错误)时,客户端才会注意到链接已关闭。
当用三个参数格式调用时:
若是链接存在并已关闭返回OK
当使用过滤器/值格式调用时:
客户端数量被杀。
# 列出全部已链接客户端 coderknock> CLIENT LIST addr=127.0.0.1:43501 fd=5 age=10 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client # 杀死当前客户端的链接 coderknock> CLIENT KILL 127.0.0.1:43501 OK # 以前的链接已经被关闭,CLI 客户端又从新创建了链接 # 以前的端口是 43501 ,如今是 43504 coderknock> CLIENT LIST addr=127.0.0.1:43504 fd=5 age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
因为一些缘由(例如设置 timeout=0 时产生的长时间空闲的客户端),须要手动杀掉客户端链接时,可使用 CLIENT KILL
命令。
自2.9.5可用。
时间复杂度:O(1)。
CLIENT PAUSE
是一个链接控制命令,能够在指定的时间(以毫秒为单位)中挂起全部Redis客户端。
该命令执行如下操做:
只对普通和发布订阅客户端有效,对于主从复制(从节点内部假装了一个客户端)是无效的,也就是此期间主从复制是正常进行的,因此此命令能够用来让主从复制保持一致。
可是它尽量地返回给调用者,所以 CLIENT PAUSE
命令的执行不会自动暂停(返回以后仍是会暂停自身的客户端)。
当指定的时间量过去时,全部客户端都被解除阻塞:这将在暂停期间触发对每一个客户端的查询缓冲区中累积的全部命令的处理。
此命令很是有用,由于它能够用一种可控的方式将客户端链接从一个Redis节点切换到另外一个Redis节点。例如,在实例升级期间,系统管理员能够执行如下操做:
使用 CLIENT PAUSE
暂停客户 端
等待几秒钟以确保从站从主设备处理最新的复制流。
把一个从节点变成一个主节点。
从新配置客户端以链接新的主节点。
能够将命令 暂停
发送到 MULTI / EXEC 块 INFO replication
中,以便在客户端被阻止时获取当前的主节点偏移量。这样,能够在从属端等待特定的偏移量,以确保处理全部的复制流。
Redis 3.2.10 / 4.0.0 中此命令还能够防止在客户端暂停期间键被释放或过时。这样,数据集就被保证是静态的,而不只仅是从客户端没法写入的角度来看,并且从内部操做的角度来讲也是如此。
若是超时无效,则该命令返回OK或错误。
coderknock> CLIENT PAUSE 10000 OK coderknock> GET hello "world" (10.06s) # 这里能够看到查询花费 10s 的时间
该命令在生产环境如要使用应挑选操做较少时,否则可能会引起不可预知的状况。
自3.2.0可用。
时间复杂度:O(1)。
有时客户端能够彻底禁用Redis服务器的回复
CLIENT REPLY
命令控制服务器是否会回复客户端的命令。提供如下模式:
ON
。这是默认模式服务器返回每一个命令的回复。
OFF
。在此模式下,服务器将不会回复客户端命令。
SKIP
。此模式会当即跳过命令的回复。
当用 OFF
或 SKIP
命令调用时,不做任何回复。调用时ON
:返回OK
。
该命令是新命令目前兼容客户端较少
自1.0.0可用。
时间复杂度:不明确。
MONITOR
是一个调试命令,返回服务器处理的每个命令,它能帮助咱们了解在数据库上发生了什么操做,能够经过redis-cli和telnet命令使用.
$ redis-cli monitor 1339518083.107412 [0 127.0.0.1:60866] "keys" "*" 1339518087.877697 [0 127.0.0.1:60866] "dbsize" 1339518090.420270 [0 127.0.0.1:60866] "set" "x" "6" 1339518096.506257 [0 127.0.0.1:60866] "get" "x" 1339518099.363765 [0 127.0.0.1:60866] "del" "x" 1339518100.544926 [0 127.0.0.1:60866] "get" "x"
使用SIGINT (Ctrl-C)来中止 经过redis-cli使用 MONITOR
命令返回的输出.
$ telnet localhost 6379 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. MONITOR +OK +1339518083.107412 [0 127.0.0.1:60866] "keys" "*" +1339518087.877697 [0 127.0.0.1:60866] "dbsize" +1339518090.420270 [0 127.0.0.1:60866] "set" "x" "6" +1339518096.506257 [0 127.0.0.1:60866] "get" "x" +1339518099.363765 [0 127.0.0.1:60866] "del" "x" +1339518100.544926 [0 127.0.0.1:60866] "get" "x" QUIT +OK Connection closed by foreign host.
使用 QUIT
命令来中止经过telnet使用 MONITOR
返回的输出.
因为 MONITOR
命令返回 服务器处理的全部的 命令, 因此在性能上会有一些消耗.
在不运行 MONITOR
命令的状况下,benchmark的测试结果:
$ src/redis-benchmark -c 10 -n 100000 -q PING_INLINE: 101936.80 requests per second PING_BULK: 102880.66 requests per second SET: 95419.85 requests per second GET: 104275.29 requests per second INCR: 93283.58 requests per second
在运行 MONITOR
命令的状况下,benchmark的测试结果: (redis-cli monitor > /dev/null):
$ src/redis-benchmark -c 10 -n 100000 -q PING_INLINE: 58479.53 requests per second PING_BULK: 59136.61 requests per second SET: 41823.50 requests per second GET: 45330.91 requests per second INCR: 41771.09 requests per second
在这种特定的状况下,运行一个 MONITOR
命令可以下降50%的吞吐量,运行多个 MONITOR
命令 下降的吞吐量更多。
每一个客户端都有本身的输出缓冲区,既然 MONITOR
能监听到全部的命令,一旦 Redis 的并发量过大 MONITOR
客户端的输出缓冲会暴涨,可能瞬间会占用大量内存。
没有统一标准的返回值, 无限的返回服务器端处理的命令流.或 key
不存在,返回 0
。
# 方式一 C:\Users\zylia>redis-cli -a admin123 monitor OK 1498547986.670236 [0 127.0.0.1:63859] "AUTH" "admin123" 1498547986.670366 [0 127.0.0.1:63859] "GET" "hello" 1498548024.414979 [0 127.0.0.1:63869] "AUTH" "admin123" 1498548024.415185 [0 127.0.0.1:63869] "COMMAND" 1498548046.317448 [0 127.0.0.1:63872] "AUTH" "admin123" 1498548046.317742 [0 127.0.0.1:63872] "COMMAND" #方式二 登陆后在进行 coderknock> MONITOR OK 1498548046.317448 [0 127.0.0.1:63872] "AUTH" "admin123" 1498548046.317742 [0 127.0.0.1:63872] "COMMAND" #方式三 Telnet C:\Users\zylia>telnet 127.0.0.1 6379 auth admin123 +OK MONITOR +OK +1498548296.621530 [0 127.0.0.1:64068] "AUTH" "admin123" +1498548296.621658 [0 127.0.0.1:64068] "GET" "hello" # 支持同时开启多个 MONITOR
tcp-keepalive:检测TCP链接活性的周期,默认值为0,也就是不进行检测,若是须要设置,建议为60,那么Redis会每隔60秒对它建立的TCP链接进行活性检测,防止大量死链接占用系统资源。
tcp-backlog:TCP 三次握手后,会将接受的链接放入队列中,tcpbacklog就是队列的大小,它在 Redis 中的默认值是 511。一般来说这个参数不须要调整,可是这个参数会受到操做系统的影响,例如在Linux操做系统中,若是/proc/sys/net/core/somaxconn小于tcp-backlog,那么在Redis启动时会看到以下日志,并建议将/proc/sys/net/core/somaxconn设置更大。
WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/ sys/net/core/somaxconn is set to the lower value of 128.
修改方法也很是简单,只须要执行以下命令:
echo 511 > /proc/sys/net/core/somaxconn
咱们来看下 Redis 源码中客户端部分的内容:
typedef struct client { uint64_t id; /* Client incremental unique ID.客户端增量唯一的ID */ int fd; /* Client socket. 客户端套接字*/ redisDb *db; /* Pointer to currently SELECTed DB. 指向当前选择的DB的指针*/ robj *name; /* As set by CLIENT SETNAME. 由客户端 SETNAME命令设置*/ sds querybuf; /* Buffer we use to accumulate client queries. 用来累积客户端查询的缓冲区*/ sds pending_querybuf; /* If this is a master, this buffer represents the yet not applied replication stream that we are receiving from the master.若是这是一个主服务器 ,这个缓冲区表示咱们从主服务器接收到的未应用的复制流 */ size_t querybuf_peak; /* Recent (100ms or more) peak of querybuf size.最近(100ms 或者更长时间)querybuf 的峰值大小 */ int argc; /* Num of arguments of current command. 当前命令的参数个数*/ robj **argv; /* Arguments of current command. 当前命令的参数*/ struct redisCommand *cmd, *lastcmd; /* Last command executed. 最后一个被执行的命令*/ int reqtype; /* Request protocol type: PROTO_REQ_* 请求协议类型:PROTO_REQ_**/ int multibulklen; /* Number of multi bulk arguments left to read. 读取的多批量参数的数量*/ long bulklen; /* Length of bulk argument in multi bulk request. 多批量请求的批量参数的长度*/ list *reply; /* List of reply objects to send to the client.发送给客户端的应答对象列表(回复列表 有的翻译也叫动态缓冲区) */ unsigned long long reply_bytes; /* Tot bytes of objects in reply list. 对象个数(列表长度)*/ size_t sentlen; /* Amount of bytes already sent in the current buffer or object being sent. 在当前的缓冲区或对象已经发送的字节数*/ time_t ctime; /* Client creation time. 客户端建立时间*/ time_t lastinteraction; /* Time of the last interaction, used for timeout 最后一次交互的时间,用于超时 */ time_t obuf_soft_limit_reached_time; int flags; /* Client flags: CLIENT_* macros. 客户端标志使用的是 CLIENT_* 宏指令(下面会列出)*/ int authenticated; /* When requirepass is non-NULL. 当 requirepass 不是 null 时会为变量赋值*/ int replstate; /* Replication state if this is a slave. 复制状态若是这是一个从机*/ int repl_put_online_on_ack; /* Install slave write handler on ACK. */ int repldbfd; /* Replication DB file descriptor. */ off_t repldboff; /* Replication DB file offset. */ off_t repldbsize; /* Replication DB file size. */ sds replpreamble; /* Replication DB preamble. */ long long read_reploff; /* Read replication offset if this is a master. */ long long reploff; /* Applied replication offset if this is a master. */ long long repl_ack_off; /* Replication ack offset, if this is a slave. */ long long repl_ack_time;/* Replication ack time, if this is a slave. */ long long psync_initial_offset; /* FULLRESYNC reply offset other slaves copying this slave output buffer should use. */ char replid[CONFIG_RUN_ID_SIZE+1]; /* Master replication ID (if master). */ int slave_listening_port; /* As configured with: SLAVECONF listening-port */ char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */ int slave_capa; /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */ multiState mstate; /* MULTI/EXEC state */ int btype; /* Type of blocking op if CLIENT_BLOCKED. */ blockingState bpop; /* blocking state */ long long woff; /* Last write global replication offset. */ list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */ dict *pubsub_channels; /* channels a client is interested in (SUBSCRIBE) */ list *pubsub_patterns; /* patterns a client is interested in (SUBSCRIBE) */ sds peerid; /* Cached peer ID. */ /* Response buffer 响应缓冲区(固定缓冲区)*/ int bufpos; // 字节数组做为响应缓冲区 16K */ char buf[PROTO_REPLY_CHUNK_BYTES];//#define PROTO_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer } client;
/* Client flags */ #define CLIENT_SLAVE (1<<0) /* This client is a slave server */ #define CLIENT_MASTER (1<<1) /* This client is a master server */ #define CLIENT_MONITOR (1<<2) /* This client is a slave monitor, see MONITOR */ #define CLIENT_MULTI (1<<3) /* This client is in a MULTI context */ #define CLIENT_BLOCKED (1<<4) /* The client is waiting in a blocking operation */ #define CLIENT_DIRTY_CAS (1<<5) /* Watched keys modified. EXEC will fail. */ #define CLIENT_CLOSE_AFTER_REPLY (1<<6) /* Close after writing entire reply. */ #define CLIENT_UNBLOCKED (1<<7) /* This client was unblocked and is stored in server.unblocked_clients */ #define CLIENT_LUA (1<<8) /* This is a non connected client used by Lua */ #define CLIENT_ASKING (1<<9) /* Client issued the ASKING command */ #define CLIENT_CLOSE_ASAP (1<<10)/* Close this client ASAP */ #define CLIENT_UNIX_SOCKET (1<<11) /* Client connected via Unix domain socket */ #define CLIENT_DIRTY_EXEC (1<<12) /* EXEC will fail for errors while queueing */ #define CLIENT_MASTER_FORCE_REPLY (1<<13) /* Queue replies even if is master */ #define CLIENT_FORCE_AOF (1<<14) /* Force AOF propagation of current cmd. */ #define CLIENT_FORCE_REPL (1<<15) /* Force replication of current cmd. */ #define CLIENT_PRE_PSYNC (1<<16) /* Instance don't understand PSYNC. */ #define CLIENT_READONLY (1<<17) /* Cluster client is in read-only state. */ #define CLIENT_PUBSUB (1<<18) /* Client is in Pub/Sub mode. */ #define CLIENT_PREVENT_AOF_PROP (1<<19) /* Don't propagate to AOF. */ #define CLIENT_PREVENT_REPL_PROP (1<<20) /* Don't propagate to slaves. */ #define CLIENT_PREVENT_PROP (CLIENT_PREVENT_AOF_PROP|CLIENT_PREVENT_REPL_PROP) #define CLIENT_PENDING_WRITE (1<<21) /* Client has output to send but a write handler is yet not installed. */ #define CLIENT_REPLY_OFF (1<<22) /* Don't send replies to client. */ #define CLIENT_REPLY_SKIP_NEXT (1<<23) /* Set CLIENT_REPLY_SKIP for next cmd */ #define CLIENT_REPLY_SKIP (1<<24) /* Don't send just this reply. */ #define CLIENT_LUA_DEBUG (1<<25) /* Run EVAL in debug mode. */ #define CLIENT_LUA_DEBUG_SYNC (1<<26) /* EVAL debugging without fork() */ #define CLIENT_MODULE (1<<27) /* Non connected client used by some module. */
自1.0.0可用。
时间复杂度:O(1)。
INFO
命令以一种易于理解和阅读的格式,返回关于Redis服务器的各类信息和统计数值。
经过给定可选的参数 section ,可让命令只返回某一部分的信息:
server
: Redis服务器的通常信息
clients
: 客户端的链接部分
memory
: 内存消耗相关信息
persistence
: RDB和AOF相关信息
stats
: 通常统计
replication
: 主/从复制信息
cpu
: 统计CPU的消耗
commandstats
: Redis命令统计
cluster
: Redis集群信息
keyspace
: 数据库的相关统计
它也能够采起如下值:
all
: 返回全部信息
default
: 值返回默认设置的信息
若是没有使用任何参数时,默认为default
。
请注意不一样Redis版本会添加或者删除一些字段。一个健壮的客户端应用解析该命令的结果时,应该跳过未知的字段,而且优雅的处理缺乏的字段。
已下描述要求 Redis >= 2.4
下面是全部 server (记录了 Redis 服务器的信息)相关的信息:
redis_version
: Redis 服务器版本
redis_git_sha1
: Git SHA1
redis_git_dirty
: Git dirty flag
os
: Redis 服务器的宿主操做系统
arch_bits
: 架构(32 或 64 位)
multiplexing_api
: Redis 所使用的事件处理机制
gcc_version
: 编译 Redis 时所使用的 GCC 版本
process_id
: 服务器进程的 PID
run_id
: Redis 服务器的随机标识符(用于 Sentinel 和集群)
tcp_port
: TCP/IP 监听端口
uptime_in_seconds
: 自 Redis 服务器启动以来,通过的秒数
uptime_in_days
: 自 Redis 服务器启动以来,通过的天数
lru_clock
: 以分钟为单位进行自增的时钟,用于 LRU 管理
下面是全部 clients(记录了已链接客户端的信息) 相关的信息:
connected_clients
: 已链接客户端的数量(不包括经过从属服务器链接的客户端)
client_longest_output_list
: 当前链接的客户端当中,最长的输出列表
client_biggest_input_buf
: 当前链接的客户端当中,最大输入缓存
blocked_clients
: 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
下面是全部 memory (记录了服务器的内存信息)相关的信息:
used_memory
: 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human
: 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss
: 从操做系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_peak
: Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human
: 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_lua
: Lua 引擎所使用的内存大小(以字节为单位)
mem_fragmentation_ratio
: used_memory_rss
和 used_memory
之间的比率
mem_allocator
: 在编译时指定的, Redis 所使用的内存分配器。能够是 libc 、 jemalloc 或者 tcmalloc 。 在理想状况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
当 rss > used ,且二者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率能够经过 mem_fragmentation_ratio 的值看出。
当 used > rss 时,表示 Redis 的部份内存被操做系统换出到交换空间了,在这种状况下,操做可能会产生明显的延迟。
因为Redis没法控制其分配如何被映射到内存页面,所以较高的 usedmemoryrss 一般是内存使用量激增的结果。
当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操做系统。
若是 Redis 释放了内存,却没有将内存返还给操做系统,那么 used_memory 的值可能和操做系统显示的 Redis 内存占用并不一致。
查看 used_memory_peak 的值能够验证这种状况是否发生。
下面是全部 persistence (记录了跟 RDB
持久化和 AOF
持久化有关的信息)相关的信息:
loading
: 一个标志值,记录了服务器是否正在载入持久化文件。
rdb_changes_since_last_save
: 距离最近一次成功建立持久化文件以后,通过了多少秒。
rdb_bgsave_in_progress
: 一个标志值,记录了服务器是否正在建立 RDB 文件。
rdb_last_save_time
: 最近一次成功建立 RDB 文件的 UNIX 时间戳。
rdb_last_bgsave_status
: 一个标志值,记录了最近一次建立 RDB 文件的结果是成功仍是失败。
rdb_last_bgsave_time_sec
: 记录了最近一次建立 RDB 文件耗费的秒数。
rdb_current_bgsave_time_sec
: 若是服务器正在建立 RDB 文件,那么这个域记录的就是当前的建立操做已经耗费的秒数。
aof_enabled
: 一个标志值,记录了 AOF 是否处于打开状态。
aof_rewrite_in_progress
: 一个标志值,记录了服务器是否正在建立 AOF 文件。
aof_rewrite_scheduled
: 一个标志值,记录了在 RDB 文件建立完毕以后,是否须要执行预定的 AOF 重写操做。
aof_last_rewrite_time_sec
: 最近一次建立 AOF 文件耗费的时长。
aof_current_rewrite_time_sec
: 若是服务器正在建立 AOF 文件,那么这个域记录的就是当前的建立操做已经耗费的秒数。
aof_last_bgrewrite_status
: 一个标志值,记录了最近一次建立 AOF 文件的结果是成功仍是失败。
若是 AOF 持久化功能处于开启状态,那么这个部分还会加上如下字段:
aof_current_size
: AOF 文件目前的大小。
aof_base_size
: 服务器启动时或者 AOF 重写最近一次执行以后,AOF 文件的大小。
aof_pending_rewrite
: 一个标志值,记录了是否有 AOF 重写操做在等待 RDB 文件建立完毕以后执行。
aof_buffer_length
: AOF 缓冲区的大小。
aof_rewrite_buffer_length
: AOF 重写缓冲区的大小。
aof_pending_bio_fsync
: 后台 I/O 队列里面,等待执行的 fsync
调用数量。
aof_delayed_fsync
: 被延迟的 fsync
调用数量。
If a load operation is on-going, these additional fields will be added:
loading_start_time
: Epoch-based timestamp of the start of the load operation
loading_total_bytes
: Total file size
loading_loaded_bytes
: Number of bytes already loaded
loading_loaded_perc
: Same value expressed as a percentage
loading_eta_seconds
: ETA in seconds for the load to be complete
下面是全部 stats(记录了通常统计信息)相关的信息:
total_connections_received
: 服务器已接受的链接请求数量。
total_commands_processed
: 服务器已执行的命令数量。
instantaneous_ops_per_sec
: 服务器每秒钟执行的命令数量。
rejected_connections
: 由于最大客户端数量限制而被拒绝的链接请求数量。
expired_keys
: 由于过时而被自动删除的数据库键数量。
evicted_keys
: 由于最大内存容量限制而被驱逐(evict)的键数量。
keyspace_hits
: 查找数据库键成功的次数。
keyspace_misses
: 查找数据库键失败的次数。
pubsub_channels
: 目前被订阅的频道数量。
pubsub_patterns
: 目前被订阅的模式数量。
latest_fork_usec
: 最近一次 fork()
操做耗费的毫秒数。
下面是全部 replication(主/从复制信息) 相关的信息:
role
: 若是当前服务器没有在复制任何其余服务器,那么这个域的值就是 master
;不然的话,这个域的值就是 slave
。注意,在建立复制链的时候,一个从服务器也多是另外一个服务器的主服务器。
若是当前服务器是一个从服务器的话,那么这个部分还会加上如下字段:
master_host
: 主服务器的 IP 地址。
master_port
: 主服务器的 TCP 监听端口号。
master_link_status
: 复制链接当前的状态, up
表示链接正常, down
表示链接断开。
master_last_io_seconds_ago
: 距离最近一次与主服务器进行通讯已通过去了多少秒钟。
master_sync_in_progress
: 一个标志值,记录了主服务器是否正在与这个从服务器进行同步。
若是同步操做正在进行,那么这个部分还会加上如下字段:
master_sync_left_bytes
: 距离同步完成还缺乏多少字节数据。
master_sync_last_io_seconds_ago
: 距离最近一次由于 SYNC 操做而进行 I/O 已通过去了多少秒。
若是主从服务器之间的链接处于断线状态,那么这个部分还会加上如下字段:
master_link_down_since_seconds
: 主从服务器链接断开了多少秒。
如下是一些总会出现的字段:
connected_slaves
: 已链接的从服务器数量。
对于每一个从服务器,都会添加如下一行信息:
slaveXXX
: ID、IP 地址、端口号、链接状态
下面是全部 cpu 相关的信息:
used_cpu_sys
: Redis 服务器耗费的系统 CPU 。
used_cpu_user
: Redis 服务器耗费的用户 CPU 。
used_cpu_sys_children
: 后台进程耗费的系统 CPU 。
used_cpu_user_children
: 后台进程耗费的用户 CPU 。
commandstats
部分记录了各类不一样类型的命令的执行统计信息,好比命令执行的次数、命令耗费的 CPU 时间、执行每一个命令耗费的平均 CPU 时间等等。对于每种类型的命令,这个部分都会添加一行如下格式的信息:
cmdstat_XXX:calls=XXX,usec=XXX,usecpercall=XXX
cluster
部分记录了和集群有关的信息,它包含如下域:
cluster_enabled
: 一个标志值,记录集群功能是否已经开启。
keyspace
部分记录了数据库相关的统计信息,好比数据库的键数量、数据库已经被删除的过时键数量等。对于每一个数据库,这个部分都会添加一行如下格式的信息:
dbXXX:keys=XXX,expires=XXX
除上面给出的这些值之外, section
参数的值还能够是下面这两个:
all
: 返回全部信息
default
: 返回默认选择的信息
具体请参见下面的测试代码。
coderknock> INFO # Server redis_version:3.2.100 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:dd26f1f93c5130ee redis_mode:standalone os:Windows arch_bits:64 multiplexing_api:WinSock_IOCP process_id:19944 run_id:472a23ff45a04eb3081b48078a0c619c26376ddf tcp_port:6379 uptime_in_seconds:268 uptime_in_days:0 hz:10 lru_clock:5378046 executable:D:\redis\redis-server.exe config_file:D:\redis\redis.windows.conf # Clients connected_clients:1 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:711792 used_memory_human:695.11K used_memory_rss:674008 used_memory_rss_human:658.21K used_memory_peak:787952 used_memory_peak_human:769.48K total_system_memory:0 total_system_memory_human:0B used_memory_lua:37888 used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:0.95 mem_allocator:jemalloc-3.6.0 # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 rdb_last_save_time:1498550002 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 aof_enabled:0 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok # Stats total_connections_received:2 total_commands_processed:6 instantaneous_ops_per_sec:0 total_net_input_bytes:165 total_net_output_bytes:11895644 instantaneous_input_kbps:0.02 instantaneous_output_kbps:2286.67 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 evicted_keys:0 keyspace_hits:1 keyspace_misses:0 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:0 migrate_cached_sockets:0 # Replication role:master connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:0.20 used_cpu_user:0.11 used_cpu_sys_children:0.00 used_cpu_user_children:0.00 # Cluster cluster_enabled:0 # Keyspace db0:keys=43,expires=0,avg_ttl=0 db1:keys=3,expires=0,avg_ttl=0
本人的直播课程在 7 月份就要开始了,但愿小伙伴们支持一下,如今报名有优惠噢