2013-01-28

网络协议设计思想与SSDB网络协议

Views: 31664 | 2 Comments

网络协议可以分为文本协议和二进制协议, 而对于基于报文的协议可分为定长报文协议和变长报文协议. 而现实业务中的网络协议基本都是基于报文的协议.

从应用层网络协议的设计发展来看, 二进制协议和定长报文协议极为罕见. 在变长报文协议中, 有两种实现方式: 结束标记和长度字段. 下面以最流行的 HTTP 来进行举例分析.

HTTP 是文本协议, 变长报文协议, 带长度字段的报文协议. HTTP 带有多个 Key-Value 对组成的首部, 用连续的两个 CRLF 分隔首部和报体, 没有报文结束标记(HTTP 1.0 以连接关闭来标记报文结束), 同时 HTTP 还是文本和二进制混合的协议, 报文首部有长度字段, 所以报体中的二进制数据无需转义.

设计网络协议, 最好就是以 HTTP 协议作为参考和标杆, 在上面做加法和减法. SSDB 的网络协议借鉴了 HTTP, 与 Redis 的网络协议殊途同归, 但相比 Redis 的网络协议更简化. 所以, SSDB 的客户端 SDK 都非常简洁, 即使是强类型语言 Java 的版本, 协议核心代码也不过百十来行.

长度字段: SSDB 的单个报文中包含多个长度字段, 因为单个 SSDB 报文包含多个分段, 每个分段可以理解为参数列表中的一个参数. 长度字段用一行数字文本来表示, 行结束符兼容 LF 和 CRLF. 使用文本而不是使用二进制, 既避免了大端小端问题, 打印效果也更好.

段结束符: 虽然有了长度字段, 但 SSDB 协议还是冗余了 LF 作为段结束符, 主要是从打印效果方面考虑. 打印效果(文本化效果)是应用层协议最重要最有用的特性!

报文结束符: SSDB 使用连续的两个 LF 作为报文结束符, 这和 HTTP 协议一样. 为什么不使用 Redis 类似的前置总长度(段数量)字段呢? 因为连续的两个 LF 打印出来可以显示为一行空白行, 视觉效果更佳, 同时也可兼具流式协议的优点.

下面是一个 telnet 连接 SSDB 服务器进行交互的例子, 从中可以看出 SSDB 网络协议的优雅:

$ telnet 127.0.0.1 8888
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
3
set
1
a
2
hi

2
ok

3
get
1
a

2
ok
2
hi

Related posts:

  1. 性能超越 Redis 的 NoSQL 数据库 SSDB
  2. SSDB 支持 Redis 协议!
  3. 单实例支撑每天上亿个请求的SSDB
  4. 使用 Twemproxy 来做 SSDB 负载均衡
  5. 从 Redis 迁移到 SSDB
Posted by ideawu at 2013-01-28 13:33:22

2 Responses to "网络协议设计思想与SSDB网络协议"

Leave a Comment