前言

一直以来都来研究redis的设计理念和实现思路,随着时间的推移有了想自己实现一版的想法,由于笔者本身是一名java开发,对于C语言中的某些理念不是非常熟悉,于是折中选用go语言进行实现,而这个开源项目将会记录笔者实现mini-redis的一些开发思路和实现的介绍。

mini-redis无论从函数名还是整体思路都基本沿用了原生redis的规范,唯一与C语言理念不同的是go语言本身对于epoll进行了封装,要想实现redis那种单线程处理所有指令的操作,笔者通过channel交互的方式来达到这一点。

同时,为了让读者更加直观的了解redis的实现核心脉络,笔者也在实现时也进行了一定简化,希望对那些想了解redis但是又不太熟悉C语言的开发朋友有所帮助。

如何部署运行mini-redis

这里笔者以Linux为例,我们找到项目中的build-linux.sh键入如下指令:

./build-linux.sh

执行该指令之后,我们的项目会生成一个bin的文件夹,其内部一个redis-server的可执行文件,此时我们通过Linux服务器执行./redis-server,最终项目会输出如下内容,说明项目成功运行了:

sharkchili@DESKTOPJ:~$ ./redis-server
2024/09/08 23:07:09 init redis server
2024/09/08 23:07:09 load redis server config
2024/09/08 23:07:09 this redis server address: localhost:6379
2024/09/08 23:07:09 event loop is listening and waiting for client connection.

此时我们就可以通过redis-cli连接mini-redis了:

sharkchili@DESKTOP-xxxx:~/redis/src$ ./redis-cli
127.0.0.1:6379> command
1) "COMMAND"
2) "PING"
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

目前的开发进度

截至目前,笔者完成了下面几个核心模块的开发:

  • mini-redis服务端ip端口绑定初始化。
  • redis-cli连接时将其封装为redisClient,并能够接收其命令请求。
  • 解析redis-cli通过RESP协议发送的命令请求。
  • 支持客户端键入command指令并回复当前服务端支持的指令集。
  • 支持客户端键入PING指令感知mini-redis是否可用。
  • 完成GET、SET指令指令解析和常规用法
  • 完成列表LINDEX、LPOP、RPUSH、LRANGE指令,可作为内存消息队列

后续开发计划:

  • 字典数据结构开发
  • 列表底层数据结构双向链表
  • 有序集合等数据结构开发
  • 字符串常规GET指令开发调测
  • 字符串SET指令开发调测
  • 列表操作LINDEX、LPOP、RPUSH、LRANGE指令开发
  • 字典操作HSET、HMSET、HSETNX、HGET、HMGET、HGETALL、HDEL指令开发
  • 有序集合所有操作指令开发
  • AOF持久化和重载机制
  • LRU缓存置换算法
  • 性能压测

如何阅读源码

本项目目录结构为:

  • adlist.go : redis底层双向链表实现
  • adlist_test.go : 双向链表测试单元
  • client.go : 处理redis-cli请求的客户端对象
  • command.go : redis所有操作指令实现
  • db.go : redis内存数据库
  • dict.go : 哈希对象操作实现
  • networking.go : 网络操作函数集
  • object.go : redis对象创建函数
  • redis.conf : 配置文件
  • redis.go : redis服务端
  • t_hash.go : 针对redis对象的哈希操作函数
  • t_list.go : 基于adlist双向链表对于redis对象的链表操作函数
  • util.go : mini-redis工具类
  • main.go : mini-redis启动入口
  • go.mod
  • build-windows.sh : Windows下程序启动脚本
  • build-linux.sh : Linux启动脚本
  • README.md

同时,在开发过程中的设计和实现也都会不断输出为文档,读者可以按需取用下面的文章来了解笔者的开发过程和实现思路:

来聊聊我用go手写redis这件事:https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486169&idx=1&sn=9b562eca113fbbe02d07f9ae2ccf0e79&chksm=c0c65e67f7b1d77166b7ff9a7a0403fb02d39ae1a111a73e12f7f1cdc3e79e91b2d116a5908a#rd

mini-redis如何解析处理客户端请求 :https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486258&idx=1&sn=5a1bfffc075881e32cc247d6a76a88fe&chksm=c0c65f8cf7b1d69a91c1a9b3c5d15467e820db886e5e60ba059ccb3861b21d5e57ee8fc9b13d#rd

实现mini-redis字符串操作:https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486268&idx=1&sn=003ba535c5a78c88cb4a15859edcfdf5&chksm=c0c65f82f7b1d69406832650746f93de3ef6b3b8a77badcf0f9924e1e052369990b4d233f10f#rd

硬核复刻redis底层双向链表核心实现:https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486323&idx=1&sn=70812c54fa782e459d443951c0a39752&chksm=c0c65fcdf7b1d6dbfe783d1d8e11e270fc567921a5e1cdbb699f2bb7a1be5392d9a9c791ee25#rd

聊聊我说如何用go语言实现redis列表操作:https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486416&idx=1&sn=1f5ad9ad17a80e2cd868ec8e33fb5015&chksm=c0c65f6ef7b1d6788012b590def4654e07153adcb18a7911fe87604f1eee55c1ba58e3c31012#rd

动手复刻redis之go语言下的字典的设计与落地:https://mp.weixin.qq.com/s?__biz=MzkwODYyNTM2MQ==&mid=2247486645&idx=1&sn=23a386c2fab95fbfd11b1b34ac1fbbcc&chksm=c0c6580bf7b1d11dde0655f93ae70265f16e8b693a0165d7b3144d9ac4d4a9d2c472b94b9d14#rd

关于我

Hi,我是 sharkChili ,是个不断在硬核技术上作死的技术人,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

image