当前位置: 首页 > news >正文

Go go-redis应用

go-redis 是 Go 语言的一个流行的 Redis 客户端库,它提供了丰富的功能来与 Redis 数据库进行交互。 

1、简单应用 

package mainimport ("context""fmt""log""github.com/redis/go-redis/v9"
)func main() {ctx := context.Background()rdb := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "", // no password setDB:       0,  // use default DB})// 设置值err1 := rdb.Set(ctx, "your_key1", "your_value1", 0).Err()if err1 != nil {log.Fatalf("无法设置键值: %v", err1)}// 获取值val, _ := rdb.Get(ctx, "your_key1").Result()fmt.Println("your_key1: ", val)err2 := rdb.LPush(ctx, "your_key2", 111, 222, 333, "444").Err()if err2 != nil {log.Fatalf("无法推送到列表: %v", err2)}// 循环处理邮件队列for {// 从 Redis 队列中获取邮件email, err := rdb.RPop(ctx, "your_key2").Result()if err == redis.Nil {// 队列为空,退出循环fmt.Println("电子邮件队列为空。")break} else if err != nil {log.Fatalf("无法从队列中获取电子邮件: %v", err)} else {fmt.Println(email)}}
}

2、连接池管理

使用 go-redis 可以方便地管理 Redis 连接池,确保高效的连接复用。 

package mainimport ("context""fmt""github.com/redis/go-redis/v9"
)func main() {var ctx = context.Background()// 创建一个新的 Redis 客户端client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,PoolSize: 10, // 设置连接池大小})// 使用客户端pong, err := client.Ping(ctx).Result()if err != nil {panic(err)}fmt.Println(pong) // 输出 PONG
}

3、管道和事务

go-redis 支持管道(pipelines)和事务(transactions),可以批量执行命令,减少网络往返次数。 

事务(Transactions)

事务在 Redis 中用来执行一系列命令,这些命令被打包在一起,然后一起执行。如果在执行过程中遇到错误,整个事务将被取消。事务可以保证操作的原子性。

package mainimport ("context""fmt""github.com/redis/go-redis/v9"
)func main() {var ctx = context.Background()// 创建 Redis 客户端client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,})// 检查连接pong, err := client.Ping(ctx).Result()if err != nil {fmt.Printf("连接失败: %v", err)return}fmt.Printf("连接成功: %s\n", pong)key1 := "key1"key2 := "key2"// 使用 WATCH 命令监视键err = client.Watch(ctx, func(tx *redis.Tx) error {// 事务中的命令// SetNX函数:当该键不存在时才设置。如果键已经存在,命令将不执行任何操作。第三个参数为设置过期时间,0表示永不过期k1, err := tx.SetNX(ctx, key1, "value1", 0).Result() // 仅当 key1 不存在时设置值if err != nil {return err}if k1 {fmt.Println("key1 设置成功")} else {fmt.Println("key1 已存在,未进行设置操作")}k2, err := tx.SetNX(ctx, key2, "value2", 0).Result() // 仅当 key2 不存在时设置值if err != nil {return err}if k2 {fmt.Println("key2 设置成功")} else {fmt.Println("key2 已存在,未进行设置操作")}// 使用 MULTI 命令开始事务pipe := tx.Pipeline()// 将命令添加到事务队列_, err = pipe.Set(ctx, key1, "value1", 0).Result()if err != nil {return err}_, err = pipe.Set(ctx, key2, "value2", 0).Result()if err != nil {return err}// 使用 EXEC 命令执行事务_, err = pipe.Exec(ctx)if err != nil {return err}return nil}, key1, key2)if err != nil {if err == redis.TxFailedErr {fmt.Println("事务失败,可能因为键被其他客户端修改")} else {fmt.Printf("发生错误: %v", err)}return}// 如果事务成功,获取 key1 和 key2 的值val1, err := client.Get(ctx, key1).Result()if err != nil {fmt.Printf("获取 key1 失败: %v", err)return}val2, err := client.Get(ctx, key2).Result()if err != nil {fmt.Printf("获取 key2 失败: %v", err)return}fmt.Printf("key1: %s, key2: %s\n", val1, val2)
}

