golang实现简单的reids服务2
- golang实现redis兼容的redis服务
- 实现redis兼容的redis服务思路
golang实现redis兼容的redis服务
- 之前做的redis服务是通过tcp封装的自定义协议
原版项目地址:https://github.com/dengjiayue/my-redis.git
- 那么能不能实现一个redis兼容的redis服务,这样一般的redis包也可以调用我们写的redis服务了呢?
当然可以,需要实现redis的RESP通信协议
新版项目地址: https://github.com/dengjiayue/my-redis-v2.0-RESP-.git
实现redis兼容的redis服务思路
- 原本的数据处理模型不变,依旧使用单线程模型,map储存数据
- 实现RESP协议的支持就可以了
首先,我们需要知道redis一般收到的读写命令是什么样的去搞清楚RESP协议的原理
读
"*2\r\n$3\r\nget\r\n$4\r\nname\r\n"
写
"*3\r\n$3\r\nset\r\n$4\r\nname\r\n$8\r\nzhangsan\r\n"
RESP使用\r\n作为换行符
*2,*3表示命令的个数
一个命令包含前面一个命令数据的长度,比如$3 表示后面的数据长度为3; 然后在长度下一行才是数据;
一般第一个是方法名set,get什么的,第二个是key值,第三个是val值(如果是get就没有第三个),后面是过期时间什么的.
明白了工作原理我们就可以封装RESP协议支持了
- 根据换行符解析每一行数据
- 先解析第一行,获取整个请求的包含多少个命令
- 再解析每一个命令
- 先解析长度,再解析数据,
- 最后根据数据中的方法,key,val等消息做数据处理
- 封装返回:成功就返回“+{msg}\r\n”,msg为处理结果;失败就返回“-Err {msg}\r\n”,msg 为失败的信息
这样你就可以通过golang的redis包调用你的redis服务了
使用go-redis包做测试
import ("context""fmt""time""github.com/go-redis/redis/v8"
)// 新建连接池
func NewPool() *redis.Client {return redis.NewClient(&redis.Options{Addr: "localhost:8080",PoolSize: 1,MinIdleConns: 1,})
}// 写入redis
func WriteRedis(client *redis.Client) {ctx := context.Background()// 写入redisrsp, err := client.Set(ctx, "name", "tom", time.Minute).Result()if err != nil {panic(err)}fmt.Println(rsp)
}// 读取redis
func ReadRedis(client *redis.Client) {ctx := context.Background()// 读取redisrsp, err := client.Get(ctx, "name").Result()if err != nil {panic(err)}fmt.Println(rsp)
}func TestWriteRedis(t *testing.T) {type args struct {client *redis.Client}tests := []struct {name stringargs args}{// TODO: Add test cases.{"test", args{NewPool()}},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {WriteRedis(tt.args.client)})}
}func TestReadRedis(t *testing.T) {type args struct {client *redis.Client}tests := []struct {name stringargs args}{// TODO: Add test cases.{"test", args{NewPool()}},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {ReadRedis(tt.args.client)defer tt.args.client.Close()})}
}// 读写测试
func TestReadWriteRedis(t *testing.T) {type args struct {client *redis.Client}tests := []struct {name stringargs args}{// TODO: Add test cases.{"test", args{NewPool()}},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {WriteRedis(tt.args.client)ReadRedis(tt.args.client)defer tt.args.client.Close()})}
}// 读写测试
func TestReadWriteRedis(t *testing.T) {type args struct {client *redis.Client}tests := []struct {name stringargs args}{// TODO: Add test cases.{"test", args{NewPool()}},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {WriteRedis(tt.args.client)ReadRedis(tt.args.client)defer tt.args.client.Close()})}
}
读写结果
=== RUN TestReadWriteRedis
=== RUN TestReadWriteRedis/test
OK
tom
--- PASS: TestReadWriteRedis/test (0.00s)
--- PASS: TestReadWriteRedis (0.00s)
PASS
ok redis_performance_test/go_redis_read_write 0.756s
仓库地址: https://github.com/dengjiayue/my-redis-v2.0-RESP-.git
相关文章:
golang实现简单的reids服务2
golang实现redis兼容的redis服务实现redis兼容的redis服务思路 golang实现redis兼容的redis服务 之前做的redis服务是通过tcp封装的自定义协议 原版项目地址:https://github.com/dengjiayue/my-redis.git 那么能不能实现一个redis兼容的redis服务,这样一般的redis包也可以调…...
跟李笑来学美式俚语(Most Common American Idioms): Part 67
Most Common American Idioms: Part 67 前言 本文是学习李笑来的Most Common American Idioms这本书的学习笔记,自用。 Github仓库链接:https://github.com/xiaolai/most-common-american-idioms 使用方法: 直接下载下来(或者clone到本地…...
QT 中 QDateTime::currentDateTime() 输出格式备查
基础 QDateTime::currentDateTime() //当前的日期和时间。 QDateTime::toString() //以特定的格式输出时间,格式 yyyy: 年份(4位数) MM: 月份(两位数,07表示七月) dd: 日期(两位数,…...
安卓手机怎么轻松转换更新ip网络地址
随着移动互联网的快速发展,IP地址作为网络身份标识的重要性日益凸显。对于安卓手机用户来说,但有时候我们希望能够轻松转更换ip地址,以提高网络安全性或访问特定内容的需要。那么,安卓手机如何更换IP地址呢?本文将为您…...
spring项目添加本地依赖,报java程序包不存在
删除引入程序中的iml文件 重新在当前项目目录下构建项目...
嵌入式硬件-- 元器件焊接
1.锡膏的使用 锡膏要保存在冰箱里。 焊接排线端子;138度的低温锡(锡膏), 第一次使用,直接拿东西挑一点涂在引脚上,不知道多少合适,加热台加热到260左右,放在上面观察锡融化&#…...
物联网入门-Arduino的下载与配置教程(以ESP32为例)-2024
教程介绍 本次教程主要讲述如何下载与配置Arduino,以及开发版对应驱动的下载安装 原文链接:物联网入门-Arduino的下载与配置教程(以ESP32为例)-2024 步骤概述 1:下载Arduino 2:安装Arduino 3:下载安装驱动 4&am…...
防火墙旁挂部署+故障切换
一、实验环境 华为ENSP 二、拓扑 三、目的 1、内网PC1访问Server 2、防火墙旁挂部署,对流量进行过滤,防火墙挂掉之后,内网PC1能继续访问到Server 3、防火墙恢复正常后,流量能回切至防火墙转发 四、思路: 1、AR1…...
PyTorch基本使用-张量的基本运算及函数计算
文章目录 1. 张量数值计算1. 1 张量基本运算1.2 点乘运算1.3 矩阵运算 2. 张量运算函数 1. 张量数值计算 1. 1 张量基本运算 加减乘除取负号: add、sub、mul、div、neg add_ 、sub_、 mul_ 、div_、 neg_ (其中带下划线的版本会修改原数据) data torch.randin…...
C#--方法
C#的代码包装 三种实现途径:方法、类和名字空间。 • 方法是包含一系列语句的代码块。 • 类用于组合类,方法,属性。 • 将多个相关类组合成名字空间。 静态方法和静态变量 • 静态成员 在类中,使用static修饰符声明的成员称为静态…...
前端权限控制
前端权限控制 一、路由权限(控制页面访问) vue // router.js const routes [{path: /dashboard,name: Dashboard,component: () > import(/views/Dashboard.vue),meta: { requiresAuth: true, roles: [admin, manager] }},{path: /user,name: Use…...
mac下载安装jdk
背景 长时间不折腾mac全部忘记 特此记录 安装 1.下载jdk 根据需要下载对应的jdk 我直接 下载到/Applicatiions目录 https://www.oracle.com/java/technologies/downloads/#java8-mac 2.解压 cd /Applicatiions tar -zxvf jdk-8u431-macosx-x64.tar.gz 3.配置环境 …...
在线PS工具:UI设计的创新选择
对于刚踏入UI设计领域的新手来说,选择合适的在线Photoshop替代工具是至关重要的。市场上存在众多的在线设计工具,让人难以抉择。以下是10个值得尝试的在线PS工具,希望能帮助你找到最适合你的那一款。 Adobe Photoshop Photoshop是设计师们长…...
生成式AI概览与详解
1. 生成式AI概览:什么是大模型,大模型应用场景(文生文,多模态) 生成式AI(Generative AI)是指通过机器学习模型生成新的数据或内容的人工智能技术。生成式AI可以生成文本、图像、音频、视频等多种…...
数据结构与算法学习笔记----树与图的深度优先遍历
数据结构与算法学习笔记----树与图的深度优先遍历 author: 明月清了个风 first publish time: 2024.12.9 pa⭐️这里只有一道题哈哈。 Acwing 846.树的重心 给定一棵树,树中包含 n n n个节点(编号 1 ∼ n 1 \sim n 1∼n)和 n − 1 n - 1 n…...
IEEE T-RO 软体机器人手指状态估计实现两栖触觉传感
摘要:南方科技大学戴建生院士、林间院士、万芳老师、宋超阳老师团队近期在IEEE T-RO上发表了关于软体机器人手指在两栖环境中本体感知方法的论文。 近日,南方科技大学戴建生院士、林间院士、万芳老师、宋超阳老师团队在机器人顶刊IEEE T-RO上以《Propri…...
【NLP 14、激活函数 ② tanh激活函数】
学会钝感力,走向美好的方向 —— 24.12.11 一、tanh激活函数 1. tanh函数的定义 tanh是双曲正切函数(Hyperbolic Tangent),数学表达式为 其函数图像是一个S型曲线,以原点 (0,0) 为中心对称,定…...
前端如何实现签名功能
1.JS实现 前端实现签名功能,通常是通过在页面上创建一个可绘制的区域,用户可以用鼠标或触摸设备进行签名。这个区域通常是一个<canvas>元素,结合JavaScript来处理绘制和保存签名。下面是一个简单的实现步骤: 1.1. 创建HTM…...
若依将数据库更改为SQLite
文章目录 1. 添加依赖项2. 更新配置文件 application-druid.yml2.1. 配置数据源2.2. 配置连接验证 3. 更新 MybatisPlusConfig4. 解决 mapper 中使用 sysdate() 的问题4.1. 修改 BaseEntity4.2. 修改 Mapper 5. 更新 YML 配置 正文开始: 前提条件:在您的…...
CRMEB Pro版v3.2源码全开源+PC端+Uniapp前端+搭建教程
一.介绍 crmeb pro版 v3.2正式发布,全新UI重磅上线,焕然一新,不负期待!页面DIY设计功能全面升级,组件更丰富,样式设计更全面;移动端商家管理,让商城管理更便捷,还从页面…...
Docker 安装 Jenkins:2.346.3
准备:已安装Docker,已配置服务器安全组规则 1581 1、拉取镜像 [rootTseng ~]# docker pull jenkins/jenkins:2.346.3 2.346.3: Pulling from jenkins/jenkins 001c52e26ad5: Pull complete 6b8dd635df38: Pull complete 2ba4c74fd680: Pull complet…...
【OpenCV】模板匹配
理论 模板匹配是一种在较大图像中搜索和查找模板图像位置的方法。为此,OpenCV 带有一个函数 cv.matchTemplate() 。它只是在输入图像上滑动模板图像(如在 2D 卷积中),并比较模板图像下的模板和输入图像的补…...
黑马商城微服务复习(5)
MQ 一、同步调用和异步调用1. 同步调用2. 异步调用 二、RabbitMQ1. 基础使用2. 实际操作 怎么用?3. RabbitMQ虚拟主机 数据隔离4. 在JAVA中实现RabbitMQ5. 交换机种类 一、同步调用和异步调用 1. 同步调用 微服务一旦拆分,必然涉及到服务之间的相互调用ÿ…...
云原生基础设施指南:精通 Kubernetes 核心与高级用法
1. 云原生的诞生 随着互联网规模的不断增长,以及企业对敏捷开发、快速交付和高可用性的需求日益增强,传统的单体架构逐渐暴露出局限性,难以满足现代业务对动态扩展和高效迭代的要求。为此,云原生应运而生。 云原生是为云计算时代…...
人工智能概要
目录 前言1.什么是人工智能(Artificial Intelligence, AI)2.人工智能发展的三次浪潮2.1 人工智能发展的第一次浪潮2.2 人工智能发展的第二次浪潮2.3 人工智能发展的第三次浪潮 3.人工智能发展的必备三要素3.1 数据3.2 算法(algorithm…...
qt QCommandLineParser详解
1、概述 QCommandLineParser是Qt框架中提供的一个类,专门用于解析命令行参数。它简化了命令行参数的处理过程,使得开发者能够轻松定义、解析和验证命令行选项和参数。QCommandLineParser适用于需要从命令行获取输入的控制台应用程序,以及需要…...
力扣 K个一组翻转链表
K个一组翻转链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(ne…...
cnocr配置及训练测试
cnocr配置及训练测试 1,相关链接2,已有模型调用测试(1)下载相关模型(2)Cnstd文本检测模型(3)模型调用解析脚本 3,自定义数据集训练测试(1)标签转换…...
解决 Flutter 在 Mac 上的编译错误
解决 Flutter 在 Mac 上的编译错误 在使用 Flutter 进行项目开发并尝试在 Mac 设备上进行编译时,遇到了一系列的错误信息,这些错误信息给项目的构建与部署带来了阻碍。 一、错误详情 在编译过程中,Xcode 输出了大量的信息,其中…...
MR30分布式IO在新能源领域加氢站的应用
导读 氢能被誉为21世纪最具发展潜力的清洁能源,氢能科技创新和产业发展持续得到各国青睐。氢能低碳环保,燃烧的产物只有水,是用能终端实现绿色低碳转型的重要载体。氢能产业链分别为上游制氢、中游储运以及下游用氢。上游制氢工艺目前大部分…...
太原网站建设哪家好/成都网站seo设计
常用功能命令1.导出整个数据库1mysqldump -u 用户名 -p –default-character-setlatin1 数据库名 > 导出的文件名(数据库默认编码是latin1)23mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql2.导出一个表1mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名23mysql…...
网站空间怎么登陆/网络推广有前途吗
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼br0 Link encap:Ethernet HWaddr D2:23:4A:E2:84:84inet addr:192.168.1.130 Bcast:192.168.1.255 Mask:255.255.255.0inet6 addr: fe80::d023:4aff:fee2:8484/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX p…...
网站建设方案书安全性/网站建设策划书范文
一、认识Web.config文件 Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中。当你通过VB.NET新建一个Web应用…...
颍东网站建设/北京seo软件
请用C语言实现 输出和为一个给定整数的所有组合启动2012/*请用C语言实现 输出和为一个给定整数的所有组合 */#include <stdio.h> //包含头文件stdio.h 为程序提供基本输入输出功能 #include <stdlib.h> //包含标准库头文件stdlib.h 以便调用函数system("pa…...
宁波免费做网站/宁波seo优化公司
绘制环境 getContext(2d):目前只支持2d场景不能在样式里设置宽高,否则变成等比缩放(包括里面画的内容也会等比缩放) 复制代码 绘制图形: 绘制方块:fillRect(L,T,W,H); 填充的方块strokeRect(L,T,W,H); 带边…...
电子名片制作app/seo 优化一般包括哪些内容
开头 对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。 那到底应该怎么学习并…...