1.redis server 端命令执行过程
- 1)nio层读取数据
- 2)解析数据 ==> 命令行格式
- 3)查找命令对应的执行函数 ==> 执行命令
- 4)同步数据到 slave和aof
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
参考:
文档信息
- 本文作者:jiushun.cheng
- 本文链接:https://minipa.github.io/2016/07/29/redis-command/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)