go redis 计数

发布时间:2026/9/14 19:00:30

go redis 计数 在 Go 中使用 Redis 做计数最常用的库是github.com/redis/go-redis/v9。以下是核心用法和常见场景1. 基础计数操作gopackage main import ( context fmt github.com/redis/go-redis/v9 ) func main() { ctx : context.Background() rdb : redis.NewClient(redis.Options{ Addr: localhost:6379, }) key : page:view:home // INCR - 自增 1 val, err : rdb.Incr(ctx, key).Result() fmt.Println(INCR:, val, err) // INCRBY - 自增指定数值 val, err rdb.IncrBy(ctx, key, 10).Result() fmt.Println(INCRBY:, val, err) // DECR - 自减 1 val, err rdb.Decr(ctx, key).Result() fmt.Println(DECR:, val, err) // DECRBY - 自减指定数值 val, err rdb.DecrBy(ctx, key, 5).Result() fmt.Println(DECRBY:, val, err) }2. 带过期时间的计数如每日统计go// 每日点赞数凌晨自动过期 func incrDailyLike(ctx context.Context, rdb *redis.Client, itemID string) (int64, error) { key : fmt.Sprintf(like:daily:%s:%s, time.Now().Format(2006-01-02), itemID) // 使用 Pipeline 原子执行 INCR EXPIRE pipe : rdb.Pipeline() incr : pipe.Incr(ctx, key) pipe.Expire(ctx, key, 25*time.Hour) // 留点余量 _, err : pipe.Exec(ctx) return incr.Val(), err }3. 限流计数滑动窗口go// 固定窗口限流每分钟内最多 100 次 func rateLimit(ctx context.Context, rdb *redis.Client, userID string) (bool, error) { key : fmt.Sprintf(ratelimit:%s:%d, userID, time.Now().Unix()/60) current, err : rdb.Incr(ctx, key).Result() if err ! nil { return false, err } if current 1 { // 第一次访问设置过期时间 rdb.Expire(ctx, key, time.Minute) } return current 100, nil }4. Hash 字段计数多维度统计go// 统计文章的多维度数据 rdb.HIncrBy(ctx, post:stats:123, views, 1) rdb.HIncrBy(ctx, post:stats:123, likes, 1) rdb.HIncrBy(ctx, post:stats:123, comments, 1) // 获取全部 stats, _ : rdb.HGetAll(ctx, post:stats:123).Result()5. 批量计数Pipelinegopipe : rdb.Pipeline() for i : 0; i 1000; i { pipe.Incr(ctx, fmt.Sprintf(counter:%d, i)) } _, err : pipe.Exec(ctx)关键注意点表格问题方案并发安全Redis 单线程INCR 天然原子无需加锁首次计数key 不存在时 INCR 自动从 0 开始返回 1溢出Redis 整数上限为 64 位有符号整数2^63-1持久化若数据极重要建议开启 AOF 或定期落库如果你有具体场景比如高并发计数、去重计数、分布式 ID 生成可以告诉我我给出更针对性的方案。在 Go 中使用go-redis获取计数值主要用GET系列命令。以下是常见场景的完整示例1. 基础获取gopackage main import ( context fmt strconv github.com/redis/go-redis/v9 ) func main() { ctx : context.Background() rdb : redis.NewClient(redis.Options{Addr: localhost:6379}) // 获取单个计数 val, err : rdb.Get(ctx, page:view:home).Result() if err redis.Nil { fmt.Println(key 不存在计数为 0) } else if err ! nil { panic(err) } else { count, _ : strconv.ParseInt(val, 10, 64) fmt.Println(当前计数:, count) } // 直接获取 int64推荐 count, err : rdb.Get(ctx, page:view:home).Int64() if err redis.Nil { count 0 } fmt.Println(计数:, count) }2. 批量获取多个计数go// MGET 一次性获取多个 key keys : []string{counter:a, counter:b, counter:c} vals, err : rdb.MGet(ctx, keys...).Result() // vals 是 []interface{}不存在的 key 对应 nil for i, v : range vals { if v nil { fmt.Printf(%s 0 (不存在)\n, keys[i]) } else { fmt.Printf(%s %v\n, keys[i], v) } }3. Hash 结构中的计数获取go// HGET 获取单个字段 views, _ : rdb.HGet(ctx, post:stats:123, views).Int64() // HMGET 获取多个字段 fields : []string{views, likes, comments} vals, _ : rdb.HMGet(ctx, post:stats:123, fields...).Result() // HGETALL 获取全部字段 all, _ : rdb.HGetAll(ctx, post:stats:123).Result() fmt.Println(all[views], all[likes])4. 获取并设置过期时间原子操作go// 获取计数同时刷新过期时间如会话活跃统计 pipe : rdb.Pipeline() get : pipe.Get(ctx, session:active:1001) pipe.Expire(ctx, session:active:1001, 30*time.Minute) _, err : pipe.Exec(ctx) count, _ : get.Int64()5. 获取时的类型转换方法go-redis的StringCmd提供了便捷转换表格方法说明.Result()返回(string, error).Int64()直接转int64key 不存在返回redis.Nil错误.Uint64()转uint64.Float64()转float64用于浮点计数.Bool()转bool6. 完整工具函数示例go// GetCounter 安全获取计数key 不存在返回 0 func GetCounter(ctx context.Context, rdb *redis.Client, key string) int64 { n, err : rdb.Get(ctx, key).Int64() if err redis.Nil { return 0 } if err ! nil { // 可打日志或上报 return 0 } return n } // GetCounters 批量获取返回 map[key]count func GetCounters(ctx context.Context, rdb *redis.Client, keys ...string) map[string]int64 { result : make(map[string]int64, len(keys)) if len(keys) 0 { return result } vals, err : rdb.MGet(ctx, keys...).Result() if err ! nil { return result } for i, v : range vals { if v ! nil { if n, ok : v.(string); ok { result[keys[i]], _ strconv.ParseInt(n, 10, 64) } } else { result[keys[i]] 0 } } return result }核心注意点Redis 中INCR等命令存储的是字符串Get返回的是字符串需用.Int64()转换key 不存在时Get返回redis.Nil错误不是返回0。
延伸阅读

更多相关文章

2026/9/14 13:20:08

sql优化建议

SELECT count(*) FROM "fsrs_cards" WHERE "fsrs_cards"."deleted_at" IS NULL and exist (select 1 from vocab_words where vocab_id 1001 and obj_id word_id and deleted_at is null) AND (user_id 1983799923358830592) AND (要分析这条S…

2026/9/13 10:05:49

RAGFlow、LightRAG 还是 GraphRAG?9 个维度帮你一次选对

从文档解析、关系推理到全局归纳,三套方案选型不靠参数对比,靠看清自己的核心约束 你的场景决定选哪个,没有银弹。 一、为什么需要它们:传统 RAG 的三道坎 问一句「过去半年设计评审中团队的主要分歧是什么」,传统 RA…

2026/9/13 23:48:37

解锁AMD Ryzen隐藏潜力:SMUDebugTool硬件调试完全指南

解锁AMD Ryzen隐藏潜力:SMUDebugTool硬件调试完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

2026/9/15 3:46:30

IMM-UPF多目标跟踪:机动建模与存在概率联合估计

简介:本资源是一套面向高校研究生、算法工程师及智能感知方向研究者的多目标跟踪(MTT)MATLAB实战代码包,聚焦非线性非高斯场景下的滤波建模与数据关联核心问题,适用于视频监控、无人系统轨迹估计等实际应用。压缩包共9…

2026/9/15 3:41:30

OBD接口不是协议:物理层与诊断协议的本质区别

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/14 11:59:31

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码