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

go 集成go-redis 缓存操作

一、什么是Go Redis

这是一个流行的Go语言Redis客户端库,它提供了细化的API,对每个Redis命令的功能进行了封装,使得用户只需记住命令,具体的用法可以直接查看接口的声明,使用成本较低。go-redis对数据类型按照Redis底层的类型进行统一,编译时可以帮助检查参数类型,并且它的响应统一采用Result的接口返回,确保了返回参数类型的正确性,对用户更加友好。此外,go-redis还支持连接池、Pipeline和事务,以及发布订阅Pub/Sub和键空间通知等功能。

二、go-redis特性

  • 多种客户端

支持单机Redis Server、Redis Cluster、Redis Sentinel、Redis分片服务器

  • 数据类型

go-redis会根据不同的redis命令处理成指定的数据类型,不必进行繁琐的数据类型转换

  • 功能完善

go-redis支持管道(pipeline)、事务、pub/sub、Lua脚本、mock、分布式锁等功能

三、安装go-redis

go-redis/v9 (支持所有的 redis 版本)

go get github.com/redis/go-redis/v9

四、连接配置

go-redis支持多种连接方式,这里只展示一种

func InitRedis() *redis.Client {rdb := redis.NewClient(&redis.Options{Addr:     viper.GetString("db.redis.addr"),Password: viper.GetString("db.redis.pwd"), // 没有密码,默认值DB:       viper.GetInt("db.redis.db"),     // 默认DB 0})return rdb
}

五、入门

Context 上下文

go-redis 支持 Context,你可以使用它控制 超时 或者传递一些数据, 也可以 监控 go-redis 性能。

ctx := context.Background()

执行 Redis 命令

val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)// 你也可以分别访问值和错误:get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())

执行尚不支持的命令

可以使用 Do() 方法执行尚不支持或者任意命令:

val, err := rdb.Do(ctx, "get", "key").Result()
if err != nil {if err == redis.Nil {fmt.Println("key does not exists")return}panic(err)
}
fmt.Println(val.(string))

Do() 方法返回 Cmd 类型,你可以使用它获取你想要的类型:

// Text is a shortcut for get.Val().(string) with proper error handling.
val, err := rdb.Do(ctx, "get", "key").Text()
fmt.Println(val, err)

方法列表:

s, err := cmd.Text()
flag, err := cmd.Bool()num, err := cmd.Int()
num, err := cmd.Int64()
num, err := cmd.Uint64()
num, err := cmd.Float32()
num, err := cmd.Float64()ss, err := cmd.StringSlice()
ns, err := cmd.Int64Slice()
ns, err := cmd.Uint64Slice()
fs, err := cmd.Float32Slice()
fs, err := cmd.Float64Slice()
bs, err := cmd.BoolSlice()

redis.Nil

redis.Nil 是一种特殊的错误,严格意义上来说它并不是错误,而是代表一种状态,例如你使用 Get 命令获取 key 的值,当 key 不存在时,返回 redis.Nil。在其他比如 BLPOP 、 ZSCORE 也有类似的响应,你需要区分错误:

val, err := rdb.Get(ctx, "key").Result()
switch {
case err == redis.Nil:fmt.Println("key不存在")
case err != nil:fmt.Println("错误", err)
case val == "":fmt.Println("值是空字符串")
}

Conn

redis.Conn 是从连接池中取出的单个连接,除非你有特殊的需要,否则尽量不要使用它。你可以使用它向 redis 发送任何数据并读取 redis 的响应,当你使用完毕时,应该把它返回给 go-redis,否则连接池会永远丢失一个连接。

cn := rdb.Conn(ctx)
defer cn.Close()if err := cn.ClientSetName(ctx, "myclient").Err(); err != nil {panic(err)
}name, err := cn.ClientGetName(ctx).Result()
if err != nil {panic(err)
}
fmt.Println("client name", name)

连接池大小

go-redis 底层维护了一个连接池,不需要手动管理。默认情况下, go-redis 连接池大小为 runtime.GOMAXPROCS * 10,在大多数情况下默认值已经足够使用,且设置太大的连接池几乎没有什么用,可以在 配置项 中调整连接池数量:

rdb := redis.NewClient(&redis.Options{PoolSize: 1000,
})

超时

如果你使用 context.Context 处理超时,但也不要禁用 DialTimeout 、ReadTimeout 和 WriteTimeout ,因为 go-redis 会在不使用 context.Context 的情况下执行一些后台检查,这些检查依赖这些超时配置项。

请注意:net.Conn 依赖 Deadline 而不是 ctx 。

context.Context 的超时时间不要设置太短,因为当 context.Context超时,连接池无法确认连接是否还能正常使用,后面可能还会接收到数据,这样的连接不能被复用,只能丢弃并打开新的网络连接。在网络出现缓慢、丢包、redis 服务器执行消耗过多时间时, 将出现大量连接被丢弃、新建连接,这样连接池也就失去了意义,且情况会越来越恶化。

你可以查看 Go Context timeouts can be harmful (英文版) 这篇文章了解更多。

context 是一种控制超时的方式,但并不是所有场景都适用它。

Lua 脚本

var incrBy = redis.NewScript(`
local key = KEYS[1]
local change = ARGV[1]local value = redis.call("GET", key)
if not value thenvalue = 0
endvalue = value + change
redis.call("SET", key, value)return value
`)

运行脚本

keys := []string{"my_counter"}
values := []interface{}{+1}
num, err := incrBy.Run(ctx, rdb, keys, values...).Int()

Lua 和 Go 类型

下面是 Lua 和 Go 语言的类型对照表,Lua 的 number 是一个浮点型数字,用于存储整数和浮点数,在 Lua 中不区分整数和浮点数,但 Redis 总是将 Lua 数字转换为舍去小数部分的整数,例如 3.14 变成 3,如果要返回浮点值,将其作为字符串返回并用 Go 解析成 float64。

Lua returnGo interface{}
number (float64)int64 (舍弃小数)
stringstring
falseredis.Nil error
trueint64(1)
{ok = "status"}string("status")
{err = "error message"}errors.New("error message")
{"foo", "bar"}[]interface{}{"foo", "bar"}
{foo = "bar", bar = "baz"}[]interface{}{} (不支持)

更多探索

官网:Golang Redis客户端

相关文章:

go 集成go-redis 缓存操作

一、什么是Go Redis 这是一个流行的Go语言Redis客户端库,它提供了细化的API,对每个Redis命令的功能进行了封装,使得用户只需记住命令,具体的用法可以直接查看接口的声明,使用成本较低。go-redis对数据类型按照Redis底…...

python数据结构基础(3)

书接上文.要创建一个单链表类,首先是初始化方法: class singlelink:def __init__(self):self.head Noneself.tail Noneself.length0return 判断链表是否为空: def isempty(self):return self.length 0 向链表尾部添加节点: def add_node(self,item):if not isinstance(…...

java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl

用大模型做车牌号识别,最简单高效 在Java场景中,java识别车牌号的需求非常普遍。过去,我们主要依赖OCR等传统方法来实现java识别车牌号,但这些方法的效果往往不稳定。随着技术的发展,现在有了更先进的解决方案——大模…...

全局池化(Global Pooling)

普通池化操作看这里:最大池化(Max Pooling)和平均池化(Average Pooling) 全局池化(Global Pooling) 是一种特殊的池化方法,主要包括: 全局平均池化(Global …...

ubuntu 24.04运行chattts时cuda安装错误原因分析

使用ubuntu 24.04,按照2noise/ChatTTS官方流程安装依赖时报错。ChatTTShttps://github.com/2noise/ChatTTS 这是因为cuda版本不对,ChatTTS目前的版本,要求支持cuda 12.4及以上,但是如果nvidia显卡驱动版本较老,无法支…...

使用 Cypher 查询语言在 Neo4j 中查找最短路径

使用 Cypher 查询语言在 Neo4j 中查找最短路径 引言1. Cypher 查询语言简介2. 查找最短路径的 Cypher 查询3. 代码解释3.1 MATCH 关键字3.2 pshortestPath(3.3 (bacon:Person {name:"Kevin Bacon"})3.4 -[*]-3.5 (meg:Person {name:"Meg Ryan"})3.6 )3.7 R…...

Qt多边形填充/不填充绘制

1 填充多边形绘制形式 void GraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {Q_UNUSED(option);Q_UNUSED(widget);//painter->setPen(pen()); // 设置默认画笔//painter->setBrush(brush()); // 设置默…...

数据结构-数组(稀疏矩阵转置)和广义表

目录 1、数组定义 1)数组存储地址计算示例①行优先②列优先 2)稀疏矩阵的转置三元组顺序表结构定义 ①普通矩阵转置②三元组顺序表转置稀疏矩阵③稀疏矩阵的快速转置 3)十字链表结构定义 2、广义表定义 1)基本操作①GetHead②GetT…...