使用 Watch 方法监视了两个键 "key1""key2"。在 Watch 的回调函数中,我们尝试设置这两个键的值,如果设置成功,我们使用 Pipeline 方法将设置操作添加到事务队列中。最后,我们使用 Exec 方法提交事务。

请注意,如果 "key1""key2" 在我们设置它们之前已经被其他客户端设置,那么事务将不会执行,并且 Watch 方法将返回 redis.TxFailedErr 错误。在实际应用中,你可能需要根据这个错误来决定是否重试事务。

 事务&管道

package mainimport ("context""fmt""github.com/redis/go-redis/v9"
)func main() {var ctx = context.Background()// 创建一个新的 Redis 客户端client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,PoolSize: 10, // 设置连接池大小})// 假设我们想检查并更新的key以及期望的旧值和新值key := "mykey"oldValue := "expectedOldValue"newValue := "newValue"// 事务:使用 MULTI 和 EXEC 命令保证操作的原子性err := client.Watch(ctx, func(tx *redis.Tx) error {// 在事务中获取key的值val, err := tx.Get(ctx, key).Result()if err != nil && err != redis.Nil {return err}// 检查值是否与预期相符if val == oldValue {// 如果相符,尝试更新值_, err := tx.Set(ctx, key, newValue, 0).Result()if err != nil {return err}fmt.Println("更新成功")return nil} else {fmt.Println("键存在,值与预期值不匹配。")return nil // 这里返回nil表示不执行任何操作,事务会因为没有EXEC调用而自动取消}}, key)if err != nil {panic(err)}// 管道:批量发送命令cmds, err := client.Pipelined(ctx, func(pipe redis.Pipeliner) error {pipe.Set(ctx, "key1", "value1", 0)pipe.Get(ctx, "key1")return nil})if err != nil {panic(err)}fmt.Println(cmds) // 输出 [SetResult(string) <nil>, StringResult(value1, nil)]
}

4、发布/订阅模式

发布:

package mainimport ("context""fmt""github.com/redis/go-redis/v9""time"
)func main() {client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,})ctx := context.Background()// 发送消息的循环for {err := client.Publish(ctx, "my_channel", "Hello, Redis!").Err()if err != nil {fmt.Printf("发布消息失败: %v\n", err)return}fmt.Println("消息发布成功")// 每5秒发布一条消息time.Sleep(5 * time.Second)}
}

 订阅:

package mainimport ("context""fmt""github.com/redis/go-redis/v9""log""os""os/signal"
)func main() {// 创建 Redis 客户端client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,})ctx := context.Background()// 订阅频道pubsub := client.Subscribe(ctx, "my_channel")// 处理接收到的消息go func() {defer func() {if err := pubsub.Close(); err != nil {log.Printf("关闭订阅失败: %v", err)}}()for {msg, err := pubsub.ReceiveMessage(ctx)if err != nil {log.Printf("接收消息失败: %v", err)return}fmt.Printf("接收到消息: %s\n", msg.Payload)}}()// 等待中断信号以退出sigChan := make(chan os.Signal, 1)signal.Notify(sigChan, os.Interrupt)<-sigChanfmt.Println("正在关闭订阅...")
}
package mainimport ("context""github.com/redis/go-redis/v9""log""os""os/signal""syscall""time"
)var ctx = context.Background()func main() {// 创建 Redis 客户端client := redis.NewClient(&redis.Options{Addr:     "localhost:6379",Password: "",DB:       0,})if err := client.Ping(ctx).Err(); err != nil {log.Fatalf("无法连接到 Redis: %v", err)}// 启动订阅者go runSubscriber(client)// 发布者循环发送消息runPublisher(client)// 等待中断信号以优雅退出quit := make(chan os.Signal, 1)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quitlog.Println("接收到退出信号,正在关闭...")if err := client.Close(); err != nil {log.Fatalf("关闭 Redis 客户端失败: %v", err)}
}func runSubscriber(client *redis.Client) {pubsub := client.Subscribe(ctx, "my_channel")defer func() {if err := pubsub.Close(); err != nil {log.Printf("关闭订阅失败: %v", err)}}()log.Println("订阅者启动,正在监听消息...")for {msg, err := pubsub.ReceiveMessage(ctx)if err != nil {log.Printf("接收消息失败: %v", err)return}log.Printf("接收到消息: %s\n", msg.Payload)}
}func runPublisher(client *redis.Client) {ticker := time.NewTicker(5 * time.Second)defer ticker.Stop()log.Println("发布者启动,将定时发送消息...")for {select {case <-ticker.C:err := client.Publish(ctx, "my_channel", "Hello, Redis!").Err()if err != nil {log.Printf("发布消息失败: %v", err)return}log.Println("消息发布成功")}}
}

 

