专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
神秘的程序员们  ·  文生图模型进化简史和生成能力比较——艺术肖像篇 ·  1 年前  
程序员小灰  ·  公司来的新人把 MyBatis 替换成 ... ·  4 天前  
程序员鱼皮  ·  年薪 10 万和 70 ... ·  3 天前  
程序猿  ·  太戏剧了!被字节起诉索赔 800 ... ·  5 天前  
51好读  ›  专栏  ›  OSC开源社区

实现一个 Java 版的 Redis:百行代码解析Redis 协议.

OSC开源社区  · 公众号  · 程序员  · 2016-10-22 08:28

正文

#长按上图识别二维码,参与OSC源创会年终盛典#


最近看了 Redis 的代码,感觉还是挺简单的.有冲动想用其它语言实现(抄)一个.原来想用 Python 实现来着.后来想想试试 Netty。


原因有二


第一:Java 的NIO 和Netty 的 EventLoop 配合起来和 Redis 的网络模型很接近.都是 Ractor 模型.甚至 Redis的模型更简单--只有一个 EventLoop 线程.写(抄)起来更方便。

第二:Netty 架构挺不错.借这个机会学习一下.

如果我们从一个很抽象(简单)的角度看 Redis Server.就是一个监听在 6379 的程序, 本质上是一个处理单线线请求的 Hashtable. 而 Redis 的协议也是非常非常的简单.比 http 协议可简单多了。

以下是这个协议的一般形式:




这基本就是一个很简单的有限状态机.




所以我给我们的命令解析器设置3个状态.




我们将初始状态设置NUMBER_OF_ARGS 也就是开始那个绿色的状态.当有数据到达时.我们不停的判断程序的状态.是哪个状态,我们做啥.




下面我们按着我们上面思路实现一下.






写到这里有一个小问题,如果你上面代码看懂了,你就会发现一个小问题.如果由于网络原因,有时数据可以并没有接收完全.而我们的代码完全没有做这方面的考虑? 而 Checkpoint 这是又什么鬼?

第一个问题:

事实上我们有考虑这个问题.所以我们继承了一个相对比较特别Decoder--ReplayingDecoder.我们看一下ReplayingDecoder的 CallDecode 方法.(这个名字起的非常的直白.你一定明白他是干啥的)




Signal replay 是 Netty 中定义的一个错误.当我们读取错误时,Netty 会再等到下次有数据到达时,再试一次Decode 方法.看看能再解析成功.所以我们就可以假设置我们要的数据都已经读取了.

但是要注意: replaydecoder 的 decode 方法会被反复调用..所以我们的代码中要做好这样的准备.

第二个问题:

CheckPoint 就是为了防止如果每次反复调用 Decode 时从头执行,而设置的一个状态.让我们这个 decode 方法有状态.

好了.现在我们创建监部分的代码.这都是套数,直接抄下来就行了。




我们把 Redis 的协议解析为RedisFrame 类




好了.这时你打开 Redis-cli 试试是不是可以连上我们的 "假Redis" Server.有意的是---你打开 Redis-cli.他会自动发一个 "Command" 命令.而你不管回复什么,它都认为连上了.



END


推荐阅读
程序员创造了世界,世界欠程序员一个1024
1024 尽情“摇”摆,High 翻全场等你来
27款实用高效的腾讯热门开源项目推荐
Ubuntu 16.10 安装之后必须做的 16件事

点击“阅读原文”查看更多精彩内容