缘起
近期在阅读《Redis 设计与实现》一书,我发现如果不动手实践,显然是无法真正理解书上奇形怪状的数据结构的。
所以为了锻炼自己的数据结构与算法能力,我参照其中一些数据结构的 API,对诸如动态字符串 SDS,双端链表 list,字典 dict 及其内嵌的哈希表 dictht 等数据结构进行了实现。
当然,为了让他们有用武之地,我在这基础上构建了一个小型 Redis,作为自己的学习记录。当然现在的项目功能还不够完善,后期我会慢慢将其完善,恳请批评指教!
github 链接
实现流程
如今本项目还只是实现了 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 命令。
4)检查命令长度
5)执行相关命令
测试结果