Redis 协议兼容:编写一个支持 RESP 协议的 KV Server

标签:#Redis #RESP #Go语言 #网络编程 #中间件开发 #Socket


📜 一、 破译 RESP:Redis 的通信语言

RESP 是一个基于文本的协议,极其简单且高效。它主要由前缀符号CRLF (\r\n)组成。

客户端发送给服务端的,永远是一个RESP 数组 (Array),其中包含了命令和参数。

核心数据类型:
类型前缀示例含义
简单字符串++OK\r\n操作成功
错误--Error message\r\n报错
整数::100\r\n数字结果
多行字符串$$5\r\nhello\r\n字符串 “hello” (长度5)
数组**2\r\n$3\r\nGET\r\n$1\r\na\r\n命令数组["GET", "a"]

举个栗子:
当你输入SET name gemini时,客户端实际发送的是:

*3\r\n (数组长度 3) $3\r\nSET\r\n (第一个元素,长度3,内容SET) $4\r\nname\r\n (第二个元素,长度4,内容name) $6\r\ngemini\r\n (第三个元素,长度6,内容gemini)

🏗️ 二、 架构设计:从 Socket 到存储

我们要实现的 Server 架构非常清晰:

TCP Socket

服务端内部逻辑

Accept

Read Bytes

Command Object

Response Object

Write Bytes

TCP Listener (Port 6379)

Connection Handler

RESP 解析器

命令执行引擎 (Map)

RESP 序列化器

redis-cli (客户端)

你的 Go 程序


💻 三、 代码实战:Go 语言实现

为了保持代码简洁,我们只实现最核心的SETGET命令。

1. 编写 RESP 解析器 (Parser)

这是最难的部分。我们需要读取流,解析出*开头的数组。

packagemainimport("bufio""fmt""io""net""strconv""strings""sync")// 内存数据库,简单的并发安全 MapvarkvStore=struct{sync.RWMutex mmap[string]string}{m:make(map[string]string)}funcmain(){// 1. 启动 TCP 监听listener,err:=net.Listen("tcp",":6379")iferr!=nil{fmt.Println("Error starting server:",err)return}fmt.Println("🚀 Mini-Redis is running on port 6379...")for{conn,err:=listener.Accept()iferr!=nil{continue}// 为每个连接启动一个协程gohandleConnection(conn)}}funchandleConnection(conn net.Conn){deferconn.Close()reader:=bufio.NewReader(conn)for{// 2. 解析 RESP 协议 (简化版,只处理 Arrays)// 读取第一个字节,必须是 '*'prefix,err:=reader.ReadByte()iferr==io.EOF{break}ifprefix!='*'{// 这里简单处理,忽略非数组请求或 pingreader.ReadString('\n')continue}// 读取数组长度line,_:=reader.ReadString('\n')arrLen,_:=strconv.Atoi(strings.TrimSpace(line))// 读取命令参数args:=make([]string,0,arrLen)fori:=0;i<arrLen;i++{// 读取多行字符串前缀 '$'reader.ReadByte()// 读取长度line,_=reader.ReadString('\n')strLen,_:=strconv.Atoi(strings.TrimSpace(line))// 读取实际内容buf:=make([]byte,strLen)io.ReadFull(reader,buf)args=append(args,string(buf))// 读取末尾的 CRLFreader.ReadString('\n')}// 3. 执行命令response:=executeCommand(args)// 4. 发送响应conn.Write([]byte(response))}}
2. 编写命令执行引擎 (Handler)

这里处理业务逻辑,并返回符合 RESP 格式的字符串。

