用go写一个简单的Redis客户端框架

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 用go写一个简单的Redis客户端框架

本篇文章,我们将用go写一个Redis的客户端,其实主要还是探究RESP协议,如果你是第一次看本专栏文章,建议先看【用go实现Redis读写分离】 和 【Redis RESP协议实现起来到底有多简单】, 本篇文章的初衷也并不是真正写一个Redis客户端。主要还是探究通信协议。



demo展示


我们将该代码已经上传到了gitee,地址: gitee.com/pdudo/Redis…


package main
import (
  "fmt"
  "gitee.com/pdudo/RedisClient"
)
func main() {
  // 连接客户端
  client, err := RedisClient.Client("localhost:6379","123456",0)
  if err != nil {
    panic(err)
  }
  // Set
  // set name pdudo EX 60
  result , err := client.Set("name","pdudo","60","")
  if err != nil {
    fmt.Println("set 失败",err)
    return
  }
  fmt.Println("set 结果:",result)
  fmt.Println("\n")
  // Get
  // get name
  result , err = client.Get("name")
  if err != nil {
    fmt.Println("get 失败",err)
    return
  }
  fmt.Println("get 结果: " , result)
}


如上代码,我们连接到了本地Redis,并且设置了一个key,名称为name,值为pdudottl60秒,而后再查询了一下name的值,我们加了一些日志,我们来看下具体执行过程:

image.png


Redis RESP报文回顾


我们只要想和Redis服务器通信或者拆解命令,这个一定是绕不开的问题,因为很重要,本篇文章核心都是基于此,所以我们需要先回顾下。


RESP是专门为Redis而发明的通信协议,在Redis 1.2引入,并以Redis 2.0 成为Redis的默认通信协议。 该协议基于传输层TCP,默认端口为6379,支持5种类型: 数组、复杂字符串、数字、简单字符串以及错误数据。


我们列一个表格来说明数据类型以及其含义,最后再描述一下涉及面。

数据类型 含义 涉及面
* 数组 发送/接收
$ 复杂字符串 发送/接收
: 数字 接收
+ 简单正常输出 接收
- 错误输出 接收

我们注意到,若我们只用发送数据的话,我们直接使用*$2种数据就可以了。


关于这个点,我们手写一版协议就清楚了。


我们想向Redis服务器输入

set age 21

若我们将21使用数字类型代替的话,会出错,如:

image.png


若想正确输入的话,可以使用

image.png

如上就正确使用了set

而若是需要接收数据,则需要使用全部数据类型了。



如何发送数据


通过如上协议回顾,我们知晓,我们发送数据的时候,仅需要*$数据类型即可。 其中*是数字类型,代表有多少组数据,$是复杂字符串类型,表示字符串的长度。


set name pdudo使用RESP可以定义如下:

image.png


*3表示数组有3个数据,setnamepdudo

但是这些数据,不能直接发送,需要由$来指定一下长度,比如set,长度为3,则标识为$3,而pdudo则标识为$5


根据如上定义,我们将代码编写如下:

image.png


如上代码表示接收的数据中,先计算数组command的长度,且写入到[]byte中,接着再循环遍历command,最后计算每个v的长度,以复杂字符串的类型$写入到[]byte中。



如何接收数据


接收数据,我一直认为是整个协议实现中最难得,但是我最近找到了新方法,我们展开讲一下,我们先抛开数组类型不谈,我们面临的数据类型有这么几类:

数据类型 含义 涉及面
$ 复杂字符串 发送/接收
: 数字 接收
+ 简单正常输出 接收
- 错误输出 接收



其中,+-:数据类型,其值均在同一行上,例如:

+OK
-NOAUTH Authentication required.
:123

而复杂字符串$比较特殊,它数据长度定义是一行,而实际数据在下一行,例如:


image.png


$5
pdudo

基于如上特性,若没有数组类型的话,而一旦使用了数组,该协议报文中,就不可能出现+``-等数据类型,仅有$以及:,基于此我们很容易写出代码来:

image.png


如上代码,是获取$:数据类型的值,其中:数据就在该符号后面,而$则需要先获取复杂字符串的长度,而后再取相应的数据+最后的空行。


那我们现在还有3种数据类型没有编写,即: +-*,对于+-我们将当行取出来即可,对于*我们需要获取其值n,然后循环n次才能获取到数据。

image.png


我们再看获取数组函数的编写

image.png

即,重复的调用我们编写的第一个函数,将数据汇总到一起后,我们最后再返回回去。



总结


所谓的编写一个Redis客户端,其实还是玩转RESP协议,正所谓万变不离其宗,怎么样,好玩么? 快来使用go写一个专属你的Redis客户端吧。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
NoSQL Redis 数据安全/隐私保护
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
文章提供了Redis最流行的图形化界面工具Another Redis Desktop Manager的下载及使用教程,包括如何下载、解压、连接Redis服务器以及使用控制台和查看数据类型详细信息。
172 6
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
|
2月前
|
NoSQL Redis 数据库
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
文章提供了Redis图形化界面工具的下载及使用教程,包括如何连接本地Redis服务器、操作键值对、查看日志和使用命令行等功能。
165 0
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
|
16天前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
25天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
65 4
|
25天前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
66 1
|
2月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
64 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
2月前
|
NoSQL 网络协议 算法
Redis 客户端连接
10月更文挑战第21天
37 1
|
2月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
69 8
|
3月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
3月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例