goredis常见基础命令
基本操作
//删除键
exists,err:= rdb.Exists(ctx,"key").Result()
if err!=nil{panic(err)
}
if exists>0{err = rdb.Del(ctx,"key").Err()if err!=nil{panic(err)}
}
string类型
//设置一个键值对
//0表示没有过期时间
err:=rdb.Set(ctx,"key1","value1",0).Err()//根据key获取value
value,err:=rdb.Get(ctx,"key1").Result()//设置一个key的值,并返回这个key的旧值
oldVal,err:=rdb.GetSet(ctx,"key1","newVal").Result()//如果key不存在,则设置这个key的值
err:=rdb.setNX(ctx,"key2","value2",0).Err()//批量查询key的值
vals,err:=rdb.MGet(ctx,"key1","key2").Result()//批量设置key的值
err := rdb.MSet(ctx,"key1","value1","key2","value2").Err()//针对一个key的数值进行递增操作,每次加1
val,err:=rdb.Incr(ctx,"key").Result()//IncrBy函数,可以指定每次递增多少
valBy,err:=rdb.IncrBy(ctx,"key",2).Result()//IncrByFloat函数,可以指定每次增长多少,加的是浮点数
valFloat,err := rdb.IncrByFloat(ctx,"key1",2.2).Result()//递减1
val,err := rdb.Decr(ctx,"key",2).Result()//递减指定的值
valBy,err:=rdb.DecrBy(ctx,"key",2).Result()//删除key
rdb.Del(ctx,"key")//删除多个key
err:=rdb.Del(ctx,"key1","key2","key3").Err()//设置过期时间
rdb.Expire(ctx,"key",2*time.Second)
Hash类型
//设置字段值
//添加重复的字段不会报错,只会覆盖
err:=rdb.HSet(ctx,"user_1","username","zhang").Err()//查询字段值
username,err:=rdb.HGet(ctx,"user_1","username").Result()//查询全部字段和值
data,err:=rdb.HGetAll(ctx,"user_1").Result()
//data是一个map类型,使用循环迭代输出
for field,val:=range data{fmt.Println(filed,val)
}//根据key和field字段,累加字段的数值
count, err := rdb.HIncrBy(ctx, "user_1", "count", 2).Result()
if err != nil {panic(err)
}
fmt.Println(count)//返回字段所有字段名
//keys是一个string数组
keys, err := rdb.HKeys(ctx, "user_1").Result()
if err != nil {panic(err)
}
fmt.Println(keys)//查询字段数量
size, err := rdb.HLen(ctx, "user_1").Result()
if err != nil {panic(err)
}
fmt.Println(size)//查询多个字段值
//vals是一个数组
vals, err := rdb.HMGet(ctx, "user_1", "username", "count").Result()
if err != nil {panic(err)
}
fmt.Println(vals)//批量设置字段值
data := make(map[string]interface{})
data["id"] = 1
data["username"] = "li"
//一次性保存多个hash字段值
err := rdb.HMSet(ctx, "key", data).Err()
if err != nil {panic(err)
}//如果field字段不存在,则设置hash的值
err := rdb.HSetNX(ctx, "key", "id", 100).Err()
if err != nil {panic(err)
}//删除字段
//删除不存在的字段不会报错
rdb.HDel(ctx, "key", "id")
//删除多个字段
rdb.HDel(ctx, "key", "id", "username")//检测字段名是否存在
f, err := rdb.HExists(ctx, "key", "id").Result()
if err != nil {panic(err)
}
if f {fmt.Println("存在")
} else {fmt.Println("不存在")
}
List
//插入一个数据
rdb.LPush(ctx, "key", "data1")//LPush支持一次插入任意个数据
err := rdb.LPush(ctx, "key", 1, 2, 3, 4, 5).Err()//当列表存在时才从左边插入插入
err := rdb.LPushX(ctx, "key", "sss").Err()//从列表的右边删除第一个数据,并返回删除的数据
val, err := rdb.RPop(ctx, "key").Result()
fmt.Println(val)//从右边插入数据
rdb.RPush(ctx, "key", "data1")//一次插入多个数据
err := rdb.RPush(ctx, "key", 1, 2, 3, 4, 5).Err()//当列表存在时从右边插入数据
err := rdb.RPushX(ctx, "key", "rVal").Err()//从列表的左边删除第一个数据,并返回
val, err := rdb.LPop(ctx, "key").Result()
fmt.Println(val)//返回列表的长度
val, err := rdb.LLen(ctx, "key").Result()
fmt.Println(val)//返回列表一个范围内的数据
//0到-1就是全部
vals, err := rdb.LRange(ctx, "key", 0, -1).Result()
fmt.Println(vals)//从列表的左边开始,删除第一个100
del, err := rdb.LRem(ctx, "key", 1, 100).Result()
fmt.Println(del)//如果有多个100,则从左边开始,删除前两个100
rdb.LRem(ctx, "key", 2, 100)//如果存在多个100,则从右边开始删除2个100
//第二个参数表示从右边开始删除几个等于100得元素
rdb.LRem(ctx, "key", -2, 100)//如果存在多个100,第二个参数为0,表示删除所有元素等于100得数据
rdb.LRem(ctx, "key", 0, 100)//根据索引查找对应元素,索引从0开始
val, err := rdb.LIndex(ctx, "key", 5).Result()//在列表中元素为5的前边加入4
err := rdb.LInsert(ctx, "Key", "before", 5, 4).Err()//只留下索引是0到2的
rdb.LTrim(ctx, "key1", 0, 2)
Set
无序集合元素不能重复
//添加100到集合中
err := rdb.SAdd(ctx, "key", 100).Err()
if err != nil {panic(err)
}//将100,200,300添加到集合中
//向集合中添加已经存在的元素将会报错
rdb.SAdd(ctx, "key", 100, 200, 300)//获取大小
size, err := rdb.SCard(ctx, "key").Result()
if err != nil {panic(err)
}
fmt.Println(size)//判断元素是否存在
ok, _ := rdb.SIsMember(ctx, "key", 100).Result()
if ok {fmt.Println("存在")
}//获取所有元素
es, _ := rdb.SMembers(ctx, "key").Result()
fmt.Println(es)//删除集合元素
//删除不存在的元素不会报错
rdb.SRem(ctx, "key", 100)//删除多个
rdb.SRem(ctx, "key", 200, 300)//随机返回集合中的元素,并删除
//val是随机删除的元素
val, _ := rdb.SPop(ctx, "key").Result()
fmt.Println(val)//随机删除多个
vals, _ := rdb.SPopN(ctx, "key", 3).Result()
fmt.Println(vals)
sorted set/zset
它为每个成员关联了一个分数(score),这个分数被用来对集合中的成员进行排序。虽然成员必须是唯一的,但是分数可以重复
l1 := redis.Z{Score: 1.0,Member: "zhang",
}
//添加元素,如果元素存在,则更新分数
err := rdb.ZAdd(ctx, "key", l1).Err()
if err != nil {panic(err)
}
err = rdb.ZAdd(ctx, "key", redis.Z{3.8, "zhang"}).Err()
if err != nil {panic(err)
}//返回元素个数
size, err := rdb.ZCard(ctx, "key").Result()
if err != nil {panic(err)
}
fmt.Println(size)//统计某个范围的元素个数
//范围[1,5]
size, err = rdb.ZCount(ctx, "key", "1", "5").Result()
if err != nil {panic(err)
}
fmt.Println(size)// 如果加上( 则表示大于或者小于,相当于去掉了等于关系。
size, err = rdb.ZCount(ctx, "key", "(1", "5").Result()
if err != nil {panic(err)
}
fmt.Println(size)//增加元素分数
rdb.ZIncrBy(ctx, "key", 2, "zhang")//返回全部数据
//元素按分数从小到大
vals, err := rdb.ZRange(ctx, "key", 0, -1).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val)
}//ZRevRange的结果是按分数从大到小排序
//根据分数范围返回集合元素,元素根据分数从小到大排序,支持分页
//初始化查询条件
op := redis.ZRangeBy{"1","10",0, // 类似sql的limit, 表示开始偏移量5, // 一次返回多少数据
}
vals, err = rdb.ZRangeByScore(ctx, "key", &op).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val)
}// ZRevRangeByScore用法类似ZRangeByScore,区别是元素根据分数从大到小排序。//返回元素和分数
vals, err = rdb.ZRangeByScoreWithScores(ctx, "key", &op).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val.Member)fmt.Println(val.Score)
}//删除集合元素
rdb.ZRem(ctx, "key", "zhang")//删除多个
rdb.ZRem(ctx, "key", "li", "wang")//根据索引范围删除元素
//删除第零个到第一个
rdb.ZRemRangeByRank(ctx, "key", 0, 1)//根据范围删除元素,"("和")"可以使用
rdb.ZRemRangeByScore(ctx, "key", "2", "5")//查询元素对应的分数
score, _ := rdb.ZScore(ctx, "key", "zhang").Result()
fmt.Println(score)//根据元素名,查询集合元素在集合中的排名,从0开始,从小到大
rk, _ := rdb.ZRank(ctx, "key", "zhang").Result()
fmt.Println(rk)
//ZRevRank是按分数从大到小排序
发布订阅
可用于消息的传输
三个部分:发布者,订阅者,Channel(频道)

