我们来一步一步用Java
写一个redis
的服务器,短期目标是实现所有的单机版本功能,长期目标是实现集群、类codis proxy功能。纯业余学习项目,一起来看看网络编程、NIO、并发、分布式的一些知识。
github地址 https://github.com/arthur-zhang/redis-server
今天的目标实现用redis-cli
连接我们的服务器,完成redis-cli
发送ping
命令,我们返回pong
先用tcpdump
抓个真正redis-cli
和redis-server
ping命令的包
127.0.0.1.62054 > 127.0.0.1.6379: Flags [P.], cksum 0xfe36 (incorrect -> 0xcfd1), seq 14:28, ack 8, win 12457, options [nop,nop,TS val 1573721279 ecr 1573665837], length 14 |
结合redis通信协议 我们可以看到请求和响应如下
请求2A 31 0D 0A 24 34 0D 0A 70 69 6E 67 0D 0A
对应 *1\r\n$4\r\nping\r\n
响应2B 50 4F 4E 47 0D 0A
对应 +PONG\r\n
请求协议*<参数数量> CR LF
$<参数 1 的字节数量> CR LF
<参数 1 的数据> CR LF
...
$<参数 N 的字节数量> CR LF
<参数 N 的数据> CR LF
redis的响应回复
- 状态回复(status reply)的第一个字节是 “+”
- 错误回复(error reply)的第一个字节是 “-“
- 整数回复(integer reply)的第一个字节是 “:”
- 批量回复(bulk reply)的第一个字节是 “$”
- 多条批量回复(multi bulk reply)的第一个字节是 ““
这里的 1\r\n$4\r\nping\r\n┌───────────────┐
│argument count │
└───────────────┘
▲
│
│
┌───┬─┴─┬────┬───┬──┬────┬────┬────┐
│ * │ 1 │\r\n│ $ │4 │\r\n│ping│\r\n│
└───┴───┴────┴───┴┬─┴────┴────┴────┘
│
│
│
▼
┌──────────────────────────┐
│ argument#1 byte size │
└──────────────────────────┘
基本代码如下,监听6397,顺序处理请求,用redis-cli
请求我们的server
redis-cli -p 6397 |
部分代码如下
public class RedisServer { |