相关文章:

Go go-redis应用

go-redis 是 Go 语言的一个流行的 Redis 客户端库&#xff0c;它提供了丰富的功能来与 Redis 数据库进行交互。 1、简单应用 package mainimport ("context""fmt""log""github.com/redis/go-redis/v9" )func main() {ctx : context…...

从混乱到有序:PDM系统如何优化物料编码

在现代制造业中&#xff0c;物料管理是企业运营的核心。物料编码作为物料管理的基础&#xff0c;对于确保物料的准确性、唯一性和高效性至关重要。随着产品种类的不断增加和产品变型的多样化&#xff0c;传统的物料编码管理方式已经不能满足企业的需求。本文将探讨产品数据管理…...

npm发布自己的插件包

要发布自己的插件包到npm&#xff0c;可以按照以下步骤进行操作: 1.创建一个新项目 首先确保你已经安装了Node.js和npm。然后&#xff0c;在你的项目目录中初始化一个新的npm项目&#xff1a;npm init命令会引导你创建一个package.json文件&#xff0c;其中包含你插件包的基本…...

Pygame:新手指南与入门教程

在游戏开发领域,pygame 是一个广受欢迎的 Python 库,它提供了开发二维游戏的丰富工具和方法。这个库让开发者可以较少地关注底层图形处理细节,更多地专注于游戏逻辑和玩法的实现。本文将详细介绍 pygame,包括其安装过程、基本概念、主要功能和一个简单游戏的开发流程。 一…...

动态IP与静态IP的优缺点

在网络连接中&#xff0c;使用动态和静态 IP 地址取决于连接的性质和要求。静态 IP 地址通常更适合企业相关服务&#xff0c;而动态 IP 地址更适合家庭网络。让我们来看看动态 IP 与静态 IP 的优缺点。 1.静态IP的优点&#xff1a; 更好的 DNS 支持&#xff1a;静态 IP 地址在…...

上海市计算机学会竞赛平台2024年1月月赛丙组最大的和

题目描述 给定两个序列 &#x1d44e;1,&#x1d44e;2,…,&#x1d44e;&#x1d45b;a1​,a2​,…,an​ 与 &#x1d44f;1,&#x1d44f;2,…,&#x1d44f;&#x1d45b;b1​,b2​,…,bn​&#xff0c;请从这两个序列中分别各找一个数&#xff0c;要求这两个数的差不超过给…...

C++三大特性之继承,详细介绍

阿尼亚全程陪伴大家学习~ 前言 每个程序员在开发新系统时&#xff0c;都希望能够利用已有的软件资源&#xff0c;以缩短开发周期&#xff0c;提高开发效率。 为了提高软件的可重用性(reusability)&#xff0c;C提供了类的继承机制。 1.继承的概念 继承&#xff1a; 指在现有…...

Python推导式详解

引言 推导式&#xff08;Comprehensions&#xff09;是Python中一种简洁且强大的语法结构&#xff0c;可以用来生成列表、字典和集合。推导式使得代码更加简洁、易读&#xff0c;同时也更具Pythonic风格。今天我将将详细介绍列表推导式、字典推导式和集合推导式&#xf…...

stm32中如何实现EXTI线 0 ~ 15与对应IO口的配置呢?

STM32的EXTI控制器支持19 个外部中断/ 事件请求。每个中断设有状态位&#xff0c;每个中断/ 事件都有独立的触发和屏蔽设置。 STM32的19个外部中断对应着19路中断线&#xff0c;分别是EXTI_Line0-EXTI_Line18&#xff1a; 线0~15&#xff1a;对应外部 IO口的输入中断。 线16&…...