发布者和订阅者是redis客户端,channel是redis服务端,发布者将消息发送到某个频道,订阅这个频道的订阅者就能接收到这条消息
Subscribe
订阅channel
// 订阅channel1这个channel
sub := rdb.Subscribe(ctx, "channel1")
// sub.Channel() 返回go channel,可以循环读取redis服务器发过来的消息
for msg := range sub.Channel() {// 打印收到的消息fmt.Println(msg.Channel)fmt.Println(msg.Payload)
}
//或者
for {msg, err := sub.ReceiveMessage(ctx)if err != nil {panic(err)}fmt.Println(msg.Channel, msg.Payload)
}
publish
将消息发送给指定的channel
rdb.Publish(ctx,"channel1","message")
PSubscribe
用法跟Subscribe一样,区别是PSubscribe订阅通道(channel)支持模式匹配。
// 订阅channel1这个channel
sub := rdb.PSubscribe(ctx,"ch_user_*")
// 可以匹配ch_user_开头的任意channel
Unsubscribe
取消订阅
// 订阅channel1这个channel
sub := rdb.Subscribe(ctx,"channel1")
// 取消订阅
sub.Unsubscribe(ctx,"channel1")
PubSubNumSub
查询指定的channel有多少个订阅者
// 查询channel_1通道的订阅者数量chs, _ := rdb.PubSubNumSub(ctx, "channel_1").Result()for ch, count := range chs {fmt.Println(ch) // channel名字fmt.Println(count) // channel的订阅者数量}
相关文章:
goredis常见基础命令
基本操作 //删除键 exists,err: rdb.Exists(ctx,"key").Result() if err!nil{panic(err) } if exists>0{err rdb.Del(ctx,"key").Err()if err!nil{panic(err)} }string类型 //设置一个键值对 //0表示没有过期时间 err:rdb.Set(ctx,"key1",…...
【Linux网络】序列化、守护进程、应用层协议HTTP、Cookie和Session
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、序列化和反序列化2、守护进程2.1 什么是进程组?2.2 什么是会话? 3、应用层协议HTTP3.1 HTTP协议3.2 HT…...
JavaScript函数-arguments的使用
在JavaScript编程语言中,函数是构建复杂逻辑和实现代码复用的关键组件。虽然现代JavaScript(尤其是ES6及之后版本)提供了更多灵活的方式来处理函数参数(如剩余参数、默认参数等),但arguments对象仍然是一个…...
Hadoop常用操作命令
在NameNode节点格式化集群 初始化集群 hdfs namenode -format启动HDFS sbin/start-dfs.sh启动yarn sbin/start-yarn.sh启动NodeManager yarn-daemon.sh start nodemanager启动DataNode hadoop-daemon.sh start datanode启动SecondaryNameNode hadoop-daemon.sh start se…...
system verilog的流操作符
流操作符,有分为操作对象是一整个数组和单独的数据两种,例如bit [7:0] a[4]和bit [31:0] b,前者操作对象是数组,后者是单独一个较大位宽的数。 流操作符有<<和>>,代表从右向左打包和从左向右打包。 打包的…...
LLM2CLIP论文学习笔记:强大的语言模型解锁更丰富的视觉表征
1. 写在前面 今天分享的一篇论文《LLM2CLIP: P OWERFUL L ANGUAGE M ODEL U NLOCKS R ICHER V ISUAL R EPRESENTATION》, 2024年9月微软和同济大学的一篇paper, 是多模态领域的一篇工作,主要探索了如何将大模型融合到Clip模型里面来进一步提…...
计算机毕业设计SpringBoot+Vue.jst网上超市系统(源码+LW文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
python-静态方法和类方法
Java之类的编程语言还带有静态方法,Python类也拥有与静态方法明确对应的方法。此外,Python还拥有类方法,要比静态方法更高级一些。 静态方法与Java一样,即便没有创建类的实例,静态方法也是可以调用的,当然…...
什么是手机9008模式?如何进入9008
之前给大家分享了一些有关手机刷机的知识,今天给大家讲一讲如果刷机过程中不慎变砖应该如何应对(当然了,希望大家都不会遇到)😂😄 在给手机 Root 或刷机时,线刷 9008 指的是利用 高通 9008 模式…...
嵌入式之指针
在嵌入式系统中指针是一种非常重要的概念。它们用于直接访问内存地址,能够提高程序的灵活性和效率。 一、基本概念 1. 指针的基本概念 定义:指针是一个变量,其值为另一个变量的地址。通过指针,可以间接访问和修改该变量的值。声…...
网络安全研究
1.1 网络安全面临的威胁 网络安全面临的威胁呈现出多样化和复杂化的趋势,给个人、企业和国家的安全带来了严峻挑战。以下是当前网络安全面临的主要威胁: 1.1.1 数据泄露风险 数据泄露是当前网络安全的重大威胁之一。根据国家互联网应急中心发布的《20…...
Git入门:数据模型 to 底层原理
版本控制系统(VCS)是软件开发中不可或缺的工具,而Git作为现代版本控制的事实标准,其底层设计远比表面命令更加优雅。本文将从数据模型的角度,揭示Git的核心工作原理。 Git的核心概念 1. 快照(Snapshot&am…...
openharmony中hdf框架的驱动消息机制的实现原理
openharmony中hdf框架的驱动消息机制的实现原理 在分析hdf框架时发现绕来绕去的,整体梳理画了一遍流程图,发现还是有点模糊甚至不清楚如何使用的,详细的每个点都去剖析细节又过于消耗时间,所以有时间便从功能应用的角度一块块的去…...
HTTP SSE 实现
参考: SSE协议 SSE技术详解:使用 HTTP 做服务端数据推送应用的技术 一句概扩 SSE可理解为:服务端和客户端建立连接之后双方均保持连接,但仅支持服务端向客户端推送数据。推送完毕之后关闭连接,无状态行。 下面是基于…...
二分图检测算法以及最大匹配算法(C++)
上一节我们学习了有向图中的最大连通分量. 本节我们来学习二分图. 二分图是一种特殊的图结构, 能够帮助我们高效地解决这些匹配和分配问题. 本文将带你了解二分图的基本概念, 判定方法, 最大匹配算法以及实际应用场景. 环境要求 本文所用样例在Windows 11以及Ubuntu 24.04上面…...
Keepalive基础
一。简介和功能 vrrp协议的软件实现,原生设计目的是为了高可用ipvs服务 功能: 1.基于vrrp协议完成地址流动 2.为vip地址所在的节点生成ipvs规则(在配置文件中预先定义) 3.为ipvs集群的各RS做健康状况检测 4.基于脚本调用接口…...
计算机毕业设计SpringBoot+Vue.jst0图书馆管理系统(源码+LW文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
【Java消息队列】应对消息丢失、重复、顺序与积压的全面策略
应对消息丢失、重复、顺序与积压的全面策略 引言kafka消息丢失生产者消费者重复消费顺序消费消息积压生产者消费者其他RabbitMQ消息丢失生产者事务机制,保证生产者发送消息到 RabbitMQ Server发送方确认机制,保证消息能从交换机路由到指定队列保证消息在 RabbitMQ Server 中的…...
AI大模型学习(三): LangChain(二)
Langchain构建聊天机器人 安装依赖 pip install langchain_community Chat History:它允许聊天机器人"记住"过去的互动,并在回应后续问题时考虑他们 代码 # 创建模型 from langchain_core.messages import HumanMessage from langchain_core.prompts import ChatP…...
apply的用法
apply 是一个在编程语言中常见的函数,它在不同的上下文和语言中有不同的用途。以下是 apply 在常见编程语言中的几种常见用法: 1. Python 中的 apply 方法 在 Python 中,apply 主要用于 pandas 库中的 DataFrame 或 Series 对象,…...
【论文解读】TransMLA: Multi-Head Latent Attention Is All You Need
论文链接 1. 论文背景与问题动机 现代大规模语言模型(LLM)在推理时往往遇到通信瓶颈,主要原因在于自注意力机制中需要缓存大量的 Key-Value(KV)对。例如,对于 LLaMA‑65B 这种模型,即使采用 8…...
CentOS 下安装和配置 HTTPD 服务的详细指南
CentOS 下安装和配置 HTTPD 服务的详细指南 CentOS 下安装和配置 HTTPD 服务的详细指南1. 环境准备2. 安装 HTTPD 服务2.1 更新系统2.2 安装 HTTPD2.3 启动 HTTPD 服务2.4 检查 HTTPD 服务状态 3. 配置防火墙3.1 开放 HTTP 和 HTTPS 端口3.2 验证防火墙规则 4. 配置 HTTPD4.1 主…...
VUE3中子组件改变父组件传过来的值(props)的方法和使用场景详解
在 Vue 3 中,子组件改变父组件传过来的值(props)的方法主要有以下几种:通过事件发射、使用 v-model、模拟 .sync 修饰符的功能(Vue 3 中已移除),以及使用 ref 或 reactive。下面我将结合代码示例…...
登录-06.JWT令牌-生成和校验
一.JWT令牌的生成和校验 JWT令牌生成 想要生成JWT令牌,那么就要首先引入JWT令牌的相关依赖, <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.2</version>…...
【Git】多人协作
文章目录 完成准备工作多人协作场景一场景二远程分支删除后,本地 git branch -a 依然能看到的解决办法 完成准备工作 在之前,我们所完成的工作如下: 基本完成 Git 的所有本地库的相关操作,git基本操作,分支理解&#…...
Python爬虫-破解字体加密技术
前言 本文是该专栏的第77篇,后面会持续分享python爬虫干货知识,记得关注。 字体加密是一种常见的反爬虫技术,通过自定义字体文件和字符映射来保护网页内容,防止爬虫直接获取文本信息。 在文章《Python爬虫-猫眼电影的影院数据》中,笔者有详细介绍过猫眼的相关数据采集。…...
邮件安全之发件人伪造
电子邮件工作原理 电子邮件传输过程中主要涉及到SMTP、IMAP、POP3三种协议,具体功能如下: SMTP:全称Simple Mail Transfer Protocol,即简单邮件传输协议,主要用于发送邮件,使用端口号25。 IMAP:全称Internet Mail Acce…...
git 常用功能
以下是 Git 的常用功能及其命令: 初始化仓库 git init在当前目录初始化一个新的 Git 仓库。 克隆仓库 git clone <仓库地址>将远程仓库克隆到本地。 查看状态 git status查看工作区和暂存区的状态。 添加文件到暂存区 git add <文件名>将文件添…...
【llm落地】从零到一,用DeepSeek打造智能BI工具:自然语言驱动数据洞察
在数据驱动的时代,商业智能 (BI) 工具已经成为企业决策的关键。然而,传统的 BI 工具往往操作复杂,需要专业技能才能驾驭。想象一下,如果用户只需要用 自然语言 就能轻松查询数据、获取分析结果甚至生成可视化图表,那将会多么高效和便捷! 本文将带你踏上从零到一构建智能…...
请谈谈 Vue 中的 key 属性的重要性,如何确保列表项的唯一标识?
1. Key属性的核心作用(附代码对比) // 错误示例:未使用key的列表渲染 <template><ul><li v-for"item in items">{{ item.text }}</li></ul> </template>// 正确示例:使用唯一key的…...
