点击上方蓝色“ Go语言中文网 ”关注, 每天一起学 Go
本文是 《用 Golang 实现一个 Redis》系列文章第二篇,本文将分别介绍 Redis 通信协议 以及 协议解析器 的实现,若您对协议有所了解可以直接阅读协议解析器部分。
Redis 通信协议
Redis 自 2.0 版本起使用了统一的协议 RESP (REdis Serialization Protocol),该协议易于实现,计算机可以高效的进行解析且易于被人类读懂。
RESP 是一个二进制安全的文本协议,工作于 TCP 协议上。客户端和服务器发送的命令或数据一律以 \r\n
(CRLF)结尾。
RESP 定义了 5 种格式:
- 简单字符串(Simple String): 服务器用来返回简单的结果,比如"OK"。非二进制安全,且不允许换行。
- 错误信息(Error): 服务器用来返回简单的结果,比如"ERR Invalid Synatx"。非二进制安全,且不允许换行。
- 整数(Integer):
llen
、scard
等命令的返回值, 64 位有符号整数 - 字符串(Bulk String): 二进制安全字符串,
get
等命令的返回值 - 数组(Array, 旧版文档中称 Multi Bulk Strings): Bulk String 数组,客户端发送指令以及
lrange
等命令响应的格式
RESP 通过第一个字符来表示格式:
- 简单字符串:以"+" 开始, 如:"+OK\r\n"
- 错误:以"-" 开始,如:"-ERR Invalid Synatx\r\n"
- 整数:以":"开始,如:":1\r\n"
- 字符串:以
$
开始 - 数组:以
*
开始
Bulk String 有两行,第一行为 $
+正文长度,第二行为实际内容。如:
$3\r\nSET\r\n
Bulk String 是二进制安全的可以包含任意字节,就是说可以在 Bulk String 内部包含 "\r\n" 字符(行尾的 CRLF 被隐藏):
$4
a\r\nb
$-1
表示 nil, 比如使用 get 命令查询一个不存在的 key 时,响应即为$-1
。
Array 格式第一行为 "*"+数组长度,其后是相应数量的 Bulk String。如, ["foo", "bar"]
的报文:
*2
$3
foo
$3
bar
客户端也使用 Array 格式向服务端发送指令。命令本身将作为第一个参数,如 SET key val