小型Redis完成! | 自己实现Redis源代码(4)
缘起
近期在阅读《Redis设计与实现》一书,我发现如果不动手实践,显然是无法真正理解书上奇形怪状的数据结构的。
所以为了锻炼自己的数据结构与算法能力,我参照其中一些数据结构的API,对诸如动态字符串SDS,双端链表list,字典dict及其内嵌的哈希表dictht等数据结构进行了实现。
当然,为了让他们有用武之地,我在这基础上构建了一个小型Redis,作为自己的学习记录。当然现在的项目功能还不够完善,后期我会慢慢将其完善,恳请批评指教!
实现流程
如今本项目还只是实现了key-value的存储功能,其他诸如切换数据库、数据持久化等功能将会在后期慢慢实现。
项目实现流程如下:
- 基本数据结构的构建
- 客户端服务端的交互
- 基本命令的实现
原理分析
1.基本数据结构的构建
下面主要介绍数据库结构redisDb的构建,其他数据结构可以参见我的系列文章:
动态字符串SDS的实现 | 自己实现Redis源代码(1)
双端链表list的实现 | 自己实现Redis源代码(2)
字典与哈希表 | 自己实现Redis源代码(3)
数据库redisDb的基本结构如下:
2. 客户端服务端的交互
客户端与服务端的结构如下
两者通过建立网络连接,进行数据交互,完成通信过程。这里的网络连接的建立是通过套接字socket建立的。
在Redis的单机应用中,一个服务端redisServer进程可以处理多个客户端的请求。对多个客户端的处理部分我们通过创建线程来完成。每次检测到有一个客户端进行连接,便为其创建一个工作线程,在其中执行客户端与服务端的通信操作。
服务端含有一个数据库数组,记录保存在服务端的所有数据库,默认数据库数量为16。
客户端含有一个数据库指针,指向其当前正在使用的目标数据库,方便其进行切换数据库操作。
3. 基本命令的实现
这里主要讲解get/set命令的实现。
服务端结构到客户端输入的命令,需要进行一下操作:
1)判断是否为查看类命令
如,查看帮助文档,查看版本信息等;
2)对命令进行分割
3)判断命令关键字
如,命令为set pig 12,切割后我们可以得到["set","pig","12"],通过对关键字set的判断,可以得知其为set命令。