Java中的远程方法调用——RPC详解

1. 什么是RPC? RPC基础介绍 Java中的远程方法调用(Remote Procedure Call,RPC)是一种允许一个程序调用另一台计算机上方法的技术,就像在本地一样。RPC的核心思想是简化分布式计算,让我们可以跨网络调用远程…...

【kafka】大数据编写kafka命令使用脚本,轻巧简洁实用kafka

kafka是大数据技术中举足轻重的技术,市面上也有很多kafka的ui界面,但是都会占用比较大的内存和性能,这里我编写好了一个fakfa的脚本集成了kafka常见的命令使用。脚本资源放在文章顶部可自行拿取。 《Kafka 命令大全系统脚本使用指南》 在大数…...

交换区(Swap Area或Swap Partition)

在操作系统中,交换区(Swap Area或Swap Partition)扮演着至关重要的角色,主要用于在物理内存(RAM)不足时提供额外的虚拟内存空间。以下是交换区的主要功能和作用: 一、内存扩展 当系统的物理内…...

Excel 无法打开文件

Excel 无法打开文件 ‘新建 Microsoft Excel 工作表.xlsx",因为 文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。...

MySQL —— Innodb 索引数据结构

文章目录 不用平衡二叉树或红黑树作为索引B树适合作为索引比B树更适合作为索引的结构——B树总结 MySQL 使用 B树索引数据结构(因为默认使用 innodb 存储引擎) B树:有序数组 平衡多叉树;B树:有序数组链表 平衡多叉树…...

