go环境本身不内置缓存系统,裸用map会panic,sync.map缺淘汰机制,手写container/list+map易静默丢数据;选对工具(如golang-lru/v2)比造轮子更关键,且泛型参数必须显式指定类型,避免类型断言失败导致零值静默丢失。

go 环境本身无需“搭建缓存系统”——缓存是业务逻辑层的选择,不是 Go 运行时自带能力。直接用 map 会 panic,裸写 sync.Map 缺 TTL 和淘汰,硬套 container/list + map 极易静默丢数据。选对工具比从零造轮子更关键。
go-cache 初始化必须设 cleanupInterval
很多人调 cache.New(5*time.Minute, 0) 后发现过期项从不清理,是因为 cleanupInterval 为 0 时,内部 janitor goroutine 根本不启动。这不是 bug,是设计:它把清理时机交给你控制。
-
cleanupInterval必须 > 0,建议设为1 * time.Minute起步;太短(如10s)增加调度开销,太长(如30m)导致内存滞留过期项 - 默认过期时间(第一个参数)可设为
cache.NoExpiration,让每个Set()自己指定 TTL - 不要依赖
DeleteExpired()手动触发——它只清当前时刻已过期的,不处理“刚过期但还没被扫到”的条目
FileCache 写入必须用临时文件 + rename
直接 os.OpenFile(cacheDir+"/"+hash, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) 是高危操作:并发写入时文件内容错乱、读取可能拿到截断或半写状态的数据。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 正确流程:先
os.WriteFile(filepath.Join(cacheDir, "tmp_"+hash), data, 0600),再os.Rename(filepath.Join(cacheDir, "tmp_"+hash), filepath.Join(cacheDir, hash)) -
filepath.Join不可省略——拼接字符串在 Windows 下路径分隔符错误,且cacheDir结尾是否带/会导致stat cache//abc或stat cache\abc这类非法路径 - 读取前务必
os.Stat检查文件存在性和ModTime是否过期,不能只靠文件名或缓存句柄
golang-lru/v2 的泛型参数不能写 any
lru.New[string, int](128) 可以,lru.New(128) 或 lru.New[any, any](128) 会导致 Get() 返回 any,类型断言失败时静默返回零值,而不是 panic —— 你根本不知道数据丢了。
- 泛型参数必须显式写出 key 和 value 类型,例如
lru.New[uint64, []byte](1024) -
Add(key, value)是覆盖语义:key 存在就更新 value 并重置 LRU 顺序,不用先Remove再Add -
Resize()是重建链表,期间所有Get/Add阻塞;迁移后历史访问序清零,别依赖旧热度做降级判断
gomemcache 的 key 必须纯 ASCII,value 必须 []byte
mc.Set("user_张三", []byte("data"), 30) 看似能跑,实际服务端静默拒绝——key 含中文会直接丢弃,Set 返回 nil error,但数据没存进去。
- key 只能含 ASCII 字母、数字、下划线、连字符;可用
strings.Map(func(r rune) rune { if r >= 'a' && r = 'A' && r = '0' && r 过滤 - value 一律走
json.Marshal→[]byte,读取时先判item == nil,再json.Unmarshal(item.Value, &v) -
mc.Timeout = 100 * time.Millisecond必须在memcache.New()后立刻设置;默认是 0(无限等待),线上故障高频点
真正难的不是“怎么存”,而是“什么时候删、删不删得干净、删完还剩什么”。缓存一致性永远藏在边界条件里:过期检查时机、并发更新顺序、GC 触发节奏、网络抖动下的 fallback 行为——这些没法靠文档覆盖,得靠压测和日志反推。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










