嵌牛导读:为了学习Redis和更好地理解Redis,决定自己写一个C++版本的Redis
嵌牛鼻子:Redis
嵌牛提问:NoSQL究竟是什么?
嵌牛正文:
写在前面的话
第一,我这里仅仅只是学习Redis的思想。所以使用的是C++,而且很多数据结构使用STL。
第二,我这里不追求性能,所以不会极致地去考虑性能问题,而是以实现功能为主。
1.NoSQL究竟是什么?
对于看过Redis源码的我来说,实际上就是一张非常大的哈希表而已。
所以第一句话非常好写
但是,作为现代C++的编程,我不太喜欢裸指针的管理,我希望能一切对象化。而且Redis中也是用了一个RedisObject来抽象对象。
很明显,JObject会被我们做出纯虚类。
1.1 测试
1.2 源码
//JString.hh
#ifndef __JSTRING_HH__
#define __JSTRING_HH__
#include "JObject.hh"
#include "StringUtils.hh"
#include <string>
#include <iostream>
class JString
: public JObject
{
public:
explicit JString(const char* str)
: JObject()
, str_(str)
{
}
explicit JString(const std::string& str)
: JObject()
, str_(str)
{
}
virtual void* Data() override{
return &str_;
}
virtual void Print() override{
std::cout << str_ << std::endl;
}
~JString()override = default;
private:
std::string str_;
};
#endif
1.3 小结
到目前为止,虽然我们只是干了一个小事情。但实际上我们实现了当我们正确解析了命令后能够对数据库进行的操作。
2. Redis协议解析
因为我们这里做的实际上是Redis服务器端的部分。所以在客户端,我们希望仍然能使用Redis的客户端。因此,我们就需要理解Redis客户端的协议。
2.1 简单协议分析
这里仅仅以set name patientCat这句话作为例子,其发送的协议结果是
*3$3\r\nset\r\n$4\r\nname\r\n$10\r\npatientCat\r\n
看上去还是比较简单的,第一个*3代表发送了3个字符串,然后$3代表第一个字符串的长度是3,以此类推。
2.2 参考
https://redis.io/topics/protocol
2.3 简单的Redis客户端
如果我们要使用Redis的客户端的话,那么我们的服务器就需要实现一些不要的功能。因此,我们就使用telnet协议作为客户端。telnet协议会在每个命令之后加入\r\n。
那么我们就简单地按照字符串解析就可以了。
2.4 简单的Redis服务器
有了上述储备,实际上我们就可以实现一个简单地Redis服务器了,实际上就是一个简单地Telnet服务器加一些改装。
https://github.com/patientCat/Jedis
下RedisServer_0.1中完成了这个功能。