探索C语言数据类型

目录 前言 一、基本数据类型 1.整型(Integer) 2.浮点型(Floating - point) 3.字符型(Character) 4.布尔型(Boolean) 二、派生数据类型 1.数组(Array&#xff09…...

凌晨官宣离婚,他们为何让老粉直呼天塌?

你说的是影视飓风MediaStorm的创始人Tim和小鱼吧,他们确实在11月5日凌晨官宣离婚了。以下是具体介绍:官宣离婚2024年11月5日凌晨,影视飓风MediaStorm的创始人Tim(潘天鸿)在社交媒体上发文,宣布与小鱼&#…...

Spring Boot 导出 Excel 文件

本文将详细介绍如何使用 Spring Boot 和 Apache POI 实现 Excel 文件的导出功能,帮助开发者快速上手。 1. 准备工作 首先,确保你的 Spring Boot 项目已成功创建并运行。接下来,需要在 pom.xml 文件中添加 Apache POI 相关依赖,以…...

HTTPSOK:SSL/TLS证书自动续期工具

HTTPSOK 是一个支持 SSL/TLS 证书自动续期 的工具,旨在简化 SSL 证书的管理,尤其是自动化处理证书续期的工作。对于大多数网站而言,SSL 证书的续期是一项必要但容易被忽视的工作,因为 SSL 证书的有效期通常为 90 天。使用 HTTPSOK…...

Uniapp安装Pinia并持久化(Vue3)

安装pinia 在uni-app的Vue3版本中,Pinia已被内置,无需额外安装即可直接使用(Vue2版本则内置了Vuex)。 HBuilder X项目:直接使用,无需安装。CLI项目:需手动安装,执行yarn add pinia…...

基于Dpabi和spm12的脑脊液(csf)分割和提取笔记

一、前言 脑脊液(csf)一直被认为与新陈代谢有重要关联,其为许多神经科学研究提供重要价值,从fMRI图像中提取脑脊液信号可用于多种神经系统疾病的诊断。特别是自2019年Science上那篇著名的csf-BOLD文章发表后,大家都试图…...

【每日一题】2012考研数据结构 - 求字符串链表公共后缀

本篇文章将为大家讲解一道关于链表的经典题目——求两个链表的共同后缀节点。该问题在实际开发中同样具有很大的应用价值,是每一位数据结构学习者不可错过的重要题目。 问题描述 假设我们有一个带头结点的单链表来保存单词,每个节点包含一个字符和指向…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

AspectJ 在 Android 中的完整使用指南

一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...