Redis 11 命令执行过程

2016/07/29 Redis 共 2806 字,约 9 分钟
MiniPa

1.redis server 端命令执行过程

  • 1)nio层读取数据
  • 2)解析数据 ==> 命令行格式
  • 3)查找命令对应的执行函数 ==> 执行命令
  • 4)同步数据到 slave和aof

cmd1

命令执行过程源码

2.同步 AOF,AOF涉及缓存有多份

  • 1.先缓存在 局部buf 中

  • 2.将局部buf copy 到 全局 server.aof_buf

  • 3.如果刚好在重写 aof 文件,还会将数据 copy到重写缓存中

3.redis 通信协议

-----------------------------------------
格式如下:
---------------------------------------------
*<参数数量> CR LF
$<参数 1 的字节数量> CR LF
<参数 1 的数据> CR LF
...
$<参数 N 的字节数量> CR LF
<参数 N 的数据> CR LF


-----------------------------------------
协议请求例子如下:
-----------------------------------------
*3
$3
SET
$5
mykey
$7
myvalue


-----------------------------------------
实际传输格式如下:
-----------------------------------------
"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"


-----------------------------------------
响应报文格式如下:
-----------------------------------------
状态回复(status reply)的第一个字节是 "+"
错误回复(error reply)的第一个字节是 "-"
整数回复(integer reply)的第一个字节是 ":"
批量回复(bulk reply)的第一个字节是 "$"
多条批量回复(multi bulk reply)的第一个字节是 "*"

-----------------------------------------
状态回复报文格式如下:
-----------------------------------------
+OK

-----------------------------------------
错误回复报文格式如下:
-----------------------------------------
-ERR unknown command 'foobar'
-WRONGTYPE Operation against a key holding the wrong kind of value

-----------------------------------------
整数回复报文格式如下:
-----------------------------------------
整数回复就是一个以 ":" 开头, CRLF 结尾的字符串表示的整数。
比如说, ":0\r\n" 和 ":1000\r\n" 都是整数回复。

-----------------------------------------
批量回复报文格式如下:
-----------------------------------------
服务器使用批量回复来返回二进制安全的字符串,字符串的最大长度为 512 MB 。
服务器发送的内容中:
*   第一字节为 `"$"` 符号
*   接下来跟着的是表示实际回复长度的数字值
*   之后跟着一个 CR LF
*   再后面跟着的是实际回复数据
*   最末尾是另一个 CR LF

对于前面的命令,服务器实际发送的内容为:
"$6\r\nfoobar\r\n"

如果被请求的值不存在, 那么批量回复会将特殊值 `-1` 用作回复的长度值, 就像这样:
服务器:$-1
-----------------------------------------
多条批量回复报文格式如下:
-----------------------------------------
像 [LRANGE] 这样的命令需要返回多个值, 这一目标可以通过多条批量回复来完成。
多条批量回复是由多个回复组成的数组, 数组中的每个元素都可以是任意类型的回复, 包括多条批量回复本身。
多条批量回复的第一个字节为 `"*"` , 后跟一个字符串表示的整数值, 这个值记录了多条批量回复所包含的回复数量, 再后面是一个 CRLF 。

客户端: LRANGE mylist 0 3
服务器: *4
服务器: $3
服务器: foo
服务器: $3
服务器: bar
服务器: $5
服务器: Hello
服务器: $5
服务器: World

在上面的示例中,服务器发送的所有字符串都由 CRLF 结尾。

正如你所见到的那样, 多条批量回复所使用的格式, 和客户端发送命令时使用的统一请求协议的格式一模一样。 它们之间的唯一区别是:

统一请求协议只发送批量回复。
而服务器应答命令时所发送的多条批量回复,则可以包含任意类型的回复。
以下例子展示了一个多条批量回复, 回复中包含四个整数值, 以及一个二进制安全字符串:
*5\r\n
:1\r\n
:2\r\n
:3\r\n
:4\r\n
$6\r\n
foobar\r\n
在回复的第一行, 服务器发送 *5\r\n , 表示这个多条批量回复包含 5 条回复, 再后面跟着的则是 5 条回复的正文。

多条批量回复也可以是空白的(empty), 就像这样:
客户端: LRANGE nokey 0 1
服务器: *0\r\n

无内容的多条批量回复(null multi bulk reply)也是存在的, 
比如当 [BLPOP]命令的阻塞时间超过最大时限时, 它就返回一个无内容的多条批量回复, 这个回复的计数值为 `-1` :
客户端: BLPOP key 1
服务器: *-1\r\n

多条批量回复中的元素可以将自身的长度设置为 `-1` , 从而表示该元素不存在, 并且也不是一个空白字符串(empty string)。

当 [SORT] 命令使用 `GET pattern` 选项对一个不存在的键进行操作时, 就会发生多条批量回复中带有空白元素的情况。

以下例子展示了一个包含空元素的多重批量回复:
服务器: *3
服务器: $3
服务器: foo
服务器: $-1
服务器: $3
服务器: bar

4.内联命令格式

当你需要和 Redis 服务器进行沟通, 但又找不到 redis-cli , 
而手上只有 telnet 的时候, 你可以通过 Redis 特别为这种情形而设的内联命令格式来发送命令。
因为没有了统一请求协议中的 "*" 项来声明参数的数量, 所以在 telnet 会话输入命令的时候, 
必须使用空格来分割各个参数, 服务器在接收到数据之后, 会按空格对用户的输入进行分析(parse), 并获取其中的命令参数。

例子如下:
-----------------------------------------
客户端: PING
服务器: +PONG

参考:

文档信息

Search

    Table of Contents