Python 短文本匹配,短文本语义相似度,基于大模型的短文本匹配,基于LLMs的短文本语义相似度识别,短文本语义扩充和匹配

1.任务描述 之前在做疾病相似度匹配的时候&#xff0c;堪称史诗级难题&#xff0c;虽然最后加上规则以及一些nlp模型&#xff0c;取得了差强人意的效果&#xff0c;但是短文本的语义相似度匹配一直属于比较难以攻克的难题 2.思路 随着近年大模型的飞速发展&#xff0c;就之前…...

提升接口性能方式汇总

1&#xff0c;sql 2&#xff0c;缓存&#xff0c;尤其面向用户&#xff0c;如app数据。可用redis咖啡&#xff0c;二级缓存。 充分利用redis&#xff0c;redis数据类型很多&#xff0c;平时场景中结合实际情况&#xff0c;找一下对应的redis实现方案 比如Zset可以排序&#…...

C++中的常见语法糖汇总

C中的语法糖是指使代码更简洁、可读性更高的语言特性和简化的语法。以下是一些常见的C语法糖&#xff1a; 1. 自动类型推导&#xff08;auto&#xff09; 使用 auto 关键字可以让编译器自动推导变量的类型&#xff0c;简化变量的声明。 auto x 10; // 编译器推导 x…...

TensorFlow Playground神经网络演示工具使用方法详解

在现代机器学习领域,神经网络无疑是一个重要的研究方向。然而,对于许多初学者来说,神经网络的概念和实际操作可能显得相当复杂。幸运的是,TensorFlow Playground 提供了一个交互式的在线工具,使得我们可以直观地理解和实验神经网络的基本原理。在这篇博客中,我们将详细介…...

【git】subtree 简单教程

git subtree使用案例 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0c;欢迎指正&am…...

C语言基础:字符串函数使用与剖析

strtok&#xff08;分割字符串&#xff09; char * strtok ( char * str, const char * sep ); sep参数是个字符串&#xff0c;定义了用作分隔符的字符集合 第一个参数指定一个字符串&#xff0c;它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记。strtok函数找…...

搭建Vulnhub靶机网络问题(获取不到IP)

搭建好靶场后&#xff0c;在攻击机运行arp-scan -l无法发现靶机IP。 这时候去看下靶机网络有没有问题。 重新启动客户机&#xff0c;一直按e进入安全模式&#xff08;要是直接开机了就先按shift进入grub界面&#xff0c;再按e&#xff09;找到ro&#xff0c;将ro改为rw signie…...

Prompt 提示词强大方法论和框架2

自从ChatGPT Chat Generative Pre-trained Transformer于2022年11月30日发布以来&#xff0c;一个新兴的行业突然兴起&#xff0c; 那就是提示工程Prompt engineering&#xff0c;可谓如日冲天。 从简单的文章扩写到RAG&#xff0c;ChatGPT展现了前所未有的惊人能力。 在上一…...

C语言分支和循环(2)

我的相关博客&#xff1a; C语言的分支与循环&#xff08;1&#xff09; 1.switch语句 除了 if 语句外&#xff0c;C语⾔还提供了 switch 语句来实现分⽀结构。 switch 语句是⼀种特殊形式的 的 if...else 结构&#xff0c;⽤于判断条件有多个结果的情况。它把多重 else if…...

14.FreeRTOS 流媒体缓存 Stream Buffer

FreeRTOS 中的 Stream Buffer&#xff08;流媒体缓存&#xff09; 在实时操作系统&#xff08;RTOS&#xff09;中&#xff0c;处理流媒体数据是一项非常关键的任务。FreeRTOS 提供了一种名为 Stream Buffer&#xff08;流媒体缓存&#xff09;的机制&#xff0c;用于高效地管…...

利用ffmpeg把视频分解成图片(每秒x张图)再图片合成视频

1. 视频分解成图片 ffmpeg -i rawVideo.mp4 -r 5 -f image2 img/%04d.png-i rawVideo.mp4 输入文件 -r 5 每秒5帧(1秒5张图) 可不写&#xff0c;默认每秒24帧 -f image2 表示输出的格式图像 可不写&#xff0c;默认图像 img/ 图片放在img文件夹下 %04d.png 图片的命名…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...