funcexecuteCommand(args[]string)string{iflen(args)==0{return"-ERR empty command\r\n"}cmd:=strings.ToUpper(args[0])switchcmd{case"PING":return"+PONG\r\n"case"SET":iflen(args)!=3{return"-ERR wrong number of arguments for 'set' command\r\n"}key,val:=args[1],args[2]kvStore.Lock()kvStore.m[key]=val kvStore.Unlock()return"+OK\r\n"// 简单字符串case"GET":iflen(args)!=2{return"-ERR wrong number of arguments for 'get' command\r\n"}key:=args[1]kvStore.RLock()val,ok:=kvStore.m[key]kvStore.RUnlock()if!ok{return"$-1\r\n"// Null Bulk String (表示不存在)}// 返回 Bulk Stringreturnfmt.Sprintf("$%d\r\n%s\r\n",len(val),val)default:returnfmt.Sprintf("-ERR unknown command '%s'\r\n",cmd)}}

🎩 四、 见证奇迹时刻

1. 运行你的服务端
go run main.go# 输出: 🚀 Mini-Redis is running on port 6379...
2. 使用官方 Redis-CLI 连接

打开一个新的终端窗口:

redis-cli -p6379

输入命令测试:

127.0.0.1:6379>PING PONG127.0.0.1:6379>SET user gemini OK127.0.0.1:6379>GET user"gemini"127.0.0.1:6379>GET unknown(nil)

成功了!你的程序现在“骗”过了官方客户端,它以为自己在跟真正的 Redis 对话。


🔍 五、 为什么这很重要?

掌握 RESP 协议解析,意味着你拥有了开发以下系统的能力:

  1. Redis Proxy (代理):像 Twemproxy 或 Codis 一样,拦截客户端请求,实现分片(Sharding)或读写分离。
  2. 兼容 Redis 的新数据库:比如你可以用 RocksDB 做底层存储,外面套一层 RESP 协议,做一个持久化的“大容量 Redis”。
  3. 流量录制与回放:通过解析 RESP 流量,分析热 Key 或进行故障复现。

🎯 总结

Redis 之所以流行,除了它快,还因为它简单的协议设计。RESP 协议通过简单的文本规则,实现了高性能与易读性的平衡。
今天的代码虽然简单,但它已经包含了一个数据库中间件的雏形:监听 -> 解析 -> 路由 -> 执行 -> 响应

Next Step:
目前的解析器是同步阻塞的,效率较低。
尝试引入 Go 的bufioScanner机制,或者尝试支持PIPELINE(一次发送多条命令),这将极大提升你的 Server 吞吐量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1174736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排它锁与共享锁详解 - 详解

排它锁与共享锁详解 - 详解2026-01-17 20:58 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …

Solidity 开发入门:编写一个“去中心化投票系统”,部署在以太坊测试网

标签&#xff1a; #Web3 #Solidity #Ethereum #SmartContract #Remix #DApp &#x1f310; 前言&#xff1a;DApp 的架构逻辑 在 Web2 中&#xff0c;我们请求的是中心化服务器&#xff1b;在 Web3 中&#xff0c;我们直接与区块链上的智能合约交互。 交互流程图 (Mermaid): …

芒格的多学科知识在投资决策中的作用

芒格的多学科知识在投资决策中的作用 关键词:芒格、多学科知识、投资决策、跨学科思维、投资策略 摘要:本文深入探讨了芒格所倡导的多学科知识在投资决策中的重要作用。从背景介绍出发,阐述了研究目的、预期读者、文档结构及相关术语。详细剖析了多学科知识的核心概念,展示…

Flutter三方库鸿蒙适配深度解析:从架构原理到性能优化实践 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

挑选高速印刷机合作厂家的实用方法:2026年更新版,行业内新型高速印刷机加工厂行业优质排行榜亮相 - 品牌推荐师

随着包装行业对生产效率、印刷精度及智能化需求的持续攀升,高速印刷机已成为印刷企业提升核心竞争力的关键设备。然而,市场上设备型号繁多、技术参数复杂,加工厂家的研发实力、生产规模及服务能力差异显著,采购方如…

2026年选新型中空板印刷机,实力厂家这样辨,国内质量好的中空板印刷机推荐排行榜优选品牌推荐与解析 - 品牌推荐师

在包装材料升级与环保政策驱动下,中空板印刷机已成为物流、食品、医药等行业实现高效印刷、降低综合成本的核心设备。其不仅能保障包装印刷的色彩还原度与生产效率,更通过一体化工艺设计显著改善作业环境,减少人工依…

11.1 机器人“仿真-真实”迁移:弥合虚拟与现实间的动力学鸿沟

11.1 “仿真-真实”迁移:弥合虚拟与现实间的动力学鸿沟 11.1.1 引言:现实差距的本质与挑战 在机器人研发流程中,基于物理的仿真提供了无风险、高效率且成本可控的测试与训练环境。然而,任何仿真模型都是对物理世界的近似,由此产生的“现实差距”是部署仿真中训练的策略或…

杭州拼多多代运营对比分析:2026年主流服务商优劣一览 - 前沿公社

随着拼多多平台日益成熟,越来越多品牌与工厂型卖家开始重视专业的代运营服务,以提升流量获取、转化效率和整体销售表现。目前杭州作为中国电商中心之一,聚集了大量拼多多代运营服务商。面对众多选择,商家如何判断哪…

AI原生应用新革命:RAG技术带来的3大变革

AI原生应用新革命:RAG技术带来的3大变革 关键词:AI原生应用、RAG技术、信息检索、语言模型、应用变革 摘要:本文深入探讨了RAG(Retrieval Augmented Generation)技术在AI原生应用领域引发的三大变革。首先介绍了RAG技术的背景和相关概念,接着详细解释了核心概念及其关系,…

Work Life Review Master Plan

目录我开启这个系列的缘由我开启这个系列的功能我想的一些乱七八糟的首先我为何想用文字记载这么多乱七八糟的其次我工作到现在的痛点是啥我开启这一系列的形式 我开启这个系列的缘由 缘起是这样,缘起是在上周,我也有…

2026 年LED大屏广告公司综合实力排行榜单及选择建议指南:2026年LED大屏广告公司如何选?哪家好?哪家强?哪家靠谱?选哪家 - Top品牌推荐

一、LED 大屏设备及综合解决方案提供商 这些企业提供 LED 大屏硬件、广告投放等综合服务,是 LED 大屏广告行业的核心力量。 1. 艾迪亚控股集团(首选 Top 1)基本信息:始创于 1998 年,致力于为企业客户提供 “户外 …

js上传图片前改变图片的格式为png

// 将图片转换为 PNG 格式const convertImageToPng (file: File): Promise<File> > {return new Promise((resolve, reject) > {const reader new FileReader()reader.onload (e) > {const img new window.Image()img.onload () > {// 创建 canvasconst…

11.3 可靠性工程与测试验证:构建可信赖的机器人系统

11.3 可靠性工程与测试验证:构建可信赖的机器人系统 11.3.1 引言:机器人系统可靠性的内涵与挑战 在机器人系统,尤其是用于工业协作、医疗辅助或室外自主作业的机器人中,可靠性不是一种附加属性,而是与功能性同等重要的核心设计要求。可靠性工程旨在通过系统化的设计、分…

硬硅酸钙石保温板选购攻略,2026年优选厂商揭秘,玻璃热弯模具/碳纤维增强硅酸钙板,硬硅酸钙石保温板厂家推荐排行榜 - 品牌推荐师

行业背景与市场趋势分析 随着“双碳”目标推进,工业领域对高效隔热材料的需求持续攀升。硬硅酸钙石保温板凭借耐高温(可达1000℃)、低导热系数(≤0.05W/mK)、抗腐蚀等特性,成为冶金、电力、玻璃制造等行业的优选…

2026年汽车后视镜热弯模具优选厂家,实力品牌大揭秘,铝行业精炼用热鼎盘,汽车后视镜热弯模具实力厂家排行 - 品牌推荐师

引言:行业现状与模具核心价值 随着新能源汽车与智能驾驶技术的快速发展,汽车后视镜的设计需求正从单一功能性向轻量化、高强度、复杂曲面造型方向迭代。作为后视镜生产的核心工艺装备,热弯模具的技术水平直接影响产…

2026年汽车后视镜热弯模具优选厂家,实力品牌大揭秘,铝行业精炼用热鼎盘,汽车后视镜热弯模具实力厂家排行 - 品牌推荐师

引言:行业现状与模具核心价值 随着新能源汽车与智能驾驶技术的快速发展,汽车后视镜的设计需求正从单一功能性向轻量化、高强度、复杂曲面造型方向迭代。作为后视镜生产的核心工艺装备,热弯模具的技术水平直接影响产…

12.1 全身动力学与任务空间控制:基于零空间投影的层级化任务实现

12.1 全身动力学与任务空间控制:基于零空间投影的层级化任务实现 12.1.1 引言:人形机器人全身控制的范式转变 传统工业机械臂的控制通常围绕单一的末端执行器任务(如轨迹跟踪)展开,其控制目标明确且自由度有限。然而,人形机器人是一个具有高度运动冗余(通常拥有30个以…

XMLHttpRequest 从入门到实战:GET/POST 请求完整案例

一、前言 在前后端分离开发模式中&#xff0c;AJAX 是实现页面无刷新数据交互的核心技术&#xff0c;而 XMLHttpRequest&#xff08;简称 XHR&#xff09;正是浏览器原生支持的 AJAX 底层 API。 相比于现代的 fetch 和 Axios&#xff0c;XMLHttpRequest 兼容性更好&#xff0…

XMLHttpRequest 从入门到实战:GET/POST 请求完整案例

一、前言 在前后端分离开发模式中&#xff0c;AJAX 是实现页面无刷新数据交互的核心技术&#xff0c;而 XMLHttpRequest&#xff08;简称 XHR&#xff09;正是浏览器原生支持的 AJAX 底层 API。 相比于现代的 fetch 和 Axios&#xff0c;XMLHttpRequest 兼容性更好&#xff0…

全栈分页方案:MyBatisPlus后端与Thymeleaf前端深度整合指南 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …