cachex

package
v0.19.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: Apache-2.0, Apache-2.0 Imports: 33 Imported by: 1

README

Go-Cachex

Go-Cachex 是一个全面的缓存库,提供多种缓存实现和适配器,支持 TTL、LRU 驱逐、并发安全、分布式锁、队列、发布订阅和上下文感知等特性。

stable license download release commit issues pull fork star go size contributors codecov Go Report Card Go Reference Sourcegraph

📚 目录

🏗️ 架构设计

Go-Cachex 采用模块化分层架构设计,提供灵活且强大的缓存解决方案:

┌─────────────────────────────────────────────────────────────┐
│                        用户代码                              │
└─────────────────────────┬───────────────────────────────────┘
                         │
┌─────────────────────────▼───────────────────────────────────┐
│              Client (统一入口 + 配置管理)                    │
└─────────────────────────┬───────────────────────────────────┘
                         │
┌─────────────────────────▼───────────────────────────────────┐
│        CtxCache (context 支持 + singleflight 去重)          │
└─────────────────────────┬───────────────────────────────────┘
                         │
┌─────────────────────────▼───────────────────────────────────┐
│  Handler (缓存实现:LRU/Redis/Ristretto/Expiring/等)        │
└─────────────────────┬───┬───┬───┬─────────────────────────────┘
                     │   │   │   │
              ┌──────▼─┐ ┌▼─┐ ┌▼─┐ ┌▼──────────────┐
              │ Memory │ │队列│ │锁│ │ 发布订阅      │
              └────────┘ └──┘ └──┘ └───────────────┘
🎯 架构层次
  • Client 层:统一的用户接口,提供配置管理和便利函数
  • CtxCache 层:为底层 Handler 添加 context 支持和并发去重功能
  • Handler 层:具体的缓存实现,支持多种存储后端
  • 扩展层:队列、锁、发布订阅等高级功能

✨ 功能特性

🚀 核心缓存功能
多种缓存后端
  • LRU Cache: 内存 LRU 缓存,支持容量限制和 TTL
  • LRU Optimized: 超高性能分片架构LRU (500%+性能提升)
  • Ristretto Cache: 基于频率的并发缓存,最佳缓存命中率
  • Redis Cache: 分布式缓存后端,支持故障转移
  • TwoLevel Cache: 智能分层缓存,L1快速缓存 + L2存储缓存
  • Sharded Cache: 分布式负载,减少锁竞争
  • Expiring Cache: 简单的 TTL 缓存,后台自动清理
统一Handler接口

所有缓存实现都支持双API设计:

  • 简化版API: Set(), Get(), Del() 等 - 适合快速简单的操作
  • WithCtx API: SetWithCtx(), GetWithCtx() 等 - 支持超时控制和取消
// 简化版 - 快速简单
cache.Set(key, value)
val, _ := cache.Get(key)

// WithCtx版 - 超时控制
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
cache.SetWithCtx(ctx, key, value)
val, _ := cache.GetWithCtx(ctx, key)

📘 详细API说明请查看 USAGE.md

🔥 高级特性
队列系统
  • 多种队列类型: FIFO、LIFO、优先级、延迟队列
  • 批量操作: 支持批量入队/出队提升性能
  • 分布式锁: 可选的队列操作锁定机制
  • 重试机制: 失败任务自动重试
  • 统计监控: 队列状态和性能统计
分布式锁
  • Redis分布式锁: 基于Redis的高可用分布式锁
  • 可选看门狗: 自动续期防止锁过期
  • 锁竞争统计: 详细的锁使用统计
  • 超时控制: 灵活的锁获取超时配置
发布订阅系统
  • Redis Pub/Sub: 高性能消息发布订阅
  • 模式订阅: 支持通配符模式订阅
  • 请求响应: 内置请求响应通信模式
  • 消息重试: 可配置的消息处理重试
  • 统计监控: 消息传递统计和监控
热Key缓存
  • SQL数据加载: 支持从数据库加载热点数据
  • Redis存储: 使用Redis作为分布式存储
  • 自动刷新: 可配置的定时数据刷新
  • 缓存预热: 启动时预加载热点数据
缓存包装器 🆕
  • 泛型支持: 支持任意类型的数据缓存 CacheWrapper[T]
  • 延迟双删: 实现延迟双删策略,确保缓存一致性
  • 数据压缩: 自动Zlib压缩,减少Redis内存占用
  • 错误处理: 优雅的错误处理和降级机制
  • 并发安全: 支持高并发访问,适用于生产环境
缓存索引管理器 🆕
  • 傻瓜式操作: CacheWrapperWithIndex 一行代码同时完成缓存读取+索引注册
  • 原子删除: Lua脚本保证索引集合与缓存键的原子清理
  • 分组管理: NewIndexGroup 预定义业务分组,一行调用批量删除
  • 零侵入: 与现有 CacheWrapper 完全兼容,无需修改已有代码
⚡ 性能与监控
双API设计 🆕
  • 简化版方法: 不带context,适合简单场景快速调用
  • 完整版方法: 带context,支持超时控制和取消操作
  • 统一接口: 所有Handler实现都支持双API,灵活选择
  • 向后兼容: 简化版方法内部自动调用WithCtx版本
Context 支持
  • 超时控制: WithCtx方法支持context超时控制
  • 取消操作: 支持通过context取消长时间运行的操作
  • 并发去重: GetOrComputeWithCtx内置singleflight机制
  • 链路追踪: Context可用于分布式链路追踪
统计与监控
  • 性能指标: 命中率、操作计数、延迟统计
  • 容量信息: 当前条目、最大容量、内存使用
  • 架构细节: 分片计数、驱逐统计、后端状态
  • 健康状态: 连接状态、错误率、过期计数
高性能优化
  • 零拷贝技术: 减少内存分配和复制
  • 分片架构: 减少锁竞争,提升并发性能
  • 批量操作: 优化网络和CPU使用率
  • 内存池: 对象重用减少GC压力

🚀 快速开始

环境要求

建议需要 Go 版本 1.23 或更高版本

安装
go get -u github.com/HitGameAI/apex-toolbox/pkg/cachex
5分钟入门
package main

import (
    "fmt"
    "time"
    "github.com/HitGameAI/apex-toolbox/pkg/cachex"
)

func main() {
    // 创建LRU缓存
    cache := cachex.NewLRUHandler(1000)
    defer cache.Close()
    
    // 设置和获取
    cache.Set([]byte("key"), []byte("value"))
    val, _ := cache.Get([]byte("key"))
    fmt.Printf("值: %s\n", string(val))
    
    // 带TTL
    cache.SetWithTTL([]byte("temp"), []byte("data"), 5*time.Second)
    
    // 查看统计
    stats := cache.Stats()
    fmt.Printf("条目数: %v\n", stats["entries"])
}

💡 更多示例:查看 USAGE.md 获取完整的使用指南和高级特性

🧩 核心组件

缓存Handler实现
  • LRU Cache - 经典LRU算法,适合中小型应用
  • LRU Optimized - 16分片架构,500%+性能提升,适合高并发场景
  • Ristretto - 高命中率缓存,适合读密集应用
  • Redis - 分布式缓存,适合多服务共享
  • TwoLevel - 两级缓存,结合内存和分布式优势
  • Expiring - 自动过期清理,适合临时数据
  • Sharded - 自定义分片策略
高级功能
  • 队列系统 - FIFO/LIFO/优先级/延迟队列
  • 分布式锁 - Redis分布式锁,支持看门狗
  • 发布订阅 - Redis Pub/Sub消息系统
  • 热Key缓存 - 热点数据自动加载和刷新
  • 泛型包装器 - CacheWrapper[T]泛型支持
  • 缓存索引管理器 - 傻瓜式缓存索引注册与原子删除 🆕

📘 详细用法:查看 USAGE.md 了解每个组件的详细使用方法

📖 文档索引

📘 使用文档
📊 性能与架构
🔧 高级组件
💻 开发资源

🏃‍♂️ 代码示例

查看 examples/ 目录获取各组件的完整示例:

examples/
├── lru/              # LRU缓存示例
├── lru_optimized/    # 高性能LRU示例
├── ristretto/        # Ristretto缓存示例
├── redis/            # Redis缓存示例
├── twolevel/         # 两级缓存示例
├── ctxcache/         # Context缓存示例
└── expiring/         # 过期缓存示例

📈 性能报告

基准测试结果
组件 操作/秒 延迟 内存使用 提升
LRU Optimized 2.8M ops/s 0.35μs 354 bytes/entry +500%
Standard LRU 500K ops/s 2.0μs 18TB bytes/entry baseline
Ristretto 1.2M ops/s 0.83μs Variable +140%
Redis Cache 100K ops/s 10μs Network N/A

详细性能分析请查看 PERFORMANCE-REPORT.md

优化特性
  • 零拷贝技术: 减少70%的内存分配
  • 分片架构: 16分片设计,减少99%的锁竞争
  • 批量操作: 网络操作性能提升10倍
  • 对象池: GC压力减少80%

🤝 贡献指南

我们欢迎各种形式的贡献!

如何贡献
  1. Fork 项目
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 打开 Pull Request
开发要求
  • Go 1.23+
  • 单元测试覆盖率 > 90%
  • 遵循 Go 代码规范
  • 添加适当的文档和示例
问题报告

如果发现 bug 或有功能建议,请通过 Issues 提交。

📄 许可证

本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。

🙏 致谢

感谢所有为本项目做出贡献的开发者!


如果觉得这个项目对您有帮助,请给我们一个 ⭐ Star!

Documentation

Overview

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-27 09:53:20 * @FilePath: \go-toolbox\cachex\\advanced_cache.go * @Description: 高级缓存包装器,支持压缩和泛型,集成队列、热key和分布式锁功能 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 23:13:01 * @FilePath: \go-toolbox\cachex\\cache.go * @Description: * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-05-20 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastLastEditTime: 2026-05-20 00:00:00 * @FilePath: \go-toolbox\cachex\\cache_index.go * @Description: 缓存索引管理器 - 基于索引集合实现缓存键的注册、查询与原子删除 * * 核心思路: * 将缓存键注册到 Redis Set(索引集合)中,删除时通过 Lua 脚本原子地 * 获取集合内所有成员并批量删除,最后删除索引集合本身。 * * 设计原则: * - 傻瓜式操作:CacheWrapperWithIndex 一行代码同时完成缓存+索引注册 * - 分组管理:NewIndexGroup 预定义业务分组,删除时一行调用 * - 原子删除:Lua 脚本保证索引+缓存键的原子清理 * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 19:15:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 19:15:00 * @FilePath: \go-toolbox\cachex\\client.go * @Description: 缓存客户端统一入口 * * 提供统一的缓存客户端接口,支持多种底层缓存实现(LRU、Ristretto、Redis、Expiring) * 主要功能包括: * - 统一的配置结构 `ClientConfig`,支持不同缓存类型的配置参数 * - 支持 context 的完整 API:Get、Set、SetWithTTL、Del、GetOrCompute * - 便利构造函数:NewLRUClient、NewRistrettoClient、NewRedisClient、NewExpiringClient * - 自动错误处理和参数验证 * - 优雅的资源管理(Close) * * 使用注意: * - 所有操作都支持 context 传入,可以实现超时控制和取消操作 * - Client 内部封装了 CtxCache,提供并发去重和 singleflight 支持 * - 不同缓存类型有不同的配置要求,使用前请确保配置正确 * - 使用完毕后应调用 Close() 方法释放资源 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 18:58:57 * @FilePath: \go-toolbox\cachex\\ctxcache.go * @Description: context 的缓存封装 `CtxCache` * 实现之上提供对上下文取消和并发去重的支持主要功能包括: * - 提供 `GetOrCompute(ctx, key, ttl, loader)` 方法:先尝试从底层缓存读取,未命中时 * 使用内部的 singleflight(flightGroup)对并发加载进行去重,并在 loader 成功后 * 将结果写回底层缓存(带可选 TTL) * - 代理常见的缓存操作(Get/Set/SetWithTTL/Del/Close),使现有的 Handler 可无缝 * 被升级为支持 context 的缓存层 * * 使用注意: * - 传入的 loader 必须尊重 ctx 取消(及时返回),以便在调用方取消时能中断加载 * - 写回缓存的操作是“最佳努力”的:写失败不会影响 loader 的返回结果,但可能 * 导致后续命中率下降 * - 本文件内实现了一个简易的 flightGroup 以代替外部的 singleflight 依赖,适用于 * 常见去重场景,不保证对极端高并发或长时间阻塞的优化需求 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-07-02 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-02 01:00:00 * @FilePath: \go-toolbox\cachex\\delay_queue.go * @Description: 高级分布式延迟队列,基于 Redis ZSET + Lua 原子脚本 * * 特性: * - 延迟执行:任务在指定时间戳到期后才被消费 * - ACK 确认:任务出队后进入 processing,处理成功才 ACK 删除;未 ACK 的任务在可见性超时后回归队列 * - 崩溃恢复:Pod 崩溃/停止时,processing 中未 ACK 的任务由其它 Pod 的 requeueStale 自动接管 * - 原子出队:Lua 脚本保证 ZRANGEBYSCORE + ZREM + ZADD(processing) 原子性,多实例安全 * - 顺序保证:Ordered 模式下同一 queue 内任务按到期时间串行处理,避免乱序 * - 堆积监控:暴露 ReadyLength/ProcessingLength,超过 MaxReadySize 阈值时记录告警日志 * - 任务去重:通过唯一 Key 标识任务,重复入队会覆盖执行时间(重新调度语义) * - 任务取消:支持通过 Key 取消未执行/处理中的延迟任务 * - 失败重试:处理失败自动 ACK 后重新入队,支持指数退避 * - 死信队列:超过最大重试次数进入死信列表,便于人工干预 * - 优雅关闭:Stop 等待所有在途任务处理完成,未 ACK 的任务靠可见性超时兜底 * * 适用场景: * - 定时状态流转(如订单超时关闭、维护计划状态自动更新) * - 延迟通知、定时任务分发 * - 跨实例的分布式定时协调 * * 不适用场景: * - 强一致性事务(Redis 故障可能丢失任务,重要任务需配合持久化补偿) * - 毫秒级精度的实时调度(受轮询间隔限制,默认 1s) * * 存储结构: * - ZSET {ns}:zset:{queue} ready,score=执行时间戳(ms) member=taskKey * - ZSET {ns}:processing:{queue} processing,score=可见性超时戳 member=taskKey * - HASH {ns}:hash:{queue} field=taskKey value=任务JSON(ready/processing 共用,ACK 时删除) * - LIST {ns}:dead:{queue} 死信队列(LPush) * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-28 09:06:22 * @FilePath: \go-toolbox\cachex\\distributed_lock.go * @Description: 分布式锁实现,提供可靠的分布式锁机制 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-06 21:15:15 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-26 10:19:57 * @FilePath: \go-toolbox\cachex\\expiring.go * @Description: * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-06 21:15:15 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-06 00:15:56 * @FilePath: \go-toolbox\cachex\\generic_cache.go * @Description: 泛型本地 TTL 缓存(GenericTTLCache) * * 与 Handler([]byte 值)互补,支持任意类型值(如 *rsa.PublicKey、bool、struct 指针等), * 避免序列化开销,适合鉴权热路径等高性能场景 * * 设计要点: * - 基于 sync.Map,无锁读路径,适合读多写少场景 * - 惰性过期:读取时检查过期时间,过期则删除并视为未命中 * - 不主动清理过期项(避免后台 goroutine 开销);过期项占用极小内存, * 下次读取时被惰性删除,或在主动 Delete 时被清理 * - 分布式一致性:通过短 TTL 容忍秒级不一致,配合主动 Delete 失效; * 启用 PubSub(WithPubSub 选项)后,Delete/Clear 事件广播到所有节点, * 收到事件的节点删除本地缓存,实现跨节点即时失效 * * KeyCodec 解决 Go 泛型键序列化问题: * Go 泛型无法在运行时从 string 还原为类型参数 K(comparable 约束不足以支撑反序列化), * kv_cache.go 中 any(ks).(K) 仅对 string 生效,对 int 等类型静默失效 * 通过 KeyCodec[K] 接口显式提供 Encode/Decode,使 PubSub 跨节点传输时能正确还原键, * 同时覆盖 string/int/int64 等常见类型,自定义键类型实现接口即可

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-19 00:00:00 * @FilePath: \go-toolbox\cachex\\hotkey.go * @Description: 热key缓存实现,提供灵活的数据字典缓存功能 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-01 00:51:56 * @FilePath: \go-toolbox\cachex\\kv_cache.go * @Description: KVCache —— 通用分布式 K-V 字典缓存 * * ============================================================================ * 设计目标 * ============================================================================ * 提供"高频读、低频写"场景下的分布式字典缓存,解决多节点部署时本地缓存 * 一致性问题适用 K→V 映射(V 必须可 JSON 序列化),如 id→name、code→config * * ============================================================================ * 核心能力(三件套) * ============================================================================ * 1. 三层兜底读取(Get/GetMany) * 本地 map[K]V → Redis Hash(HGET/HMGET) → loader 全量预热 * 读路径:优先命中本地,miss 查 Redis 并回填本地,再 miss 走 loader * 加载全量后同步写回 Redis Hash,避免缓存穿透 * * 2. 写后失效广播(Set/SetMany/Delete/DeleteMany/Clear) * 写操作同步双写:本地 map + Redis Hash(Lua 脚本保证 HSET+EXPIRE 原子) * 写成功后通过 Redis PubSub 广播 invalidate 消息到其他节点: * - 收到消息的节点删除本地对应 key,下次 Get 走 Redis 拿最新值 * - 通过 instanceID 区分自己发的消息,避免循环处理 * - Refresh(自动刷新/手动预热)不广播,避免周期性刷新引发雪崩 * * 3. pbmo 风格全局注册(RegisterKV/GetKV/MustGetKV/GetKVMany) * SetGlobalRedisClient(client) 设置全局 Redis 客户端 * RegisterKV[K,V](name, loadFunc, opts...) 一行注册 * GetKV[K,V](name) / MustGetKV[K,V](name) 业务侧取用 * GetKVMany[K,V](ctx, name, keys) 批量读取快捷封装(空 keys 或出错返回 nil) * StopAllKV() 统一关闭所有注册实例 * * ============================================================================ * 存储结构 * ============================================================================ * - Redis: Hash 类型 * Key = {namespace}:{name} (如 core:kv:game:game_library) * Field = K 的字符串序列化 (string 直接用,int 用 strconv) * Value = V 的 JSON 序列化 * - 本地: map[K]V + RWMutex * - PubSub 频道: {namespace}:{name}:invalidate (失效广播专用) * * ============================================================================ * 适用场景 * ============================================================================ * ✅ id→name、code→config 等点查字典(高频读、低频写) * ✅ 多节点部署需要本地缓存一致性的 K→V 映射 * ✅ V 为可 JSON 序列化类型(string/int/struct 等) * * ============================================================================ * 不适用场景(请用其他机制) * ============================================================================ * ❌ 需要原子递增的计数器/版本号 → 用 VersionTracker(Redis INCR 语义) * ❌ 整体列表响应缓存(带排序/过滤/分页) → 用 CacheWrapper + 索引集合 * ❌ 缓存不可序列化对象(如 SDK 客户端实例 *Client) → 无法用 KVCache * ❌ 强一致事务场景 → KVCache 是最终一致(PubSub 异步失效) * * ============================================================================ * 与同库其他缓存组件的边界 * ============================================================================ * - VersionTracker:SDK 客户端实例生命周期管理(INCR 哨兵 + 比较 + 重建),非字典缓存 * - CacheWrapper:单 key 读穿透缓存(func 包装),适合整体响应 * - CacheIndexManager:基于 Redis Set 索引的批量删除,配合 CacheWrapper 使用 * - HotKeyCache[K,V]:本地+Redis 双层字典(无 PubSub 广播,单节点失效) * - KVCache(本文件):HotKeyCache 的增强版,新增 PubSub 失效广播 + 全局注册表 * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-01-13 13:15:19 * @FilePath: \go-toolbox\cachex\\logger.go * @Description: go-cachex 日志接口,直接复用 go-logger * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-06 22:05:59 * @FilePath: \go-toolbox\cachex\\lru.go * @Description: 简单的 goroutine 安全 LRU 缓存(LRUHandler) * * 提供可选的每项 TTL 支持,键/值以 []byte 表示(内部以 string 存储键) * 该实现适合用作本地内存缓存或测试用例中的轻量缓存 * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 22:30:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-25 11:07:52 * @FilePath: \go-toolbox\cachex\\lru_optimized.go * @Description: 超高性能优化版本的 LRU 缓存实现 * * 主要优化点: * 1. 分片设计减少锁竞争 * 2. 原子操作优化热路径 * 3. 零拷贝字节操作 * 4. 高效的内存池管理 * 5. 批量操作支持 * 6. NUMA友好的内存布局 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-08-18 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-08-18 00:00:00 * @FilePath: \go-toolbox\cachex\\model_cache.go * @Description: ModelCache —— 基于 gorm 反射的泛型 model 整实例缓存 * * ============================================================================ * 设计目标 * ============================================================================ * 与 ModelKVCache(字段级 KV,如 id→name)互补,本组件缓存完整 model 实例: * - 支持复合业务键(如 tenant_id + platform_id → 整条配置记录) * - 底层复用 KVCache 三层兜底(本地 → Redis Hash → BatchLoader 按 DB 精准回源) * - 写后失效广播(Set/Delete 自动通知其他节点删本地缓存) * - 全量 loader 缺省(配置类小表按需回源即可,不参与 autoRefresh / Warmup) * * 存储结构: * Redis Hash:Key = {namespace}:{tableName}:model,Field = 复合 key(separator 拼接), * Value = 整个 model 的 JSON 序列化 * * ============================================================================ * 使用方式 * ============================================================================ * 1. 注册(bootstrap 阶段,可复用 ModelKVBase 共享 namespace/ttl): * * cachex.NewModelCache[models.PaymentReceiveConfigModel](channelBase, gwglobal.DB). * KeyFields("TenantId", "PlatformId"). // 缺省自动取 gorm 主键 * Register() * * 2. 读取(三层兜底,miss 时 BatchLoader 按 key 精准回源 DB): * * m, found, err := cachex.MustGetModelCache[models.PaymentReceiveConfigModel](). * Get(ctx, tenantID, platformID) * * 3. 写维护(通常由宿主服务的 CachedRepository 在 Create/Update/Delete 后自动调用): * * _ = cachex.MustGetModelCache[models.PaymentReceiveConfigModel]().Set(ctx, m) * _ = cachex.MustGetModelCache[models.PaymentReceiveConfigModel]().Delete(ctx, m) * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-07-01 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-03 17:55:06 * @FilePath: \go-toolbox\cachex\\model_kv.go * @Description: ModelKVCache —— 基于 gorm 反射的泛型 model KV 缓存(pbmo 风格) * * ============================================================================ * 设计目标 * ============================================================================ * 一行注册:自动通过 gorm 反射获取表名/列名,cacheName 自动派生为 {tableName}:{fieldName} * 业务侧通过 MustGetModelKV[M]().Set/Delete 自动维护所有字段缓存 * 查询侧通过 MustGetModelKV[M]().GetFieldMany(ctx, "FieldName", keys) 批量读取 * * 性能优化: * 1. unsafe 偏移读取字段(注册时预编译 extractor,零运行时反射) * 2. 共享 loadAll(N 个字段缓存只查 1 次 DB,短 TTL 复用) * 3. 缓存 *KVCache 引用(Set/Delete 不查全局 map) * * ============================================================================ * 使用方式 * ============================================================================ * 1. 定义模块级 base(共享 namespace/ttl/refreshInterval): * * gameBase := cachex.NewModelKVBase(). * Namespace(constants.KVNamespaceGame). * TTL(constants.TTLKVCacheGame). * RefreshInterval(constants.KVCacheRefreshInterval) * * 2. 各 model 一行注册(cacheName 自动派生,只需传 Go 字段名): * * cachex.NewModelKV[models.GameBrandModel](gameBase, gwglobal.DB). * Field("Name"). * Field("Code"). * Register() * * 3. Service 层 Create/Update/Delete 自动维护所有字段缓存: * * _ = cachex.MustGetModelKV[models.GameBrandModel]().Set(ctx, m) * _ = cachex.MustGetModelKV[models.GameBrandModel]().Delete(ctx, m) * * 4. 查询侧批量读取某字段: * * cachex.MustGetModelKV[models.GameLibraryModel]().GetFieldMany(ctx, "Name", gameIDs) * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-07-06 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-06 23:52:16 * @FilePath: \go-toolbox\cachex\\object_pool.go * @Description: 通用对象预生成池(pbmo 风格),削减高并发下实时构造对象的 CPU 冲击 * * ============================================================================ * 设计目标 * ============================================================================ * 一行注册:业务侧注入 factory 即可,宿主自动完成冷启动预填充、后台周期补充 * 适用于 CPU 密集型对象的预生成(如 RSA 密钥对、序列化模板、连接预热等) * * 特性: * 1. 注册即启动(冷启动同步预生成少量 + 异步补齐 + 周期任务兜底) * 2. 低水位阈值触发补充,防重叠执行避免堆积 * 3. 池空时调用方可回退实时构造,保证可用性 * 4. 全局注册表,宿主可统一 StopAllObjectPools 优雅关闭 * 5. 复用 go-toolbox syncx.PeriodicTaskManager / syncx.Go,不造轮子 * * ============================================================================ * 使用方式 * ============================================================================ * 1. bootstrap 阶段注入全局依赖(与 KVCache/Scheduler 共用): * * cachex.SetLogger(gwglobal.LOGGER) * * 2. 业务侧定义对象类型并注册(注册即启动): * * type TempKeyPem struct { * PublicKeyPem string * PrivateKeyPem string * } * * pool := cachex.RegisterObjectPool[TempKeyPem]("temp_key_pool", func() (TempKeyPem, error) { * // CPU 密集型构造逻辑 * return TempKeyPem{...}, nil * }, * cachex.WithObjectPoolCapacity(64), * cachex.WithObjectPoolColdStartCount(8)) * * 3. 业务侧取用(缓存 pool 引用,避免每次查注册表): * * if v, ok := pool.TryGet(); ok { * // 命中池,0 次 CPU 构造 * } else { * // 回退实时构造 * } * * 4. bootstrap 阶段优雅关闭(可选,进程退出时 goroutine 也会被回收): * * cachex.StopAllObjectPools() * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-28 09:06:22 * @FilePath: \go-toolbox\cachex\\pubsub.go * @Description: Redis 发布订阅功能封装,提供傻瓜式调用接口 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-12-21 15:35:16 * @FilePath: \go-toolbox\cachex\\queue.go * @Description: Redis队列实现,支持FIFO、优先级队列等多种队列类型 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-06 22:01:16 * @FilePath: \go-toolbox\cachex\\redis.go * @Description: Redis 的缓存适配器(RedisHandler) * 接口映射到 Redis 客户端调用主要职责: * - 提供 Redis 版本的 Get/Set/SetWithTTL/GetTTL/Del/Close 方法实现,返回和接受 []byte * 以保持与抽象 `Handler` 的兼容性 * - 封装连接配置结构 `RedisConfig`,并提供从文件加载配置的辅助函数 * - 适合作为分布式或远程的 L2 缓存(或共享缓存)使用 * * 使用注意: * - 值以二进制形式写入 Redis,序列化/反序列化由调用方负责(这里直接保存 []byte) * - 调用方应管理好配置与凭据(`RedisConfig`),并注意 Redis 客户端的生命周期 * - Redis 操作会使用内部 context(可通过 WithCtx 创建带自定义 ctx 的 handler) * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-06-30 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-06-30 11:03:26 * @FilePath: \go-toolbox\cachex\\resource_version.go * @Description: 资源版本追踪器,用于分布式环境下的资源变更检测和缓存失效 * 支持通过 Redis 共享版本号,实现多节点间的配置/资源热更新感知 * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-10-26 15:39:09 * @FilePath: \go-toolbox\cachex\\ristretto.go * @Description: Ristretto 适配器(RistrettoHandler) * * 对 dgraph-io/ristretto 的薄包装,满足仓库中的 `Handler` 接口Ristretto * 提供高性能的本地缓存,支持基于成本的驱逐与统计指标使用此适配器 * 可在进程内获得生产级缓存表现,但需要在项目中引入 ristretto 依赖 * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2026-07-02 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-07-02 13:34:42 * @FilePath: \apex-core-service\go-toolbox\cachex\\scheduler.go * @Description: go-cachex 调度器管理器 * * 复用全局 Redis 客户端与日志器(与 KVCache 同一套注入机制), * 业务侧一行 RegisterScheduler 即可注册调度器,宿主服务统一 * 调用 StartAllSchedulers / StopAllSchedulers 启停所有调度器 * * 使用示例: * * // 1. bootstrap 阶段注入全局依赖(与 RegisterKV 共用) * cachex.SetGlobalRedisClient(gwglobal.REDIS) * cachex.SetLogger(gwglobal.LOGGER) * * // 2. 业务侧注册调度器(handler 为任务处理函数) * sched := cachex.RegisterScheduler[MyData]("my_scheduler", handleFunc, * cachex.WithSchedulerQueueName("core:my_queue"), * cachex.WithSchedulerNamespace("core:my")) * * // 3. 业务侧入队/取消 * sched.EnqueueAt(ctx, &cachex.DelayTask[MyData]{Key: "k1", Data: d, ExecuteAt: t}) * sched.Cancel(ctx, "k1") * * // 4. bootstrap 阶段统一启停 * cachex.StartAllSchedulers(ctx) * cachex.StopAllSchedulers() * * Copyright (c) 2026 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-06 21:35:15 * @FilePath: \go-toolbox\cachex\\sharded.go * @Description: 分片缓存封装(ShardedHandler) * * 将缓存分为多个 shard,每个 shard 使用独立的 Handler 实例(例如多个 LRU) * 适用于降低单个实例的锁竞争或将负载分散到多个后端实例的场景 * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-05 22:55:22 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-06 21:56:49 * @FilePath: \go-toolbox\cachex\\twolevel.go * @Description: 两级缓存封装(TwoLevelHandler) * * 提供 L1(快速、本地)与 L2(容量大或远程)两级缓存组合:L1 命中直接返回, * L1 未命中时回退到 L2 并将数据提升(promote)到 L1, 写入支持同步写入(write-through) * 或异步回填策略 * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-06 22:35:20 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-06 22:35:20 * @FilePath: \go-toolbox\cachex\\validate.go * @Description: 缓存操作的通用验证 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 23:50:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-12-05 13:50:02 * @FilePath: \go-toolbox\cachex\\wrapper.go * @Description: 缓存包装器实现 * * 缓存包装器(CacheWrapper)是一个高阶函数,用于为任意数据加载函数添加Redis缓存功能。 * * 核心特性: * - 泛型支持:支持任意类型的数据缓存 * - 数据压缩:使用Zlib算法压缩缓存数据,节省Redis内存 * - 延迟双删:实现延迟双删策略,保证缓存一致性 * - 错误处理:优雅处理Redis连接错误和数据序列化错误 * - 并发安全:支持高并发访问 * * 使用示例: * loader := CacheWrapper(redisClient, "cache_key", dataLoaderFunc, time.Hour) * result, err := loader(ctx) * * Copyright (c) 2025 by kamalyes, All Rights Reserved.

Index

Constants

View Source
const (
	CompressionPrefix    = zipx.GzipPrefix    // 压缩消息前缀标记
	CompressionPrefixLen = zipx.GzipPrefixLen // 压缩前缀长度
)

压缩相关常量(使用 zipx 的常量)

View Source
const DefaultMaxEntries = 10000

防止无界内存增长:强制设置最小容量

Variables

View Source
var (
	// ErrNotFound 表示在缓存中找不到请求的键
	// 当尝试获取一个不存在的缓存项时返回此错误
	ErrNotFound = errors.New("key not found in cache")

	// ErrDataWrite 表示写入数据时发生错误
	// 当向缓存存储数据失败时返回此错误
	ErrDataWrite = errors.New("failed to write data to cache")

	// ErrDataRead 表示读取数据时发生错误
	// 当从缓存读取数据失败时返回此错误
	ErrDataRead = errors.New("failed to read data from cache")

	// ErrClosed 表示缓存已关闭
	// 当尝试在已关闭的缓存实例上执行操作时返回此错误
	ErrClosed = errors.New("cache is closed")

	// ErrInvalidKey 表示使用了无效的键
	// 当传入的缓存键为空或格式不正确时返回此错误
	ErrInvalidKey = errors.New("invalid cache key")

	// ErrInvalidValue 表示使用了无效的值
	// 当传入的缓存值为nil或格式不正确时返回此错误
	ErrInvalidValue = errors.New("invalid cache value")

	// ErrInvalidTTL 表示使用了无效的 TTL 值
	// 当传入的过期时间为负数或其他无效值时返回此错误
	ErrInvalidTTL = errors.New("invalid TTL value")

	// ErrCapacityExceeded 表示超出了缓存容量限制
	// 当缓存已达到最大容量限制无法存储更多数据时返回此错误
	ErrCapacityExceeded = errors.New("cache capacity exceeded")

	// ErrNotInitialized 表示缓存未正确初始化
	// 当尝试使用未初始化的缓存实例时返回此错误
	ErrNotInitialized = errors.New("cache not properly initialized")

	// ErrUnavailable 表示缓存服务暂时不可用(比如 Redis 连接断开)
	// 当底层存储服务(如Redis、Memcached等)连接失败或不可达时返回此错误
	ErrUnavailable = errors.New("cache service unavailable")

	// ErrTimeout 表示操作超时
	// 当缓存操作执行时间超过设定的超时时间时返回此错误
	ErrTimeout = errors.New("cache operation timed out")
)
View Source
var (
	ErrDelayQueueClosed  = errors.New("delay queue is closed")
	ErrDelayQueueRunning = errors.New("delay queue consumer is already running")
	ErrInvalidDelayTask  = errors.New("invalid delay task: key required and execute time required")
	ErrDelayTaskNotFound = errors.New("delay task not found")
)

延迟队列错误

View Source
var (
	ErrLockNotFound    = errors.New("lock not found")
	ErrLockNotObtained = errors.New("lock not obtained")
	ErrLockExpired     = errors.New("lock has expired")
	ErrLockNotOwned    = errors.New("lock not owned by this instance")
)
View Source
var (
	ErrChannelClosed      = fmt.Errorf("channel is closed")
	ErrCompressFailed     = fmt.Errorf("compress data failed")
	ErrPersistFailed      = fmt.Errorf("persist to redis failed")
	ErrRPushFailed        = fmt.Errorf("rpush failed")
	ErrPullFailed         = fmt.Errorf("pull from redis failed")
	ErrInvalidBLPopResult = fmt.Errorf("invalid blpop result")
	ErrDecompressFailed   = fmt.Errorf("decompress data failed")
	ErrUnknownPersistMode = fmt.Errorf("unknown persistence mode")
	ErrGetRedisLenFailed  = fmt.Errorf("failed to get redis queue length")
	ErrNoData             = fmt.Errorf("no data available") // 队列无数据(超时/空),用于零分配判断
)

DurableChannel 错误定义

Functions

func ClearAllKV

func ClearAllKV(ctx context.Context) error

ClearAllKV 清空所有已注册 KV 缓存(本地 + Redis),并广播 clear 消息到其他节点 并发执行各缓存的 Clear 操作,返回首个错误(不中断其余缓存) 适用于服务启动时重置缓存,清除 Redis 中已删除记录的残留字段

func GetKVMany

func GetKVMany[K comparable, V any](ctx context.Context, name string, keys []K) map[K]V

GetKVMany 批量获取已注册 KV 缓存的值的快捷封装 空 keys 或任何错误(未注册/查询失败)均返回 nil,适用于"读不到就用零值"的回显场景

cachex.GetKVMany[string, string](ctx, constants.KVGameLibrary, gameIDs)

func LockWithRetry

func LockWithRetry(ctx context.Context, client redis.UniversalClient, key string, config LockConfig, fn func() error) error

LockWithRetry 带重试的锁获取工具函数

func MutexLock

func MutexLock(ctx context.Context, client redis.UniversalClient, key string, ttl time.Duration, fn func() error) error

MutexLock 互斥锁工具函数,确保同时只有一个操作在执行

func NewDefaultCachexLogger

func NewDefaultCachexLogger() logger.ILogger

NewDefaultCachexLogger 创建默认配置的Cachex日志器

func NewRedisOptions

func NewRedisOptions(addr, password string, db int) *redis.Options

NewRedisOptions 创建推荐的Redis配置 这个函数设置了一些推荐的默认值以避免常见的警告和问题

func PublishJSON

func PublishJSON[T any](p *PubSub, ctx context.Context, channel string, message T) error

PublishJSON 发布JSON消息(泛型版本)

func RefreshAllKV

func RefreshAllKV(ctx context.Context) error

RefreshAllKV 从数据源刷新所有已注册 KV 缓存(清空本地后重新加载,写回 Redis,不广播) 并发执行各缓存的 Refresh 操作,返回首个错误(不中断其余缓存) 适用于服务启动时预热缓存,通常在 ClearAllKV 之后调用以确保缓存与数据库一致

func RefreshAndSwapAllKV

func RefreshAndSwapAllKV(ctx context.Context) error

RefreshAndSwapAllKV 原子刷新所有已注册 KV 缓存(先加载 → Lua 原子替换 Redis → 替换本地 → 广播) 并发执行各缓存的 RefreshAndSwap 操作,返回首个错误(不中断其余缓存) 适用于启动预热(WarmupAllKV 调用),消除 Clear→Refresh 空窗期

func RegisterKV

func RegisterKV[K comparable, V any](
	name string,
	loader KVLoader[K, V],
	opts ...KVOption,
)

RegisterKV 注册 KV 缓存(pbmo 风格)

使用者只需在初始化阶段调用一次,后续可通过 GetKV[K,V](name) 获取实例

cachex.SetGlobalRedisClient(gwglobal.REDIS)
cachex.RegisterKV[string, string]("game_library", repo.GameLibrary.LoadNameMap,
    cachex.WithKVNamespace("core:kv"))

注意:name 必须全局唯一,重复注册将 panic

func ResetAllModelKVLoadCache

func ResetAllModelKVLoadCache()

ResetAllModelKVLoadCache 重置所有已注册 ModelKVCache 的 loadAll 共享缓存 在 ClearAllKV 之前调用,确保后续 Refresh 从 DB 加载最新数据而非复用旧缓存

func ResetModelCacheRegistry

func ResetModelCacheRegistry()

ResetModelCacheRegistry 清空全局注册表(仅测试用)

func ResetModelKVRegistry

func ResetModelKVRegistry()

ResetModelKVRegistry 清空全局注册表(仅测试用)

func SetGlobalRedisClient

func SetGlobalRedisClient(client redis.UniversalClient)

SetGlobalRedisClient 注入全局 Redis 客户端 必须在调用 RegisterKV 之前完成注入,否则 RegisterKV 将 panic

func SetLogger

func SetLogger(l logger.ILogger)

SetLogger 注入全局日志记录器 必须在 RegisterKV 之前调用,所有后续注册的 KVCache 实例将复用此日志器 未调用时使用默认日志器 NewDefaultCachexLogger()

func SimplePublish

func SimplePublish(client redis.UniversalClient, channel string, message any) error

SimplePublish 简单发布消息

func SimpleSubscribe

func SimpleSubscribe(client redis.UniversalClient, channel string, handler MessageHandler) (*PubSub, *Subscriber, error)

SimpleSubscribe 简单订阅封装:内部 pubsub 不暴露配置,采用快速失败语义 启动重试窗口收窄为 2s(simple 场景 Redis 未就绪即快速返回错误,与服务级订阅的 30s 默认窗口/0 无限自愈语义区分) 警告:此函数创建的 PubSub 实例需要手动管理生命周期,使用完毕后需要调用 pubsub.Close(); 推荐使用 NewPubSub() + Subscribe() 以便更好地管理生命周期

func StartAllObjectPools

func StartAllObjectPools(ctx context.Context) error

StartAllObjectPools 启动所有已注册的对象池(通常无需调用,注册时已自动启动) 仅供未启用自动启动的场景使用

func StartAllSchedulers

func StartAllSchedulers(ctx context.Context) error

StartAllSchedulers 启动所有已注册的调度器(服务启动时调用) 任一启动失败立即返回错误,已启动的不会被回滚(可再次调用 StopAllSchedulers 清理)

func StopAllKV

func StopAllKV()

StopAllKV 停止所有已注册 KV 缓存的自动刷新(服务关闭时调用)

func StopAllObjectPools

func StopAllObjectPools() error

StopAllObjectPools 停止所有已注册的对象池(服务关闭时调用) 收集所有错误,返回第一个错误(其余错误仅记录日志)

func StopAllSchedulers

func StopAllSchedulers() error

StopAllSchedulers 停止所有已注册的调度器(服务关闭时调用) 收集所有错误,返回第一个错误(其余错误仅记录日志)

func ValidateBasicOp

func ValidateBasicOp(key []byte, initialized, closed bool) error

ValidateBasicOp 验证基本操作的参数(检查键、缓存状态)

func ValidateCapacity

func ValidateCapacity(current, max int) error

ValidateCapacity 验证是否超出容量限制

func ValidateClosed

func ValidateClosed(closed bool) error

ValidateClosed 验证缓存是否已关闭

func ValidateInitialized

func ValidateInitialized(initialized bool) error

ValidateInitialized 验证缓存是否已初始化

func ValidateKey

func ValidateKey(key []byte) error

ValidateKey 验证键是否有效

func ValidateTTL

func ValidateTTL(ttl time.Duration) error

ValidateTTL 验证 TTL 是否有效(允许 -1 表示无限期)

func ValidateValue

func ValidateValue(value []byte) error

ValidateValue 验证值是否有效

func ValidateWriteOp

func ValidateWriteOp(key, value []byte, initialized, closed bool) error

ValidateWriteOp 验证写操作的参数(检查键、值、缓存状态)

func ValidateWriteWithTTLOp

func ValidateWriteWithTTLOp(key, value []byte, ttl time.Duration, initialized, closed bool) error

ValidateWriteWithTTLOp 验证带 TTL 的写操作参数

func WarmupAllKV

func WarmupAllKV(ctx context.Context) error

WarmupAllKV 启动预热:重置 ModelKV 缓存 → 原子替换所有 KV 缓存 解决 autoRefresh 首次触发延迟(RefreshInterval=5min)期间缓存为空/陈旧的问题

流程:

  1. ResetAllModelKVLoadCache — 重置 ModelKV 共享 loadAll 缓存,强制下次从 DB 查询
  2. RefreshAndSwapAllKV — 原子替换所有 KV 缓存(先从 DB 加载,再 Lua 原子替换 Redis + 本地 + 广播)

与旧方案(Clear→Refresh)的区别:

  • 旧方案有空窗期:Clear DEL Redis 后、Refresh HSET 前,其他请求 cache miss → DB 雪崩
  • 新方案无空窗:先加载数据,再原子替换(DEL+HSET 一次 Lua),Redis 从旧值→新值无缝切换

返回首个错误(不中断其余缓存的预热),调用方根据日志判断是否需要重试 日志统一使用 globalLogger(未注入时 fallback 到默认日志器),无需调用方传参

func WithCache

func WithCache(ctx context.Context, c *CtxCache) context.Context

WithCache 把 CtxCache 写入 ctx

Types

type AdvancedCache

type AdvancedCache[T any] struct {
	// contains filtered or unexported fields
}

AdvancedCache 高级缓存包装器

func NewAdvancedCache

func NewAdvancedCache[T any](client redis.UniversalClient, config AdvancedCacheConfig) *AdvancedCache[T]

NewAdvancedCache 创建高级缓存

func (*AdvancedCache[T]) BatchGet

func (c *AdvancedCache[T]) BatchGet(ctx context.Context, keys []string) (map[string]T, error)

BatchGet 批量获取

func (*AdvancedCache[T]) BatchSet

func (c *AdvancedCache[T]) BatchSet(ctx context.Context, items map[string]T, ttl ...time.Duration) error

BatchSet 批量设置

func (*AdvancedCache[T]) Clear

func (c *AdvancedCache[T]) Clear(ctx context.Context, pattern string) error

Clear 清空指定模式的所有缓存

func (*AdvancedCache[T]) Close

func (c *AdvancedCache[T]) Close() error

Close 关闭缓存

func (*AdvancedCache[T]) Delete

func (c *AdvancedCache[T]) Delete(ctx context.Context, keys ...string) error

Delete 删除缓存

func (*AdvancedCache[T]) Exists

func (c *AdvancedCache[T]) Exists(ctx context.Context, keys ...string) (int64, error)

Exists 检查键是否存在

func (*AdvancedCache[T]) Expire

func (c *AdvancedCache[T]) Expire(ctx context.Context, key string, ttl time.Duration) error

Expire 设置键的过期时间

func (*AdvancedCache[T]) Get

func (c *AdvancedCache[T]) Get(ctx context.Context, key string) (T, bool, error)

Get 获取缓存

func (*AdvancedCache[T]) GetHotKeyManager

func (c *AdvancedCache[T]) GetHotKeyManager() *HotKeyManager

GetHotKeyManager 获取热key管理器

func (*AdvancedCache[T]) GetLockManager

func (c *AdvancedCache[T]) GetLockManager() *LockManager

GetLockManager 获取锁管理器

func (*AdvancedCache[T]) GetMetrics

func (c *AdvancedCache[T]) GetMetrics() *CacheMetrics

GetMetrics 获取缓存指标(返回原子快照,避免数据竞争)

func (*AdvancedCache[T]) GetOrSet

func (c *AdvancedCache[T]) GetOrSet(ctx context.Context, key string, fn func() (T, error), ttl ...time.Duration) (T, error)

GetOrSet 获取或设置缓存(如果不存在则设置)

func (*AdvancedCache[T]) GetQueue

func (c *AdvancedCache[T]) GetQueue() *QueueHandler

GetQueue 获取队列处理器

func (*AdvancedCache[T]) Keys

func (c *AdvancedCache[T]) Keys(ctx context.Context, pattern string) ([]string, error)

Keys 获取匹配模式的所有键

func (*AdvancedCache[T]) Ping

func (c *AdvancedCache[T]) Ping(ctx context.Context) error

Ping 测试连接

func (*AdvancedCache[T]) ResetMetrics

func (c *AdvancedCache[T]) ResetMetrics()

ResetMetrics 重置缓存指标(原子写入,避免替换指针导致数据竞争)

func (*AdvancedCache[T]) Set

func (c *AdvancedCache[T]) Set(ctx context.Context, key string, value T, ttl ...time.Duration) error

Set 设置缓存

func (*AdvancedCache[T]) TTL

func (c *AdvancedCache[T]) TTL(ctx context.Context, key string) (time.Duration, error)

TTL 获取键的TTL

func (*AdvancedCache[T]) Wrap

func (c *AdvancedCache[T]) Wrap(key string, fn CacheWrapperFunc[T], ttl ...time.Duration) CacheWrapperFunc[T]

Wrap 包装函数以添加缓存功能

type AdvancedCacheConfig

type AdvancedCacheConfig struct {
	Compression        CompressionType // 压缩类型
	MinSizeForCompress int             // 启用压缩的最小大小(字节)
	DefaultTTL         time.Duration   // 默认TTL
	Namespace          string          // 命名空间
	EnableMetrics      bool            // 是否启用指标统计
	Logger             logger.ILogger  // 日志记录器(可选,不设置则使用 NoOpLogger)
}

AdvancedCacheConfig 高级缓存配置

type AlertCallback

type AlertCallback func(event AlertEvent)

AlertCallback 预警回调函数 当队列长度达到阈值时触发

type AlertEvent

type AlertEvent struct {
	Level     AlertLevel // 预警级别
	QueueKey  string     // 队列键
	Length    int64      // 当前队列长度
	MaxSize   int64      // 最大队列长度
	Threshold int64      // 触发阈值
	Message   string     // 预警消息
	Timestamp time.Time  // 触发时间
}

AlertEvent 预警事件

type AlertLevel

type AlertLevel int

AlertLevel 预警级别

const (
	AlertLevelInfo     AlertLevel = iota // 信息级别
	AlertLevelWarning                    // 警告级别
	AlertLevelError                      // 错误级别
	AlertLevelCritical                   // 严重级别
)

func (AlertLevel) String

func (a AlertLevel) String() string

String 返回预警级别的字符串表示

type BatchLoader

type BatchLoader[K comparable, V any] func(ctx context.Context, keys []K) (map[K]V, error)

BatchLoader 按需批量回源加载器:按指定 keys 从数据源精准加载 K->V 映射 适用于"全量加载不可行"的场景(如跨服务 RPC 按需查询、大数据量表按主键查) 与 KVLoader 互斥可选:两者都配置时,KVLoader 用于 autoRefresh 全量预热,BatchLoader 用于 miss 时精准回源

type CacheAsideOperation

type CacheAsideOperation[T any] struct {
	// contains filtered or unexported fields
}

CacheAsideOperation 旁路缓存操作

func (*CacheAsideOperation[T]) Read

func (op *CacheAsideOperation[T]) Read() (T, error)

Read 读取数据

func (*CacheAsideOperation[T]) Write

func (op *CacheAsideOperation[T]) Write(value T) error

Write 写入数据(延迟双删模式)

type CacheBuilder

type CacheBuilder struct {
	// contains filtered or unexported fields
}

CacheBuilder 缓存构建器

func NewCacheBuilder

func NewCacheBuilder(redisClient redis.UniversalClient, namespace string) *CacheBuilder

NewCacheBuilder 创建缓存构建器

func (*CacheBuilder) Build

func (b *CacheBuilder) Build() *SmartCache

Build 构建缓存实例

func (*CacheBuilder) OnError

func (b *CacheBuilder) OnError(fn func(ctx context.Context, err error)) *CacheBuilder

OnError 设置错误回调

func (*CacheBuilder) OnMiss

func (b *CacheBuilder) OnMiss(fn func(ctx context.Context, key string) (interface{}, error)) *CacheBuilder

OnMiss 设置缓存未命中回调(数据加载器)

func (*CacheBuilder) OnSet

func (b *CacheBuilder) OnSet(fn func(ctx context.Context, key string, value interface{})) *CacheBuilder

OnSet 设置缓存设置后回调

func (*CacheBuilder) WithCompression

func (b *CacheBuilder) WithCompression(compType CompressionType) *CacheBuilder

WithCompression 启用压缩

func (*CacheBuilder) WithHotKey

func (b *CacheBuilder) WithHotKey() *CacheBuilder

WithHotKey 启用热key保护

func (*CacheBuilder) WithKeyPattern

func (b *CacheBuilder) WithKeyPattern(pattern string) *CacheBuilder

WithKeyPattern 设置key模板

func (*CacheBuilder) WithLock

func (b *CacheBuilder) WithLock(timeout time.Duration) *CacheBuilder

WithLock 启用分布式锁

func (*CacheBuilder) WithPubSub

func (b *CacheBuilder) WithPubSub() *CacheBuilder

WithPubSub 启用发布订阅

func (*CacheBuilder) WithRefreshThreshold

func (b *CacheBuilder) WithRefreshThreshold(threshold float64) *CacheBuilder

WithRefreshThreshold 设置自动刷新阈值

func (*CacheBuilder) WithTTL

func (b *CacheBuilder) WithTTL(ttl time.Duration) *CacheBuilder

WithTTL 设置默认过期时间

type CacheDistributedLock

type CacheDistributedLock struct {
	Timeout        time.Duration // 获取锁的超时时间(默认 500ms)
	Expiration     time.Duration // 锁的过期时间(默认 5s)
	EnableWatchdog bool          // 是否启用看门狗自动续期(默认 true)
}

CacheDistributedLock 分布式锁配置

type CacheFunc

type CacheFunc[T any] func(ctx context.Context) (T, error)

CacheFunc 是一个函数类型,用于表示返回数据和错误的数据加载函数。

泛型参数:

T: 数据加载函数返回的数据类型,可以是任意可序列化为JSON的类型

参数:

ctx: 上下文,用于控制超时和取消

返回值:

T: 加载的数据
error: 加载过程中可能出现的错误

func CacheWrapper

func CacheWrapper[T any](client redis.UniversalClient, key string, cacheFunc CacheFunc[T], expiration time.Duration, opts ...CacheOption) CacheFunc[T]

CacheWrapper 是一个高阶函数,用于为数据加载函数添加Redis缓存功能。

该函数实现了以下核心特性:

  1. 缓存查询:首先尝试从Redis获取缓存数据
  2. 数据压缩:使用Zlib算法压缩缓存数据,减少内存使用
  3. 延迟双删:实现延迟双删策略,防止并发写入导致的缓存不一致
  4. 错误处理:区分Redis连接错误和键不存在错误,优雅降级

缓存流程:

  1. 尝试从Redis获取缓存数据
  2. 如果缓存存在且有效,解压缩并反序列化返回
  3. 如果缓存不存在或无效,执行原始数据加载函数
  4. 将加载的数据序列化、压缩后存储到Redis
  5. 执行延迟双删策略确保缓存一致性

延迟双删策略:

  • 第一次删除:在设置新缓存前删除旧缓存
  • 设置缓存:存储新的缓存数据
  • 延迟删除:100ms后再次删除缓存并重新设置,防止并发问题

泛型参数:

T: 缓存数据的类型,必须支持JSON序列化

参数:

client: Redis客户端实例
key: 缓存键名,建议使用有意义的命名规范
cacheFunc: 数据加载函数,当缓存不存在时调用
expiration: 缓存过期时间

返回值:

返回一个缓存包装后的数据加载函数,该函数具有相同的签名但增加了缓存功能

使用示例:

创建用户数据加载器
userLoader := func(ctx context.Context) (*User, error) {
    return getUserFromDB(ctx, userID)
}

包装为缓存加载器
cachedLoader := CacheWrapper(client, "user:123", userLoader, time.Hour)

使用缓存加载器
user, err := cachedLoader(ctx)

注意事项:

  • 确保数据类型T支持JSON序列化
  • 缓存键名应该具有唯一性和可读性
  • 合理设置过期时间以平衡性能和数据一致性
  • 大对象缓存会消耗更多内存,即使有压缩
  • 可通过 WithForceRefresh(true) 强制刷新缓存

func CacheWrapperWithIndex

func CacheWrapperWithIndex[T any](
	manager *CacheIndexManager,
	idxKey string,
	client redis.UniversalClient,
	key string,
	cacheFunc CacheFunc[T],
	expiration time.Duration,
	opts ...CacheOption,
) CacheFunc[T]

CacheWrapperWithIndex 带自动索引注册的 CacheWrapper 在执行 CacheWrapper 的同时自动将缓存键注册到指定索引集合 这是推荐的缓存+索引一体化入口,用户无需手动调用 Register

使用方式:

loader := cachex.CacheWrapperWithIndex(mgr, "idx:tenant_options", redisClient, cacheKey, loadFunc, ttl, opts...)
result, err := loader(ctx)  // 缓存读取+索引注册一步完成

type CacheIndexManager

type CacheIndexManager struct {
	// contains filtered or unexported fields
}

CacheIndexManager 缓存索引管理器 基于索引集合(Redis Set)追踪缓存键,支持按分组原子删除

使用方式:

mgr := cachex.NewCacheIndexManager(redisClient)

// 写缓存时自动注册索引
loader := cachex.CacheWrapperWithIndex(mgr, "idx:tenant", redisClient, "cache:key", loadFunc, time.Minute)
result, err := loader(ctx)  // 缓存+索引注册一步完成

// 删缓存时按分组原子删除
mgr.DeleteByIndex(ctx, "idx:tenant")  // 删除该索引下所有缓存键

func NewCacheIndexManager

func NewCacheIndexManager(client redis.UniversalClient) *CacheIndexManager

NewCacheIndexManager 创建缓存索引管理器

func (*CacheIndexManager) DeleteByIndex

func (m *CacheIndexManager) DeleteByIndex(ctx context.Context, idxKeys ...string) (int64, error)

DeleteByIndex 根据索引集合原子删除所有关联缓存键 使用Lua脚本保证原子性,避免SCAN操作 返回删除的缓存键数量

func (*CacheIndexManager) DeleteByKeys

func (m *CacheIndexManager) DeleteByKeys(ctx context.Context, keys ...string) error

DeleteByKeys 按缓存键直接删除缓存(用于已知确切键名的场景)

func (*CacheIndexManager) GetIndexMembers

func (m *CacheIndexManager) GetIndexMembers(ctx context.Context, idxKey string) ([]string, error)

GetIndexMembers 获取索引集合中的所有缓存键

func (*CacheIndexManager) NewIndexGroup

func (m *CacheIndexManager) NewIndexGroup(idxKeys ...string) *IndexGroup

NewIndexGroup 创建索引分组

func (*CacheIndexManager) Register

func (m *CacheIndexManager) Register(ctx context.Context, idxKey string, cacheKeys ...string)

Register 将缓存键注册到指定的索引集合中 写入缓存时调用,将实际缓存键记录到对应分类的索引集合

type CacheMetrics

type CacheMetrics struct {
	Hits           int64 `json:"hits"`
	Misses         int64 `json:"misses"`
	Sets           int64 `json:"sets"`
	Deletes        int64 `json:"deletes"`
	Compressions   int64 `json:"compressions"`
	Decompressions int64 `json:"decompressions"`
	TotalSize      int64 `json:"total_size"`
}

CacheMetrics 缓存指标

type CacheOption

type CacheOption func(*CacheOptions)

CacheOption 缓存选项函数类型

func Combine

func Combine(opts ...CacheOption) CacheOption

Combine 组合多个选项为一个选项

参数:

opts: 要组合的选项列表

使用场景:

  • 将多个相关选项组合成一个预设
  • 创建可重用的选项组合
  • 简化选项传递

示例:

vipPreset := Combine(
    WithTTL(time.Hour * 24),
    WithRetry(3),
    WithAsyncUpdate(),
)

func Match

func Match(cases []Case, defaultOpt ...CacheOption) CacheOption

Match 多条件匹配选项构建器 - 类似 switch-case

参数:

cases: 条件-选项对的切片
defaultOpt: 所有条件都不满足时的默认选项(可选)

使用场景:

  • 多个互斥条件的选项选择
  • 替代复杂的 if-else-if 链
  • 提高代码可读性

示例:

Match([]Case{
    {Condition: level == "VIP", Opt: WithTTL(time.Hour * 24)},
    {Condition: level == "Premium", Opt: WithTTL(time.Hour * 12)},
}, WithTTL(time.Hour))

func When

func When(condition bool, opt CacheOption) CacheOption

When 条件选项构建器 - 当条件为 true 时应用选项

参数:

condition: 条件表达式
opt: 当条件为 true 时应用的选项

使用场景:

  • 简化条件选项的构建代码
  • 提高代码可读性
  • 函数式编程风格

示例:

When(isVIP, WithTTL(time.Hour * 24))
When(needRefresh, WithForceRefresh(true))

func WhenThen

func WhenThen(condition bool, thenOpt, elseOpt CacheOption) CacheOption

WhenThen 条件选项构建器 - 根据条件选择不同的选项

参数:

condition: 条件表达式
thenOpt: 当条件为 true 时应用的选项
elseOpt: 当条件为 false 时应用的选项

使用场景:

  • 二选一的选项场景
  • 简化 if-else 逻辑
  • 函数式编程风格

示例:

WhenThen(isVIP, WithTTL(time.Hour * 24), WithTTL(time.Hour))

func WithAsyncUpdate

func WithAsyncUpdate() CacheOption

WithAsyncUpdate 使用异步方式更新缓存

使用场景:

  • 非关键数据,允许短暂的数据延迟
  • 高并发场景,减少阻塞
  • 缓存更新耗时较长的情况

func WithCachePenetration

func WithCachePenetration[T any](defaultValue T) CacheOption

WithCachePenetration 启用缓存穿透保护,当数据不存在时缓存默认值

参数:

defaultValue: 数据不存在时要缓存的默认值(必须与泛型类型T兼容)
ttl: 默认值的缓存时长(可选,nil 时使用 5 分钟)

使用场景:

  • 防止缓存穿透攻击(大量查询不存在的数据)
  • 减少数据库压力(避免重复查询不存在的数据)
  • 提高系统稳定性

注意:

  • 默认值使用与正常数据相同的 TTL
  • 如需为默认值设置不同的 TTL,可组合使用 WithTTL

示例:

查询用户设置,不存在时缓存空对象
WithCachePenetration(&models.AgentSettingsModel{})

查询用户信息,不存在时缓存默认值并保留 5 分钟
WithCachePenetration(&User{ID: -1}), WithTTL(5*time.Minute)

func WithDistributedLock

func WithDistributedLock(lock *CacheDistributedLock) CacheOption

WithDistributedLock 启用分布式锁防止缓存击穿

参数:

config: 分布式锁配置(可选,nil 时使用默认配置)

默认配置:

  • Timeout: 500ms(获取锁超时时间)
  • Expiration: 5s(锁过期时间)
  • EnableWatchdog: true(启用看门狗自动续期)

使用场景:

  • 高并发场景下防止缓存击穿(多个请求同时查询 DB)
  • 第一个请求获取锁后查询 DB,其他请求等待并从缓存读取
  • 看门狗机制自动续期,防止长时间查询导致锁过期

示例:

使用默认配置
WithDistributedLock(nil)

自定义配置
WithDistributedLock(&CacheDistributedLock{
    Timeout:        1 * time.Second,
    Expiration:     10 * time.Second,
    EnableWatchdog: true,
})

快速配置(禁用看门狗)
WithDistributedLock(&CacheDistributedLock{EnableWatchdog: false})

func WithForceRefresh

func WithForceRefresh(force bool) CacheOption

WithForceRefresh 设置是否强制刷新缓存

参数:

force: true 表示强制从数据源加载,false 表示优先使用缓存

使用场景:

  • 管理员操作需要最新数据
  • 定时任务刷新缓存
  • 数据变更后立即更新缓存

func WithJitter

func WithJitter(percent float64) CacheOption

WithJitter 设置 TTL 随机抖动百分比,避免缓存雪崩

参数:

percent: 抖动百分比(0-1),例如 0.005 表示 ±0.5% 的随机抖动

使用场景:

  • 大量缓存同时创建,避免同时失效
  • 防止缓存雪崩
  • 分散缓存失效时间

示例:

WithJitter(0.005)  // ±0.5% 抖动,1小时缓存会在 59.7-60.3 分钟之间随机失效
WithJitter(0.01)   // ±1% 抖动,1小时缓存会在 59.4-60.6 分钟之间随机失效
WithJitter(0.05)   // ±5% 抖动,1小时缓存会在 57-63 分钟之间随机失效

func WithRetry

func WithRetry(times int) CacheOption

WithRetry 设置 Redis 操作失败时重试

参数:

times: 重试次数(建议不超过 3 次)

使用场景:

  • Redis 网络不稳定
  • 关键数据必须缓存成功
  • 提高缓存可靠性

func WithTTL

func WithTTL(ttl time.Duration) CacheOption

WithTTL 覆盖默认的缓存过期时间

参数:

ttl: 自定义的缓存过期时间

使用场景:

  • 动态调整缓存时长
  • 不同条件下使用不同的 TTL
  • VIP 用户使用更长的缓存时间

func WithoutCompression

func WithoutCompression() CacheOption

WithoutCompression 跳过数据压缩

使用场景:

  • 数据量很小(如布尔值、小字符串)
  • 数据已经压缩过(如图片、视频链接)
  • 需要极致性能,压缩开销大于收益

type CacheOptions

type CacheOptions struct {
	ForceRefresh         bool                  // 是否强制刷新缓存(清除缓存重新获取)
	TTLOverride          *time.Duration        // 覆盖默认 TTL(为 nil 时使用默认值)
	SkipCompress         bool                  // 跳过压缩(用于小数据或已压缩的数据)
	UseAsync             bool                  // 使用异步更新缓存(适用于非关键数据)
	RetryOnError         bool                  // Redis 错误时重试(默认不重试)
	RetryTimes           int                   // 重试次数(默认 0)
	JitterPercent        *float64              // TTL 随机抖动百分比(0-1,nil 时使用默认 0.005 即 ±0.5%)
	CachePenetration     bool                  // 是否启用缓存穿透保护(false=不保护,true=缓存默认值)
	DefaultValue         interface{}           // 缓存穿透时的默认值(需要与泛型类型T匹配)
	CacheDistributedLock *CacheDistributedLock // 分布式锁配置(nil 表示不启用)
}

CacheOptions 缓存选项配置

type CachePattern

type CachePattern[T any] struct {
	// contains filtered or unexported fields
}

CachePattern 缓存模式封装(生产级别)

func NewCachePattern

func NewCachePattern[T any](cache *MultiLevelCache[T]) *CachePattern[T]

NewCachePattern 创建缓存模式

func (*CachePattern[T]) CacheAside

func (p *CachePattern[T]) CacheAside(
	ctx context.Context,
	key string,
	dbLoader func() (T, error),
	dbWriter func(T) error,
) *CacheAsideOperation[T]

CacheAside 旁路缓存模式(Cache-Aside) 读:先读缓存,未命中则读DB并写入缓存 写:先写DB,再删除缓存(延迟双删)

func (*CachePattern[T]) ReadThrough

func (p *CachePattern[T]) ReadThrough(ctx context.Context, key string, dbLoader func() (T, error)) (T, error)

ReadThrough 穿透读缓存模式

func (*CachePattern[T]) WriteBehind

func (p *CachePattern[T]) WriteBehind(ctx context.Context, key string, value T, dbWriter func(T) error) error

WriteBehind 异步写缓存模式(Write-Behind/Write-Back)

func (*CachePattern[T]) WriteThrough

func (p *CachePattern[T]) WriteThrough(ctx context.Context, key string, value T, dbWriter func(T) error) error

WriteThrough 穿透写缓存模式

type CacheStrategy

type CacheStrategy struct {
	// 基础配置
	Namespace   string
	KeyPattern  string        // key模板,如: "user:{user_id}"
	DefaultTTL  time.Duration // 默认过期时间
	Compression CompressionType

	// 高级功能
	EnableHotKey     bool          // 启用热key保护
	EnableLock       bool          // 启用分布式锁
	EnablePubSub     bool          // 启用发布订阅
	LockTimeout      time.Duration // 锁超时时间
	RefreshThreshold float64       // 刷新阈值(0-1),剩余TTL低于此值时自动刷新

	// 回调函数
	OnCacheMiss func(ctx context.Context, key string) (interface{}, error) // 缓存未命中时的回调
	OnCacheSet  func(ctx context.Context, key string, value interface{})   // 缓存设置后的回调
	OnError     func(ctx context.Context, err error)                       // 错误回调
}

CacheStrategy 缓存策略

type CacheType

type CacheType string

CacheType 定义支持的缓存类型

const (
	CacheLRU          CacheType = "lru"
	CacheLRUOptimized CacheType = "lru_optimized"
	CacheRistretto    CacheType = "ristretto"
	CacheRedis        CacheType = "redis"
	CacheExpiring     CacheType = "expiring"
)

type CacheWrapperFunc

type CacheWrapperFunc[T any] func(ctx context.Context) (T, error)

CacheWrapper 缓存包装器函数类型

type Case

type Case struct {
	Condition bool        // 条件
	Opt       CacheOption // 选项
}

Case 条件-选项对

func NewCase

func NewCase(condition bool, opt CacheOption) Case

NewCase 创建条件-选项对

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client 是支持 context 的缓存客户端

func NewClient

func NewClient(ctx context.Context, cfg *ClientConfig) (*Client, error)

NewClient 根据配置创建带 context 能力的缓存客户端

func NewExpiringClient

func NewExpiringClient(ctx context.Context, cleanupInterval time.Duration) (*Client, error)

NewExpiringClient 创建过期缓存客户端的便利函数

func NewLRUClient

func NewLRUClient(ctx context.Context, capacity int) (*Client, error)

NewLRUClient 创建 LRU 缓存客户端的便利函数

func NewLRUOptimizedClient

func NewLRUOptimizedClient(ctx context.Context, capacity int) (*Client, error)

NewLRUOptimizedClient 创建优化版本 LRU 缓存客户端的便利函数

func NewRedisClient

func NewRedisClient(ctx context.Context, opts *redis.Options) (*Client, error)

NewRedisClient 创建 Redis 缓存客户端的便利函数

func NewRistrettoClient

func NewRistrettoClient(ctx context.Context, config *RistrettoConfig) (*Client, error)

NewRistrettoClient 创建 Ristretto 缓存客户端的便利函数

func (*Client) BatchGet

func (c *Client) BatchGet(keys [][]byte) ([][]byte, []error)

BatchGet 实现Handler.BatchGet

func (*Client) BatchGetWithCtx

func (c *Client) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取多个键的值(支持context)

func (*Client) Close

func (c *Client) Close() error

Close 实现Handler.Close

func (*Client) Del

func (c *Client) Del(key []byte) error

Del 实现Handler.Del

func (*Client) DelWithCtx

func (c *Client) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 删除缓存键(支持context)

func (*Client) Get

func (c *Client) Get(key []byte) ([]byte, error)

Get 实现Handler.Get

func (*Client) GetConfig

func (c *Client) GetConfig() ClientConfig

GetConfig 返回客户端配置(只读)

func (*Client) GetOrCompute

func (c *Client) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 实现Handler.GetOrCompute

func (*Client) GetOrComputeWithCtx

func (c *Client) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取或计算缓存值(带去重,支持context)

func (*Client) GetTTL

func (c *Client) GetTTL(key []byte) (time.Duration, error)

GetTTL 实现Handler.GetTTL

func (*Client) GetTTLWithCtx

func (c *Client) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 获取键的剩余TTL(支持context)

func (*Client) GetWithCtx

func (c *Client) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 从缓存中获取值(支持context)

func (*Client) Set

func (c *Client) Set(key, value []byte) error

Set 实现Handler.Set

func (*Client) SetWithCtx

func (c *Client) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 设置缓存值(支持context)

func (*Client) SetWithTTL

func (c *Client) SetWithTTL(key, value []byte, ttl time.Duration) error

SetWithTTL 实现Handler.SetWithTTL

func (*Client) SetWithTTLAndCtx

func (c *Client) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存值(支持context)

func (*Client) Stats

func (c *Client) Stats() map[string]interface{}

Stats 实现Handler.Stats(不带context)

func (*Client) StatsWithCtx

func (c *Client) StatsWithCtx(ctx context.Context) map[string]interface{}

StatsWithCtx 返回缓存统计信息(支持context)

func (*Client) WithContext

func (c *Client) WithContext(ctx context.Context) context.Context

WithContext 在上下文中嵌入当前客户端

type ClientConfig

type ClientConfig struct {
	Type            CacheType
	Capacity        int              // for lru/expiring/ristretto
	CleanupInterval time.Duration    // for expiring cache
	RedisConfig     *redis.Options   // for redis
	RistrettoConfig *RistrettoConfig // for ristretto
}

ClientConfig 用于统一配置入口

type CompressionType

type CompressionType string

CompressionType 压缩类型

const (
	CompressionNone CompressionType = "none"
	CompressionGzip CompressionType = "gzip"
)

type CtxCache

type CtxCache struct {
	// contains filtered or unexported fields
}

CtxCache 是一个基于 context 的缓存封装,包装已有的 Handler 它提供支持 context 取消的 GetOrCompute(带 loader)以及并发去重(singleflight)

func FromContext

func FromContext(ctx context.Context) *CtxCache

FromContext 从 ctx 中读取 CtxCache(若不存在返回 nil)

func NewCtxCache

func NewCtxCache(h Handler) *CtxCache

NewCtxCache 用现有的 Handler 创建 CtxCache

func (*CtxCache) BatchGet

func (c *CtxCache) BatchGet(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGet 批量获取多个键的值

func (*CtxCache) Close

func (c *CtxCache) Close() error

Close 关闭底层 handler(如果底层实现需要关闭)

func (*CtxCache) Del

func (c *CtxCache) Del(ctx context.Context, key []byte) error

Del 删除键

func (*CtxCache) Get

func (c *CtxCache) Get(ctx context.Context, key []byte) ([]byte, error)

Get 直接从底层缓存读取

func (*CtxCache) GetOrCompute

func (c *CtxCache) GetOrCompute(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrCompute:先尝试从缓存读取;若未命中,则使用 singleflight 保证并发时只会执行一次 loader loader 应该尊重传入的 ctx(以便在 ctx 取消时尽早停止) - key: 缓存键(字节切片) - ttl: 保存到缓存的 TTL(<=0 表示不设置 TTL) - loader: 计算值的函数,接收同一个 ctx

func (*CtxCache) GetTTL

func (c *CtxCache) GetTTL(ctx context.Context, key []byte) (time.Duration, error)

GetTTL 获取键的剩余生存时间

func (*CtxCache) Set

func (c *CtxCache) Set(ctx context.Context, key, value []byte) error

Set 直接写入底层缓存(无 TTL)

func (*CtxCache) SetWithTTL

func (c *CtxCache) SetWithTTL(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTL 写入缓存并设置 TTL

func (*CtxCache) Stats

func (c *CtxCache) Stats() map[string]interface{}

Stats 返回缓存统计信息

type DataLoader

type DataLoader[K comparable, V any] interface {
	Load(ctx context.Context) (map[K]V, error)
}

DataLoader 数据加载器接口

type DeadLetterQueue

type DeadLetterQueue[T any] interface {
	// Push 将数据推入死信队列
	// queueKey: 队列键(如 "message:user_offline", "task:timeout" 等)
	// data: 要存储的数据
	Push(ctx context.Context, queueKey string, data T) error

	// GetItems 获取死信队列数据(不移除)
	// queueKey: 队列键
	// count: 获取的数据数量
	GetItems(ctx context.Context, queueKey string, count int64) ([]T, error)

	// GetLength 获取死信队列长度
	// queueKey: 队列键
	GetLength(ctx context.Context, queueKey string) (int64, error)

	// Remove 从死信队列中移除数据
	// queueKey: 队列键
	// count: 移除的数据数量(从队列头部开始)
	Remove(ctx context.Context, queueKey string, count int64) error

	// Clear 清空指定的死信队列
	// queueKey: 队列键
	Clear(ctx context.Context, queueKey string) error

	// SetAlertCallback 设置预警回调
	// callback: 预警回调函数
	SetAlertCallback(callback AlertCallback)

	// SetAlertThresholds 设置预警阈值
	// warning: 警告阈值(队列长度百分比,如 0.6 表示 60%)
	// error: 错误阈值(队列长度百分比,如 0.8 表示 80%)
	// critical: 严重阈值(队列长度百分比,如 0.95 表示 95%)
	SetAlertThresholds(warning, error, critical float64)
}

DeadLetterQueue 死信队列接口(泛型) T: 存储的数据类型

func NewDeadLetterQueue

func NewDeadLetterQueue[T any](queueHandler *QueueHandler, config DeadLetterQueueConfig) DeadLetterQueue[T]

NewDeadLetterQueue 创建死信队列 示例:

queueHandler := cachex.NewQueueHandler(client, "dlq:", queueConfig)
config := cachex.DeadLetterQueueConfig{
    MaxSize: 1000,
    WarningThreshold: 0.6,
    ErrorThreshold: 0.8,
    CriticalThreshold: 0.95,
}
dlq := cachex.NewDeadLetterQueue[*MyData](queueHandler, config)

type DeadLetterQueueConfig

type DeadLetterQueueConfig struct {
	MaxSize           int64         // 队列最大长度
	AlertCallback     AlertCallback // 预警回调(可选)
	WarningThreshold  float64       // 警告阈值(默认 0.6,即 60%)
	ErrorThreshold    float64       // 错误阈值(默认 0.8,即 80%)
	CriticalThreshold float64       // 严重阈值(默认 0.95,即 95%)
}

DeadLetterQueueConfig 死信队列配置

type DelayConsumerOptions

type DelayConsumerOptions struct {
	// OverrideMaxRetries 覆盖最大重试次数(>0 生效,0 表示用队列配置)
	OverrideMaxRetries int
	// OverrideRetryDelay 覆盖重试延迟(>0 生效,0 表示用队列配置)
	OverrideRetryDelay time.Duration
}

DelayConsumerOptions 消费者选项(覆盖队列级配置)

type DelayQueue

type DelayQueue[T any] struct {
	// contains filtered or unexported fields
}

DelayQueue 分布式延迟队列

基于 Redis ZSET(score=执行时间戳)+ Hash(存储任务体)实现, 通过 Lua 脚本保证多实例下的原子出队,适合跨实例的延迟任务协调。

func NewDelayQueue

func NewDelayQueue[T any](client redis.UniversalClient, config ...DelayQueueConfig) *DelayQueue[T]

NewDelayQueue 创建延迟队列 client 必须是非 nil 的 Redis 客户端;config 为空时使用默认配置

func (*DelayQueue[T]) Cancel

func (q *DelayQueue[T]) Cancel(ctx context.Context, queueName, key string) (bool, error)

Cancel 取消未执行的延迟任务 返回是否成功移除(false 表示任务不存在或已被消费)

func (*DelayQueue[T]) DeadLength

func (q *DelayQueue[T]) DeadLength(ctx context.Context, queueName string) (int64, error)

DeadLength 返回死信队列长度

func (*DelayQueue[T]) EnqueueAt

func (q *DelayQueue[T]) EnqueueAt(ctx context.Context, queueName string, task *DelayTask[T]) error

EnqueueAt 在指定时间执行任务 如果任务 Key 已存在,会覆盖更新执行时间(重新调度)

func (*DelayQueue[T]) EnqueueWithDelay

func (q *DelayQueue[T]) EnqueueWithDelay(ctx context.Context, queueName string, task *DelayTask[T], delay time.Duration) error

EnqueueWithDelay 延迟指定时间后执行(ExecuteAt 会被覆盖为 now+delay)

func (*DelayQueue[T]) GetDeadTasks

func (q *DelayQueue[T]) GetDeadTasks(ctx context.Context, queueName string, offset, limit int64) ([]*DelayTask[T], error)

GetDeadTasks 获取死信队列任务列表(分页)

func (*DelayQueue[T]) GetTask

func (q *DelayQueue[T]) GetTask(ctx context.Context, queueName, key string) (*DelayTask[T], error)

GetTask 获取任务详情(未执行的)

func (*DelayQueue[T]) Length

func (q *DelayQueue[T]) Length(ctx context.Context, queueName string) (int64, error)

Length 返回 ready 队列中待执行的任务数(兼容方法,等同 ReadyLength)

func (*DelayQueue[T]) ProcessingLength

func (q *DelayQueue[T]) ProcessingLength(ctx context.Context, queueName string) (int64, error)

ProcessingLength 返回 processing 中处理中(未 ACK)的任务数 持续增长通常意味着消费者处理过慢或 Pod 频繁崩溃未 ACK

func (*DelayQueue[T]) ReadyLength

func (q *DelayQueue[T]) ReadyLength(ctx context.Context, queueName string) (int64, error)

ReadyLength 返回 ready 队列中待执行的任务数

func (*DelayQueue[T]) StartConsumer

func (q *DelayQueue[T]) StartConsumer(
	ctx context.Context,
	queueName string,
	handler func(context.Context, *DelayTask[T]) error,
	opts ...DelayConsumerOptions,
) error

StartConsumer 启动消费者 goroutine 同一队列名重复调用会返回 ErrDelayQueueRunning handler 返回 error 时任务会重新入队(带指数退避延迟),超过最大重试次数后进入死信队列

func (*DelayQueue[T]) Stop

func (q *DelayQueue[T]) Stop() error

Stop 停止所有消费者并等待在途任务处理完成

func (*DelayQueue[T]) StopConsumer

func (q *DelayQueue[T]) StopConsumer(queueName string)

StopConsumer 停止指定队列的消费者(不等待在途任务)

type DelayQueueConfig

type DelayQueueConfig struct {
	Namespace         string        // Redis 键命名空间前缀,默认 "delayq"
	PollInterval      time.Duration // 消费者轮询间隔,默认 1s
	BatchSize         int64         // 每次轮询最多拉取的到期任务数,默认 10
	Concurrency       int           // 单实例内并发处理任务数,默认 5(Ordered=true 时忽略)
	MaxRetries        int           // 最大重试次数(不含首次执行),默认 3
	RetryDelay        time.Duration // 失败重试基础延迟,默认 5s(实际按指数退避:delay * 2^retry)
	VisibilityTimeout time.Duration // 可见性超时:任务出队后多久未 ACK 视为失败回归队列,默认 5m
	Ordered           bool          // 顺序模式:同一 queue 内任务按到期时间串行处理,禁用 WorkerPool 并发
	MaxReadySize      int64         // ready 堆积告警阈值,超过时记录 Warn 日志,默认 10000(0 表示不检查)
	Logger            logger.ILogger
}

DelayQueueConfig 延迟队列配置

func DefaultDelayQueueConfig

func DefaultDelayQueueConfig() DelayQueueConfig

DefaultDelayQueueConfig 返回默认配置

type DelayTask

type DelayTask[T any] struct {
	Key        string    `json:"key"`         // 唯一标识,用于去重和取消
	Data       T         `json:"data"`        // 任务数据
	ExecuteAt  time.Time `json:"execute_at"`  // 执行时间(到期时间)
	RetryCount int       `json:"retry_count"` // 已重试次数
}

DelayTask 延迟任务(对外暴露)

type DistributedLock

type DistributedLock struct {
	// contains filtered or unexported fields
}

DistributedLock 分布式锁

func NewDistributedLock

func NewDistributedLock(client redis.UniversalClient, key string, config LockConfig) *DistributedLock

NewDistributedLock 创建分布式锁

func (*DistributedLock) Extend

func (l *DistributedLock) Extend(ctx context.Context, ttl time.Duration) error

Extend 延长锁的TTL

func (*DistributedLock) GetStats

func (l *DistributedLock) GetStats(ctx context.Context) (*LockStats, error)

func (*DistributedLock) IsLocked

func (l *DistributedLock) IsLocked(ctx context.Context) (bool, error)

IsLocked 检查锁是否仍然有效

func (*DistributedLock) Lock

func (l *DistributedLock) Lock(ctx context.Context) error

Lock 获取锁(阻塞)

func (*DistributedLock) LockWithTimeout

func (l *DistributedLock) LockWithTimeout(ctx context.Context, timeout time.Duration) error

LockWithTimeout 带超时的获取锁

func (*DistributedLock) OnAfterExtend

func (l *DistributedLock) OnAfterExtend(fn func(ctx context.Context, err error)) *DistributedLock

OnAfterExtend 设置续期后置钩子 watchdog 在 Extend 完成后执行,err 为 Extend 的返回错误(nil 表示续期成功) 可用于续期结果监控、告警、指标采集

func (*DistributedLock) OnBeforeExtend

func (l *DistributedLock) OnBeforeExtend(fn func(ctx context.Context)) *DistributedLock

OnBeforeExtend 设置续期前置钩子 watchdog 在 IsLocked 确认锁仍有效后、Extend 调用前执行 可用于续期前置检查、监控指标采集、自定义逻辑注入

func (*DistributedLock) TTL

TTL 获取锁的剩余TTL

func (*DistributedLock) TryLock

func (l *DistributedLock) TryLock(ctx context.Context) (bool, error)

TryLock 尝试获取锁(非阻塞)

func (*DistributedLock) Unlock

func (l *DistributedLock) Unlock(ctx context.Context) error

Unlock 释放锁

func (*DistributedLock) WithLogger

func (c *DistributedLock) WithLogger(logger logger.ILogger) *DistributedLock

WithLogger 设置日志记录器

type DurableChannel

type DurableChannel[T any] struct {
	// contains filtered or unexported fields
}

DurableChannel 分布式可恢复的持久化 Channel

func NewDurableChannel

func NewDurableChannel[T any](client redis.UniversalClient, config DurableChannelConfig) *DurableChannel[T]

NewDurableChannel 创建持久化 Channel

这是一个通用的持久化消息队列,适用于多种场景:

示例 1:WebSocket 消息队列(单机模式)

ch := cachex.NewDurableChannel[*Message](redisClient, cachex.DurableChannelConfig{
    Name: "user:123:messages",
    BufferSize: 100,
    PersistenceMode: cachex.PersistHybrid,
})
defer ch.Close()

示例 2:分布式任务队列(使用 WorkerID 隔离)

import "github.com/HitGameAI/apex-toolbox/pkg/osx"

ch := cachex.NewDurableChannel[*Task](redisClient, cachex.DurableChannelConfig{
    Name: "worker:tasks",
    WorkerID: osx.GetWorkerId(), // 自动获取节点 ID(支持 K8s)
    WorkerCount: 5,
    PersistenceMode: cachex.PersistHybrid,
})

示例 3:事件总线

ch := cachex.NewDurableChannel[Event](redisClient, cachex.DurableChannelConfig{
    Name: "events:user-actions",
    Namespace: "myapp",
})

示例 4:日志收集

ch := cachex.NewDurableChannel[LogEntry](redisClient, cachex.DurableChannelConfig{
    Name: "logs:application",
    BufferSize: 1000,
    PersistenceMode: cachex.PersistAsync,
})

使用方式:

// 发送消息
ch.Send(ctx, data)

// 接收消息
msg := <-ch.Receive()

func (*DurableChannel[T]) Close

func (dc *DurableChannel[T]) Close() error

Close 关闭 Channel

func (*DurableChannel[T]) GetConfig

func (dc *DurableChannel[T]) GetConfig() DurableChannelConfig

GetConfig 获取配置信息

func (*DurableChannel[T]) GetQueueKey

func (dc *DurableChannel[T]) GetQueueKey() string

GetQueueKey 获取当前配置的队列 Key

func (*DurableChannel[T]) Len

func (dc *DurableChannel[T]) Len() (int64, error)

Len 获取总队列长度(内存 + Redis)

func (*DurableChannel[T]) MemLen

func (dc *DurableChannel[T]) MemLen() int

MemLen 获取内存队列长度 受限于内存大小,通常不会超过 int 的范围(在 64 位系统上是 2^31-1)

func (*DurableChannel[T]) Receive

func (dc *DurableChannel[T]) Receive() <-chan T

Receive 接收消息(类似 <-channel)

func (*DurableChannel[T]) RedisLen

func (dc *DurableChannel[T]) RedisLen() (int64, error)

RedisLen 获取 Redis 队列长度

func (*DurableChannel[T]) Send

func (dc *DurableChannel[T]) Send(ctx context.Context, data T) error

Send 发送消息(类似 channel <-)

func (*DurableChannel[T]) TryReceive

func (dc *DurableChannel[T]) TryReceive(ctx context.Context) (T, bool)

TryReceive 非阻塞接收(类似 select case)

type DurableChannelConfig

type DurableChannelConfig struct {
	Name            string      // Channel 名称(必填)
	Namespace       string      // Redis key 命名空间(默认 "dchan")
	WorkerID        int64       // 工作节点标识(默认 0,用于分布式场景节点隔离)
	BufferSize      int         // 内存缓冲区大小(默认 100)
	PersistenceMode PersistMode // 持久化模式(默认 PersistHybrid,决定是否启动消费者)
	WorkerCount     int         // 消费者 Worker 数量(PersistSync 下自动为 0,其他模式默认 1)
	// PollInterval 每次 BLPOP 的等待时长,也就是拉取的轮询粒度
	//
	// Redis 的 BLPOP 超时是**秒级**的,go-redis 对低于 1s 的值会上调到 1s 并打一行警告
	// 所以这里配 100ms 实际等 1s,比配置慢十倍,而且只有打开 redis 的日志才看得见
	// 默认值因此定为 1s —— 与实际行为一致,不再骗人
	//
	// [EN] How long each BLPOP waits, which is the polling granularity. Redis expresses that
	// timeout in whole seconds and go-redis raises anything below one second to one second
	// with a warning, so a configured 100ms actually waited a second, ten times longer than
	// asked, visible only with redis logging on. The default is therefore one second, which
	// is what actually happens
	PollInterval       time.Duration
	RecoveryOnStart    bool          // 启动时是否恢复未消费消息(默认 true)
	TTL                time.Duration // Redis 队列过期时间(默认 24h,0 表示永不过期)
	EnableCompression  bool          // 是否启用压缩(默认 false,大消息建议启用)
	CompressionMinSize int           // 压缩阈值(默认 1KB)
	QueryTimeout       time.Duration // 查询操作超时时间(Len/RedisLen,默认 3s)
}

DurableChannelConfig 持久化 Channel 配置

通用配置,适用于各种场景: - Name: 队列名称,建议使用有意义的命名(如 "user:123:messages", "tasks:worker-1") - Namespace: Redis key 前缀,用于隔离不同应用(默认 "dchan") - WorkerID: 工作节点标识,用于分布式场景下的节点隔离(默认 0)

  • 分布式场景:每个节点使用不同的 WorkerID(如 0, 1, 2...)
  • 单机场景:所有实例使用相同的 WorkerID(默认 0)
  • 推荐使用 osx.GetWorkerId() 自动获取(支持 K8s Pod 序号)

- PersistenceMode: 根据场景选择(决定是否启动消费者):

  • PersistSync: 只写 Redis,不启动消费者(生产者模式)
  • PersistAsync: 异步写入 + 启动消费者(快速响应)
  • PersistHybrid: 先写 Redis + 启动消费者(推荐,平衡可靠性和性能)

- WorkerCount: 消费者数量(PersistSync 模式下自动为 0,其他模式默认 1) - QueryTimeout: 查询操作超时时间(Len/RedisLen,默认 3s)

func DefaultDurableChannelConfig

func DefaultDurableChannelConfig(name string) DurableChannelConfig

DefaultDurableChannelConfig 默认配置

type ExpiringHandler

type ExpiringHandler struct {
	// contains filtered or unexported fields
}

ExpiringHandler 是一个简单的基于 map 的线程安全内存缓存,支持 TTL 和后台清理 它实现了 Handler 接口

func NewExpiringHandler

func NewExpiringHandler(cleanupInterval time.Duration) *ExpiringHandler

NewExpiringHandler 创建一个新的 ExpiringHandler,cleanupInterval 控制后台清理频率(为0则使用1s)

func (*ExpiringHandler) BatchGet

func (h *ExpiringHandler) BatchGet(keys [][]byte) ([][]byte, []error)

func (*ExpiringHandler) BatchGetWithCtx

func (h *ExpiringHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取多个键的值

func (*ExpiringHandler) Close

func (h *ExpiringHandler) Close() error

Close 停止后台清理并释放资源

func (*ExpiringHandler) Del

func (h *ExpiringHandler) Del(key []byte) error

func (*ExpiringHandler) DelWithCtx

func (h *ExpiringHandler) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 删除键

func (*ExpiringHandler) Get

func (h *ExpiringHandler) Get(key []byte) ([]byte, error)

func (*ExpiringHandler) GetOrCompute

func (h *ExpiringHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取缓存值,如果不存在则计算并设置

func (*ExpiringHandler) GetOrComputeWithCtx

func (h *ExpiringHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取缓存值,如果不存在则计算并设置

func (*ExpiringHandler) GetTTL

func (h *ExpiringHandler) GetTTL(key []byte) (time.Duration, error)

func (*ExpiringHandler) GetTTLWithCtx

func (h *ExpiringHandler) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 返回剩余TTL(0 表示无TTL),找不到返回ErrNotFound

func (*ExpiringHandler) GetWithCtx

func (h *ExpiringHandler) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 读取值,如果不存在或已过期返回ErrNotFound

func (*ExpiringHandler) Set

func (h *ExpiringHandler) Set(key, value []byte) error

func (*ExpiringHandler) SetWithCtx

func (h *ExpiringHandler) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 将值写入缓存(无TTL,支持context)

func (*ExpiringHandler) SetWithTTL

func (h *ExpiringHandler) SetWithTTL(key, value []byte, ttl time.Duration) error

func (*ExpiringHandler) SetWithTTLAndCtx

func (h *ExpiringHandler) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 写入值并设置TTL(ttl<=0 表示不过期,支持context)

func (*ExpiringHandler) Stats

func (h *ExpiringHandler) Stats() map[string]interface{}

Stats 返回缓存统计信息

type FieldCacheConfig

type FieldCacheConfig struct {
	CacheName string // KV cache 名称(自动派生为 {tableName}:{fieldName},无需手动指定)
	FieldName string // model Go 字段名(PascalCase,如 "Name"、"Code")
}

FieldCacheConfig 字段缓存配置:一个 model 字段对应一个独立的 KV cache

type GenericCacheOption

type GenericCacheOption[K comparable, V any] func(*GenericTTLCache[K, V])

GenericCacheOption 泛型缓存配置选项

func WithLogger

func WithLogger[K comparable, V any](log logger.ILogger) GenericCacheOption[K, V]

WithLogger 配置日志记录器(不设置则使用默认 logger)

func WithPubSub

func WithPubSub[K comparable, V any](pubsub *PubSub, channel string, codec KeyCodec[K]) GenericCacheOption[K, V]

WithPubSub 启用 PubSub 跨节点失效 同一逻辑缓存的所有节点必须使用相同 channel 和兼容的 codec 构造时自动订阅失效频道,Delete/Clear 会广播到其他节点

type GenericTTLCache

type GenericTTLCache[K comparable, V any] struct {
	// contains filtered or unexported fields
}

GenericTTLCache 基于 sync.Map + TTL 的泛型本地缓存 与 Handler([]byte 值)互补:Handler 适合缓存可序列化数据,GenericTTLCache 适合缓存内存对象

启用跨节点失效(可选):

pubsub := cachex.NewPubSub(redisClient)
cache := cachex.NewGenericTTLCache[string, *rsa.PublicKey](
    cachex.WithPubSub[string, *rsa.PublicKey](pubsub, "ac:jwks:invalidate", cachex.StringKeyCodec{}),
)
defer cache.Stop()

func NewGenericTTLCache

func NewGenericTTLCache[K comparable, V any](opts ...GenericCacheOption[K, V]) *GenericTTLCache[K, V]

NewGenericTTLCache 创建泛型本地 TTL 缓存 不传选项时为纯本地缓存;通过 WithPubSub 启用跨节点失效后,构造时自动订阅失效频道

func (*GenericTTLCache[K, V]) Clear

func (c *GenericTTLCache[K, V]) Clear()

Clear 清空本地缓存并广播 clear 事件(启用 PubSub 时其他节点同步清空)

func (*GenericTTLCache[K, V]) Delete

func (c *GenericTTLCache[K, V]) Delete(key K)

Delete 删除缓存项 启用 PubSub 时会广播失效事件到其他节点

func (*GenericTTLCache[K, V]) DeleteLocal

func (c *GenericTTLCache[K, V]) DeleteLocal(key K)

DeleteLocal 仅删除本地缓存项,不广播失效事件 用于本地缓存疑似脏数据的自愈场景,不影响其他节点

func (*GenericTTLCache[K, V]) Invalidate

func (c *GenericTTLCache[K, V]) Invalidate(key K)

Invalidate 广播失效事件到其他节点,不删除本地缓存 用于本节点写入新值后,让其他节点删除旧值,下次读取走回源拿最新值 典型场景:拉黑 jti 后本节点 Store(true),调用 Invalidate 让其他节点删除旧值后回源感知拉黑

func (*GenericTTLCache[K, V]) Load

func (c *GenericTTLCache[K, V]) Load(key K) (V, bool)

Load 加载缓存项,未命中或已过期返回零值与 false

func (*GenericTTLCache[K, V]) Stop

func (c *GenericTTLCache[K, V]) Stop()

Stop 停止 PubSub 订阅(如果已启用) 未启用 PubSub 的实例无需调用;调用后不再接收跨节点失效事件,本地读写不受影响

func (*GenericTTLCache[K, V]) Store

func (c *GenericTTLCache[K, V]) Store(key K, value V, ttl time.Duration)

Store 存储缓存项,ttl 为存活时长

type Handler

type Handler interface {

	// Set 设置缓存键值对
	Set(key, value []byte) error

	// SetWithTTL 设置带有过期时间的缓存键值对
	SetWithTTL(key, value []byte, ttl time.Duration) error

	// Get 根据键获取缓存值
	Get(key []byte) ([]byte, error)

	// GetTTL 获取指定键的剩余过期时间
	GetTTL(key []byte) (time.Duration, error)

	// Del 删除指定的缓存键
	Del(key []byte) error

	// BatchGet 批量获取多个键的值
	BatchGet(keys [][]byte) ([][]byte, []error)

	// GetOrCompute 获取缓存值,如果不存在则通过loader函数计算并存储
	GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

	// SetWithCtx 设置缓存键值对
	SetWithCtx(ctx context.Context, key, value []byte) error

	// SetWithTTLAndCtx 设置带有过期时间的缓存键值对
	SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

	// GetWithCtx 根据键获取缓存值
	GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

	// GetTTLWithCtx 获取指定键的剩余过期时间
	GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

	// DelWithCtx 删除指定的缓存键
	DelWithCtx(ctx context.Context, key []byte) error

	// BatchGetWithCtx 批量获取多个键的值
	BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

	// GetOrComputeWithCtx 获取缓存值,如果不存在则通过loader函数计算并存储
	GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

	// Stats 获取缓存统计信息
	Stats() map[string]interface{}

	// Close 关闭缓存实例并释放资源
	Close() error
}

Handler 是缓存操作的统一接口 同时提供简化版(不带context)和完整版(带context)两种调用方式 简化版方法:Set, Get, Del 等 - 适用于简单场景 完整版方法:SetWithCtx, GetWithCtx, DelWithCtx 等 - 支持超时控制和取消操作

func NewRedisHandler

func NewRedisHandler(cfg *redis.Options) (Handler, error)

NewRedisHandler 创建新的 RedisHandler

func NewRedisHandlerSimple

func NewRedisHandlerSimple(addr, password string, db int) (Handler, error)

NewRedisHandlerSimple 创建新的 RedisHandler,使用推荐的配置 这是一个便捷函数,使用了优化的默认配置以避免常见问题

type HotKeyCache

type HotKeyCache[K comparable, V any] struct {
	// contains filtered or unexported fields
}

HotKeyCache 热key缓存

func NewHotKeyCache

func NewHotKeyCache[K comparable, V any](
	client redis.UniversalClient,
	keyName string,
	loader DataLoader[K, V],
	config HotKeyConfig,
) *HotKeyCache[K, V]

NewHotKeyCache 创建热key缓存

func (*HotKeyCache[K, V]) Clear

func (h *HotKeyCache[K, V]) Clear(ctx context.Context) error

Clear 清空缓存

func (*HotKeyCache[K, V]) Delete

func (h *HotKeyCache[K, V]) Delete(ctx context.Context, key K) error

Delete 删除单个键

func (*HotKeyCache[K, V]) Exists

func (h *HotKeyCache[K, V]) Exists(ctx context.Context, key K) (bool, error)

Exists 检查键是否存在

func (*HotKeyCache[K, V]) Get

func (h *HotKeyCache[K, V]) Get(ctx context.Context, key K) (V, bool, error)

Get 获取单个值

func (*HotKeyCache[K, V]) GetAll

func (h *HotKeyCache[K, V]) GetAll(ctx context.Context) (map[K]V, error)

GetAll 获取所有值

func (*HotKeyCache[K, V]) GetStats

func (h *HotKeyCache[K, V]) GetStats(ctx context.Context) (*HotKeyStats, error)

func (*HotKeyCache[K, V]) Keys

func (h *HotKeyCache[K, V]) Keys(ctx context.Context) ([]K, error)

Keys 获取所有键

func (*HotKeyCache[K, V]) LoadAll

func (h *HotKeyCache[K, V]) LoadAll(ctx context.Context) (map[K]V, error)

LoadAll 从Redis或数据源加载所有数据

func (*HotKeyCache[K, V]) Refresh

func (h *HotKeyCache[K, V]) Refresh(ctx context.Context) error

Refresh 手动刷新缓存

func (*HotKeyCache[K, V]) SaveToRedis

func (h *HotKeyCache[K, V]) SaveToRedis(ctx context.Context) error

SaveToRedis 保存到Redis

func (*HotKeyCache[K, V]) Set

func (h *HotKeyCache[K, V]) Set(ctx context.Context, key K, value V) error

Set 设置单个值

func (*HotKeyCache[K, V]) SetAll

func (h *HotKeyCache[K, V]) SetAll(ctx context.Context, data map[K]V) error

SetAll 设置所有值

func (*HotKeyCache[K, V]) Size

func (h *HotKeyCache[K, V]) Size(ctx context.Context) (int, error)

Size 获取缓存大小(直接从本地缓存计算,避免触发加载)

func (*HotKeyCache[K, V]) Stop

func (h *HotKeyCache[K, V]) Stop()

Stop 停止自动刷新和清理

type HotKeyConfig

type HotKeyConfig struct {
	DefaultTTL        time.Duration  // 默认TTL
	RefreshInterval   time.Duration  // 刷新间隔
	EnableAutoRefresh bool           // 是否启用自动刷新
	Namespace         string         // 命名空间
	Logger            logger.ILogger // 日志记录器(可选,不设置则使用 NoOpLogger)
	MaxLocalCacheSize int            // 本地缓存最大条目数,防止无界增长,默认 10000
}

HotKeyConfig 热key配置

type HotKeyManager

type HotKeyManager struct {
	// contains filtered or unexported fields
}

HotKeyManager 热key管理器

func NewHotKeyManager

func NewHotKeyManager(client redis.UniversalClient, opts ...HotKeyOption) *HotKeyManager

NewHotKeyManager 创建热key管理器

func (*HotKeyManager) Get

func (m *HotKeyManager) Get(name string) (interface{}, bool)

Get 获取热key缓存

func (*HotKeyManager) GetAllStats

func (m *HotKeyManager) GetAllStats(ctx context.Context) (map[string]*HotKeyStats, error)

GetAllStats 获取所有缓存统计

func (*HotKeyManager) GetCache

func (m *HotKeyManager) GetCache(name string) (interface{}, bool)

GetCache 获取缓存

func (*HotKeyManager) RefreshAll

func (m *HotKeyManager) RefreshAll(ctx context.Context) error

RefreshAll 刷新所有缓存

func (*HotKeyManager) Register

func (m *HotKeyManager) Register(name string, cache interface{})

Register 注册热key缓存

func (*HotKeyManager) RegisterCache

func (m *HotKeyManager) RegisterCache(name string, cache interface{})

RegisterCache 注册缓存

func (*HotKeyManager) StopAll

func (m *HotKeyManager) StopAll()

StopAll 停止所有自动刷新

type HotKeyOption

type HotKeyOption func(*HotKeyConfig)

HotKeyOption 热key管理器配置项

func WithHotKeyAutoRefresh

func WithHotKeyAutoRefresh(enable bool) HotKeyOption

WithHotKeyAutoRefresh 是否启用自动刷新

func WithHotKeyLogger

func WithHotKeyLogger(l logger.ILogger) HotKeyOption

WithHotKeyLogger 设置日志记录器

func WithHotKeyMaxLocalCacheSize

func WithHotKeyMaxLocalCacheSize(n int) HotKeyOption

WithHotKeyMaxLocalCacheSize 设置本地缓存最大条目数

func WithHotKeyNamespace

func WithHotKeyNamespace(ns string) HotKeyOption

WithHotKeyNamespace 设置命名空间

func WithHotKeyRefreshInterval

func WithHotKeyRefreshInterval(d time.Duration) HotKeyOption

WithHotKeyRefreshInterval 设置自动刷新间隔

func WithHotKeyTTL

func WithHotKeyTTL(ttl time.Duration) HotKeyOption

WithHotKeyTTL 设置默认 TTL

type HotKeyStats

type HotKeyStats struct {
	KeyName         string    `json:"key_name"`
	LocalCacheSize  int       `json:"local_cache_size"`
	LastRefreshTime time.Time `json:"last_refresh_time"`
	TTL             int64     `json:"ttl_seconds"`
}

GetStats 获取统计信息

type IDGenerator

type IDGenerator struct {
	OnSequenceInit func() int64 // key不存在时动态获取起始值
	// contains filtered or unexported fields
}

IDGenerator 通用ID生成器

func NewIDGenerator

func NewIDGenerator(redisClient redis.UniversalClient) *IDGenerator

NewIDGenerator 创建ID生成器实例

func (*IDGenerator) ForceResetSequence

func (g *IDGenerator) ForceResetSequence(ctx context.Context, timePrefix string) error

ForceResetSequence 强制重置指定时间的序列号(仅用于测试或特殊场景) 警告:此方法会删除已有序列号,可能导致ID重复,生产环境慎用

func (*IDGenerator) GenerateID

func (g *IDGenerator) GenerateID(ctx context.Context) (string, error)

GenerateID 生成一个ID

func (*IDGenerator) GenerateIDs

func (g *IDGenerator) GenerateIDs(ctx context.Context, n int) ([]string, error)

GenerateIDs 批量生成ID(Lua脚本实现,原子高效)

func (*IDGenerator) GetCurrentSequence

func (g *IDGenerator) GetCurrentSequence(ctx context.Context) (int64, error)

GetCurrentSequence 获取当前时间的序列号(不增加)

func (*IDGenerator) GetIDPrefix

func (g *IDGenerator) GetIDPrefix() string

Getter方法,便于测试

func (*IDGenerator) GetIDSuffix

func (g *IDGenerator) GetIDSuffix() string

func (*IDGenerator) GetSeparator

func (g *IDGenerator) GetSeparator() string

func (*IDGenerator) GetSequenceByTime

func (g *IDGenerator) GetSequenceByTime(ctx context.Context, timePrefix string) (int64, error)

GetSequenceByTime 获取指定时间段的序列号(不增加)

func (*IDGenerator) ResetSequence

func (g *IDGenerator) ResetSequence(ctx context.Context, timePrefix string) error

ResetSequence 仅在 key 不存在时初始化序列号,已存在则不做任何操作 这样可以避免在分布式环境下误删已有序列号导致ID重复

func (*IDGenerator) WithExpire

func (g *IDGenerator) WithExpire(d time.Duration) *IDGenerator

WithExpire 设置序列号过期时间

func (*IDGenerator) WithIDPrefix

func (g *IDGenerator) WithIDPrefix(prefix string) *IDGenerator

WithIDPrefix 设置ID前缀

func (*IDGenerator) WithIDSuffix

func (g *IDGenerator) WithIDSuffix(suffix string) *IDGenerator

WithIDSuffix 设置ID后缀

func (*IDGenerator) WithKeyPrefix

func (g *IDGenerator) WithKeyPrefix(prefix string) *IDGenerator

WithKeyPrefix 设置Redis键前缀

func (*IDGenerator) WithSeparator

func (g *IDGenerator) WithSeparator(sep string) *IDGenerator

WithSeparator 设置分隔符

func (*IDGenerator) WithSequenceInitCallback

func (g *IDGenerator) WithSequenceInitCallback(cb func() int64) *IDGenerator

WithSequenceInitCallback 设置key不存在时的序列号初始化回调

func (*IDGenerator) WithSequenceLength

func (g *IDGenerator) WithSequenceLength(length int) *IDGenerator

WithSequenceLength 设置序列号长度

func (*IDGenerator) WithSequenceStart

func (g *IDGenerator) WithSequenceStart(start int64) *IDGenerator

WithSequenceStart 设置序列号起始值

func (*IDGenerator) WithTimeFormat

func (g *IDGenerator) WithTimeFormat(format string) *IDGenerator

WithTimeFormat 设置时间格式

type IndexGroup

type IndexGroup struct {
	// contains filtered or unexported fields
}

IndexGroup 索引分组,用于按业务维度批量管理多个索引集合 预定义分组后,一行调用即可删除该分组下所有缓存

使用方式:

tenantGroup := mgr.NewIndexGroup("idx:tenant_options", "idx:region_options", "idx:platform_options")
tenantGroup.Delete(ctx)  // 一行删除所有关联缓存

func (*IndexGroup) AddIndexKeys

func (g *IndexGroup) AddIndexKeys(keys ...string)

AddIndexKeys 向分组中追加索引键

func (*IndexGroup) Delete

func (g *IndexGroup) Delete(ctx context.Context) (int64, error)

Delete 删除分组内所有索引集合关联的缓存键

func (*IndexGroup) IndexKeys

func (g *IndexGroup) IndexKeys() []string

IndexKeys 返回分组内的索引键列表

type Int64KeyCodec

type Int64KeyCodec struct{}

Int64KeyCodec int64 键编解码器

func (Int64KeyCodec) Decode

func (Int64KeyCodec) Decode(data string) (int64, error)

func (Int64KeyCodec) Encode

func (Int64KeyCodec) Encode(key int64) string

type IntKeyCodec

type IntKeyCodec struct{}

IntKeyCodec int 键编解码器

func (IntKeyCodec) Decode

func (IntKeyCodec) Decode(data string) (int, error)

func (IntKeyCodec) Encode

func (IntKeyCodec) Encode(key int) string

type KVCache

type KVCache[K comparable, V any] struct {
	// contains filtered or unexported fields
}

KVCache 通用键值缓存

使用方式一(推荐,通过全局注册表):

cachex.RegisterKV[string, string]("game_library", loadFunc,
    cachex.WithKVNamespace("core:kv"), cachex.WithKVTTL(30*time.Minute))
cache, err := cachex.GetKV[string, string]("game_library")
cache.Set(ctx, "id1", "value1")

使用方式二(直接构造):

cache := cachex.NewKVCache[string, string](redisClient, "game_library",
    loadFunc, cachex.KVCacheConfig{...})

func GetKV

func GetKV[K comparable, V any](name string) (*KVCache[K, V], error)

GetKV 按名称获取已注册的 KV 缓存

cache, err := cachex.GetKV[string, string]("game_library")
cache.Set(ctx, "id1", "name1")

func MustGetKV

func MustGetKV[K comparable, V any](name string) *KVCache[K, V]

MustGetKV 按名称获取已注册的 KV 缓存,未注册时 panic(适合初始化阶段使用)

func NewKVCache

func NewKVCache[K comparable, V any](
	client redis.UniversalClient,
	name string,
	loader KVLoader[K, V],
	config KVCacheConfig,
) *KVCache[K, V]

NewKVCache 创建 KV 缓存实例

func (*KVCache[K, V]) Clear

func (c *KVCache[K, V]) Clear(ctx context.Context) error

Clear 清空本地与 Redis 缓存(并广播 clear 消息给其他节点) 使用 Pipeline 合并 DEL + PUBLISH,将 2 次 RTT 减少为 1 次

func (*KVCache[K, V]) Client

func (c *KVCache[K, V]) Client() redis.UniversalClient

Client 返回底层 Redis 客户端,供上层组件(如 ModelKVCache)构建 Pipeline 批量写入

func (*KVCache[K, V]) Delete

func (c *KVCache[K, V]) Delete(ctx context.Context, key K) error

Delete 删除单个 key(并广播失效消息) 使用 Pipeline 合并 HDEL + PUBLISH,将 2 次 RTT 减少为 1 次

func (*KVCache[K, V]) DeleteFromPipe

func (c *KVCache[K, V]) DeleteFromPipe(pipe redis.Pipeliner, key K)

DeleteFromPipe 将 HDel 命令追加到给定 pipeline(不立即执行),同时删本地缓存 调用方负责执行 pipeline(pipe.Exec)与广播失效

func (*KVCache[K, V]) DeleteMany

func (c *KVCache[K, V]) DeleteMany(ctx context.Context, keys []K) error

DeleteMany 批量删除多个 key(HDEL 单次 RTT,并广播失效消息) 使用 Pipeline 合并 HDEL + PUBLISH,将 2 次 RTT 减少为 1 次

func (*KVCache[K, V]) Get

func (c *KVCache[K, V]) Get(ctx context.Context, key K) (V, bool, error)

Get 获取单个值(本地 -> Redis -> BatchLoader 按需回源 / LoadAll 全量兜底)

func (*KVCache[K, V]) GetLastRefreshTime

func (c *KVCache[K, V]) GetLastRefreshTime() time.Time

GetLastRefreshTime 原子读取最后刷新时间

func (*KVCache[K, V]) GetMany

func (c *KVCache[K, V]) GetMany(ctx context.Context, keys []K) (map[K]V, error)

GetMany 批量获取多个 key 的值(缺失的 key 不出现在返回 map 中)

查询路径:本地缓存 -> Redis HMGET -> BatchLoader 按需回源(可选) 当配置了 BatchLoader 时,Redis 也 miss 的 key 会按需精准回源(而非全量 LoadAll)

func (*KVCache[K, V]) GetManyToPipe

func (c *KVCache[K, V]) GetManyToPipe(pipe redis.Pipeliner, keys []K) *redis.SliceCmd

GetManyToPipe 将 HMGet 命令追加到给定 pipeline(不立即执行),返回 *redis.SliceCmd 供 Exec 后读取 调用方负责执行 pipeline(pipe.Exec)与解析结果

与 GetMany 的差异:跳过本地缓存读和 BatchLoader 回源,仅从 Redis 读取 适用于多字段 Pipeline 聚合场景(ModelKVCache.GetFieldsMany),将 N 个字段的 HMGet 合并为 1 次 RTT 代价:不回填本地缓存、不支持 miss 回源;单字段场景应优先用 GetMany 保留三层兜底

func (*KVCache[K, V]) LoadAll

func (c *KVCache[K, V]) LoadAll(ctx context.Context) (map[K]V, error)

LoadAll 从 Redis 或数据源加载全量数据

说明:Redis Hash field 永远是 string,因此仅当 K 为 string 时支持从 Redis 全量恢复; 其他 K 类型(如 int64)请由调用方在 loader 中自行转换为 string 主键, 或直接由 loader 重建(推荐做法,与项目 Repository.LoadNameMap 模式一致)

func (*KVCache[K, V]) Name

func (c *KVCache[K, V]) Name() string

Name 返回 KV 缓存名称(用于批量操作的日志输出与实例标识)

func (*KVCache[K, V]) PublishInvalidation

func (c *KVCache[K, V]) PublishInvalidation(keys []string)

PublishInvalidation 广播失效消息(导出版本,供上层批量场景按需调用)

func (*KVCache[K, V]) Refresh

func (c *KVCache[K, V]) Refresh(ctx context.Context) error

Refresh 手动刷新缓存(从数据源重新加载,仅更新本节点 + Redis,不广播)

func (*KVCache[K, V]) RefreshAndSwap

func (c *KVCache[K, V]) RefreshAndSwap(ctx context.Context) error

RefreshAndSwap 原子刷新:先从数据源加载新数据,再用 Lua 脚本原子替换 Redis(DEL+HSET+EXPIRE), 最后替换本地缓存并广播 clear 通知其他节点从 Redis 重新加载

与 Clear+Refresh 的区别:

  • Clear+Refresh 有空窗期(Redis DEL 后、HSET 前),其他请求会 cache miss → lazy LoadAll → DB 雪崩
  • RefreshAndSwap 先加载数据再原子替换,Redis 从旧值→新值无空窗,其他节点收到 clear 后从 Redis 读到最新数据

适用于启动预热(WarmupAllKV)和高优先级缓存刷新场景

func (*KVCache[K, V]) Set

func (c *KVCache[K, V]) Set(ctx context.Context, key K, value V) error

Set 设置单个值(同步双写本地 + Redis,并广播失效消息给其他节点)

func (*KVCache[K, V]) SetMany

func (c *KVCache[K, V]) SetMany(ctx context.Context, items map[K]V) error

SetMany 批量设置多个值(Lua 脚本一次 RTT 完成 HSET + EXPIRE,并广播失效消息)

func (*KVCache[K, V]) SetToPipe

func (c *KVCache[K, V]) SetToPipe(pipe redis.Pipeliner, key K, value V) error

SetToPipe 将 HSET+TTL(Lua 原子脚本)命令追加到给定 pipeline(不立即执行),同时写本地缓存 调用方负责执行 pipeline(pipe.Exec)与广播失效,避免多字段场景下 N 次 RTT

func (*KVCache[K, V]) Size

func (c *KVCache[K, V]) Size() int

Size 返回本地缓存大小(原子读取,零锁开销)

func (*KVCache[K, V]) Stop

func (c *KVCache[K, V]) Stop()

Stop 停止自动刷新与 PubSub 订阅

type KVCacheConfig

type KVCacheConfig struct {
	DefaultTTL        time.Duration  // 默认TTL,默认 30 分钟
	RefreshInterval   time.Duration  // 自动刷新间隔,默认 5 分钟
	EnableAutoRefresh bool           // 是否启用自动刷新,默认 true
	Namespace         string         // Redis 命名空间,默认 "kv"
	Logger            logger.ILogger // 日志记录器(可选)
	MaxLocalCacheSize int            // 本地缓存最大条目数,默认 10000
	BatchLoader       any            // 按需批量回源加载器(可选,类型应为 BatchLoader[K,V])
}

KVCacheConfig KV 缓存配置

type KVLoader

type KVLoader[K comparable, V any] func(ctx context.Context) (map[K]V, error)

KVLoader KV 数据加载器:从数据源加载全量 K->V 映射

type KVOption

type KVOption func(*KVCacheConfig)

KVOption KV 缓存配置项

func WithKVAutoRefresh

func WithKVAutoRefresh(enable bool) KVOption

WithKVAutoRefresh 是否启用自动刷新

func WithKVBatchLoader

func WithKVBatchLoader[K comparable, V any](loader BatchLoader[K, V]) KVOption

WithKVBatchLoader 设置按需批量回源加载器 配置后,GetMany 在本地+Redis 都 miss 时按缺失 keys 精准回源(而非全量 LoadAll) 适用于"全量加载不可行"的场景(如跨服务 RPC 按需查询、大数据量表按主键查)

cachex.RegisterKV[string, string]("user_nickname", nil,
    cachex.WithKVBatchLoader[string, string](func(ctx, keys) (map[string]string, error) {
        // 调用 RPC 批量查询,返回 user_id -> nickname 映射
    }),
    cachex.WithKVAutoRefresh(false),  // 仅有 BatchLoader 时关闭自动刷新
)

func WithKVLogger

func WithKVLogger(l logger.ILogger) KVOption

WithKVLogger 设置日志记录器

func WithKVMaxLocalCacheSize

func WithKVMaxLocalCacheSize(n int) KVOption

WithKVMaxLocalCacheSize 设置本地缓存最大条目数

func WithKVNamespace

func WithKVNamespace(ns string) KVOption

WithKVNamespace 设置 Redis 命名空间

func WithKVRefreshInterval

func WithKVRefreshInterval(d time.Duration) KVOption

WithKVRefreshInterval 设置自动刷新间隔

func WithKVTTL

func WithKVTTL(ttl time.Duration) KVOption

WithKVTTL 设置默认 TTL

type KeyCodec

type KeyCodec[K comparable] interface {
	// Encode 将键序列化为字符串(用于 PubSub 传输)
	Encode(key K) string
	// Decode 将字符串反序列化为键
	Decode(data string) (K, error)
}

KeyCodec 键编解码器 用于 PubSub 跨节点传输时将泛型键 K 序列化为字符串,以及将字符串反序列化回 K 解决 Go 泛型无法在运行时从 string 还原为 K 的限制(comparable 约束不足以支撑反序列化)

type LRUHandler

type LRUHandler struct {
	// contains filtered or unexported fields
}

LRUHandler 是一个简单的线程安全 LRU 缓存实现,满足 Handler 接口 - keys/values 使用 []byte 表示,key 在内部以 string 存储 - 当超过容量时,按最近最少使用 (LRU) 驱逐 - 支持可选的 TTL(通过 SetWithTTL)

func NewLRUHandler

func NewLRUHandler(maxEntries int) *LRUHandler

NewLRUHandler 创建一个新的 LRUHandler,maxEntries<=0 时使用默认容量

func (*LRUHandler) BatchGet

func (h *LRUHandler) BatchGet(keys [][]byte) ([][]byte, []error)

BatchGet 批量获取

func (*LRUHandler) BatchGetWithCtx

func (h *LRUHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取

func (*LRUHandler) Close

func (h *LRUHandler) Close() error

Close 实现 Handler.Close

func (*LRUHandler) Del

func (h *LRUHandler) Del(key []byte) error

Del 删除缓存键

func (*LRUHandler) DelWithCtx

func (h *LRUHandler) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 删除缓存键(支持context)

func (*LRUHandler) Get

func (h *LRUHandler) Get(key []byte) ([]byte, error)

Get 获取缓存值

func (*LRUHandler) GetOrCompute

func (h *LRUHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取或计算(简化版)

func (*LRUHandler) GetOrComputeWithCtx

func (h *LRUHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取或计算缓存值

func (*LRUHandler) GetTTL

func (h *LRUHandler) GetTTL(key []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*LRUHandler) GetTTLWithCtx

func (h *LRUHandler) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 获取键的剩余TTL(支持context)

func (*LRUHandler) GetWithCtx

func (h *LRUHandler) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 获取缓存值(支持context)

func (*LRUHandler) Set

func (h *LRUHandler) Set(key, value []byte) error

Set 设置缓存键值对(不带TTL)

func (*LRUHandler) SetWithCtx

func (h *LRUHandler) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 设置缓存键值对(支持context)

func (*LRUHandler) SetWithTTL

func (h *LRUHandler) SetWithTTL(key, value []byte, ttl time.Duration) error

SetWithTTL 设置带TTL的缓存键值对

func (*LRUHandler) SetWithTTLAndCtx

func (h *LRUHandler) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存键值对(支持context)

func (*LRUHandler) Stats

func (h *LRUHandler) Stats() map[string]interface{}

Stats 返回缓存统计信息

type LRUOptimizedHandler

type LRUOptimizedHandler struct {
	// contains filtered or unexported fields
}

LRUOptimizedHandler 高性能分片LRU缓存处理器

func NewLRUOptimizedHandler

func NewLRUOptimizedHandler(maxEntries int) *LRUOptimizedHandler

NewLRUOptimizedHandler 创建分片式高性能LRU缓存

func (*LRUOptimizedHandler) BatchGet

func (h *LRUOptimizedHandler) BatchGet(keys [][]byte) ([][]byte, []error)

func (*LRUOptimizedHandler) BatchGetWithCtx

func (h *LRUOptimizedHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取,减少锁开销

func (*LRUOptimizedHandler) Clear

func (h *LRUOptimizedHandler) Clear()

Clear 清空所有缓存条目但不关闭 handler,使其可以继续使用 线程安全,可在并发访问时调用

func (*LRUOptimizedHandler) Close

func (h *LRUOptimizedHandler) Close() error

Close 实现 Handler.Close

func (*LRUOptimizedHandler) Del

func (h *LRUOptimizedHandler) Del(key []byte) error

func (*LRUOptimizedHandler) DelWithCtx

func (h *LRUOptimizedHandler) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 实现Handler.Del

func (*LRUOptimizedHandler) Get

func (h *LRUOptimizedHandler) Get(key []byte) ([]byte, error)

Get 获取缓存值

func (*LRUOptimizedHandler) GetOrCompute

func (h *LRUOptimizedHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取缓存值,如果不存在则计算并设置

func (*LRUOptimizedHandler) GetOrComputeWithCtx

func (h *LRUOptimizedHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取或计算值(使用singleflight防止并发重复计算,支持context)

func (*LRUOptimizedHandler) GetTTL

func (h *LRUOptimizedHandler) GetTTL(key []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*LRUOptimizedHandler) GetTTLWithCtx

func (h *LRUOptimizedHandler) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 获取键的剩余TTL(支持context)

func (*LRUOptimizedHandler) GetWithCtx

func (h *LRUOptimizedHandler) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 获取缓存值(支持context)

func (*LRUOptimizedHandler) Set

func (h *LRUOptimizedHandler) Set(key, value []byte) error

Set 设置缓存值

func (*LRUOptimizedHandler) SetWithCtx

func (h *LRUOptimizedHandler) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 设置缓存(支持context)

func (*LRUOptimizedHandler) SetWithTTL

func (h *LRUOptimizedHandler) SetWithTTL(key, value []byte, ttl time.Duration) error

func (*LRUOptimizedHandler) SetWithTTLAndCtx

func (h *LRUOptimizedHandler) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存(支持context)

func (*LRUOptimizedHandler) Stats

func (h *LRUOptimizedHandler) Stats() map[string]interface{}

Stats 返回缓存统计信息

type LockConfig

type LockConfig struct {
	TTL              time.Duration  // 锁的TTL
	RetryInterval    time.Duration  // 重试间隔
	MaxRetries       int            // 最大重试次数
	Namespace        string         // 命名空间
	EnableWatchdog   bool           // 是否启用看门狗自动续期
	WatchdogInterval time.Duration  // 看门狗检查间隔
	Logger           logger.ILogger // 日志记录器
}

LockConfig 锁配置

type LockManager

type LockManager struct {
	// contains filtered or unexported fields
}

LockManager 锁管理器

func NewLockManager

func NewLockManager(client redis.UniversalClient, opts ...LockOption) *LockManager

NewLockManager 创建锁管理器

func (*LockManager) CleanupExpiredLocks

func (m *LockManager) CleanupExpiredLocks(ctx context.Context) error

CleanupExpiredLocks 清理过期的锁

func (*LockManager) GetAllLockStats

func (m *LockManager) GetAllLockStats(ctx context.Context) (map[string]*LockStats, error)

GetAllLockStats 获取管理器中所有锁的统计信息

func (*LockManager) GetLock

func (m *LockManager) GetLock(key string) *DistributedLock

GetLock 获取或创建锁

func (*LockManager) ReleaseAllLocks

func (m *LockManager) ReleaseAllLocks(ctx context.Context) error

ReleaseAllLocks 释放所有锁

func (*LockManager) ReleaseLock

func (m *LockManager) ReleaseLock(ctx context.Context, key string) error

ReleaseLock 释放锁并从管理器中移除

type LockOption

type LockOption func(*LockConfig)

LockOption 锁管理器配置项

func WithLockLogger

func WithLockLogger(l logger.ILogger) LockOption

WithLockLogger 设置日志记录器

func WithLockMaxRetries

func WithLockMaxRetries(n int) LockOption

WithLockMaxRetries 设置最大重试次数

func WithLockNamespace

func WithLockNamespace(ns string) LockOption

WithLockNamespace 设置命名空间

func WithLockRetryInterval

func WithLockRetryInterval(d time.Duration) LockOption

WithLockRetryInterval 设置重试间隔

func WithLockTTL

func WithLockTTL(ttl time.Duration) LockOption

WithLockTTL 设置锁的 TTL

func WithLockWatchdog

func WithLockWatchdog(enable bool) LockOption

WithLockWatchdog 是否启用看门狗自动续期

func WithLockWatchdogInterval

func WithLockWatchdogInterval(d time.Duration) LockOption

WithLockWatchdogInterval 设置看门狗检查间隔

type LockStats

type LockStats struct {
	Key            string        `json:"key"`
	Token          string        `json:"token"`
	Acquired       bool          `json:"acquired"`
	ExpireTime     time.Time     `json:"expire_time"`
	TTL            time.Duration `json:"ttl"`
	WatchdogActive bool          `json:"watchdog_active"`
}

GetLockStats 获取锁统计信息

type MessageHandler

type MessageHandler func(ctx context.Context, channel string, message string) error

MessageHandler 消息处理器接口

type ModelCache

type ModelCache[M any] struct {
	// contains filtered or unexported fields
}

ModelCache 泛型 model 整实例缓存

底层持有一个 KVCache[string, M],复用其本地分片缓存、Redis Hash、 PubSub 失效广播与 BatchLoader 按需回源能力

func GetModelCache

func GetModelCache[M any]() (*ModelCache[M], error)

GetModelCache 按 model 类型获取已注册的 ModelCache

func MustGetModelCache

func MustGetModelCache[M any]() *ModelCache[M]

MustGetModelCache 按 model 类型获取已注册的 ModelCache,未注册时 panic

cachex.MustGetModelCache[models.PaymentReceiveConfigModel]().Get(ctx, tenantID, platformID)

func (*ModelCache[M]) Delete

func (c *ModelCache[M]) Delete(ctx context.Context, m *M) error

Delete 删除整实例缓存(从 model 实例提取复合 key,直接操作底层 KV)

func (*ModelCache[M]) DeleteByKey

func (c *ModelCache[M]) DeleteByKey(ctx context.Context, keyValues ...string) error

DeleteByKey 按键字段值删除整实例缓存(无需 model 实例)

func (*ModelCache[M]) Get

func (c *ModelCache[M]) Get(ctx context.Context, keyValues ...string) (M, bool, error)

Get 按键字段值读取整实例(本地 → Redis → DB 按需回源) keyValues 顺序必须与注册的 KeyFields 一致

func (*ModelCache[M]) InvalidateAll

func (c *ModelCache[M]) InvalidateAll(ctx context.Context) error

InvalidateAll 清空该 model 的全部缓存条目(本地 + Redis + 广播 clear) 适用于按 filters 批量更新/删除后无法定位受影响 key 的兜底失效

func (*ModelCache[M]) Set

func (c *ModelCache[M]) Set(ctx context.Context, m *M) error

Set 写穿整实例缓存(本地 + Redis + 失效广播)

func (*ModelCache[M]) TableName

func (c *ModelCache[M]) TableName() string

TableName 返回 gorm 解析的表名(供上层 Repository 构建原生 SQL 复用)

type ModelCacheBuilder

type ModelCacheBuilder[M any] struct {
	// contains filtered or unexported fields
}

ModelCacheBuilder 泛型 model 整实例缓存 builder(链式配置后 Register)

func NewModelCache

func NewModelCache[M any](base *ModelKVBase, db *gorm.DB) *ModelCacheBuilder[M]

NewModelCache 创建指定 model 类型的 builder,继承 base 的 opts

cachex.NewModelCache[models.PaymentReceiveConfigModel](channelBase, gwglobal.DB)

func (*ModelCacheBuilder[M]) ExtraOptions

func (b *ModelCacheBuilder[M]) ExtraOptions(opts ...KVOption) *ModelCacheBuilder[M]

ExtraOptions 追加 base 之外的额外 KVOption(覆盖或补充)

func (*ModelCacheBuilder[M]) KeyFields

func (b *ModelCacheBuilder[M]) KeyFields(names ...string) *ModelCacheBuilder[M]

KeyFields 设置缓存键字段(model Go 字段名,顺序即复合 key 的拼接顺序) 可选:未设置时自动取 gorm schema 的 PrioritizedPrimaryField(仅单主键可用,复合主键必须显式指定)

func (*ModelCacheBuilder[M]) Register

func (b *ModelCacheBuilder[M]) Register() *ModelCache[M]

Register 注册到全局表,返回 ModelCache 实例

func (*ModelCacheBuilder[M]) Separator

func (b *ModelCacheBuilder[M]) Separator(sep string) *ModelCacheBuilder[M]

Separator 设置复合 key 拼接分隔符(默认 ":",要求键字段值中不含该分隔符,如 uuid/数字)

type ModelKVBase

type ModelKVBase struct {
	// contains filtered or unexported fields
}

ModelKVBase 共享 KV 选项的 base(preset),用于多个 model 复用 namespace/ttl/refreshInterval

gameBase := cachex.NewModelKVBase().
    Namespace(constants.KVNamespaceGame).
    TTL(constants.TTLKVCacheGame).
    RefreshInterval(constants.KVCacheRefreshInterval)

func NewModelKVBase

func NewModelKVBase() *ModelKVBase

NewModelKVBase 创建 base preset

func (*ModelKVBase) Namespace

func (b *ModelKVBase) Namespace(ns string) *ModelKVBase

Namespace 设置命名空间(透传到底层 KVCache)

func (*ModelKVBase) Options

func (b *ModelKVBase) Options(opts ...KVOption) *ModelKVBase

Options 追加任意底层 KVOption

func (*ModelKVBase) RefreshInterval

func (b *ModelKVBase) RefreshInterval(d time.Duration) *ModelKVBase

RefreshInterval 设置自动刷新间隔

func (*ModelKVBase) TTL

func (b *ModelKVBase) TTL(ttl time.Duration) *ModelKVBase

TTL 设置缓存过期时间

type ModelKVBuilder

type ModelKVBuilder[M any] struct {
	// contains filtered or unexported fields
}

ModelKVBuilder 泛型 model KV 缓存 builder(链式配置后 Register)

func NewModelKV

func NewModelKV[M any](base *ModelKVBase, db *gorm.DB) *ModelKVBuilder[M]

NewModelKV 创建指定 model 类型的 builder,继承 base 的 opts

cachex.NewModelKV[models.GameBrandModel](gameBase, gwglobal.DB)

func (*ModelKVBuilder[M]) ExtraOptions

func (b *ModelKVBuilder[M]) ExtraOptions(opts ...KVOption) *ModelKVBuilder[M]

ExtraOptions 追加 base 之外的额外 KVOption(覆盖或补充)

func (*ModelKVBuilder[M]) Field

func (b *ModelKVBuilder[M]) Field(fieldName string) *ModelKVBuilder[M]

Field 添加字段缓存(cacheName 自动派生为 {tableName}:{fieldName},无需手动指定)

func (*ModelKVBuilder[M]) Fields

func (b *ModelKVBuilder[M]) Fields(fieldNames ...string) *ModelKVBuilder[M]

Fields 批量添加字段缓存(等价于多次调用 Field,更简洁)

cachex.NewModelKV[models.GameLibraryModel](gameBase, gwglobal.DB).
    Fields("Name", "GameCode", "BrandId", "GameType").
    Register()

func (*ModelKVBuilder[M]) KeyField

func (b *ModelKVBuilder[M]) KeyField(name string) *ModelKVBuilder[M]

KeyField 设置主键字段名(model Go 字段名,如 "Id"、"TenantId") 可选:未设置时自动从 gorm schema 的 PrioritizedPrimaryField 检测

func (*ModelKVBuilder[M]) LoadTTL

func (b *ModelKVBuilder[M]) LoadTTL(ttl time.Duration) *ModelKVBuilder[M]

LoadTTL 设置共享 loadAll 的复用窗口(默认 1s,N 个字段缓存只查 1 次 DB)

func (*ModelKVBuilder[M]) Register

func (b *ModelKVBuilder[M]) Register() *ModelKVCache[M]

Register 注册到全局表,返回 ModelKVCache 实例

type ModelKVCache

type ModelKVCache[M any] struct {
	// contains filtered or unexported fields
}

ModelKVCache 泛型 model KV 缓存

一个 model 可对应多个字段缓存,通过 gorm 自动查询 + unsafe 反射提取

func GetModelKV

func GetModelKV[M any]() (*ModelKVCache[M], error)

GetModelKV 按 model 类型获取已注册的 ModelKVCache

func MustGetModelKV

func MustGetModelKV[M any]() *ModelKVCache[M]

MustGetModelKV 按 model 类型获取已注册的 ModelKVCache,未注册时 panic

cachex.MustGetModelKV[models.GameBrandModel]().Set(ctx, m)

func (*ModelKVCache[M]) Delete

func (c *ModelKVCache[M]) Delete(ctx context.Context, m *M) error

Delete 删除 model 的所有字段缓存(unsafe 提取 key)

func (*ModelKVCache[M]) DeleteByKey

func (c *ModelKVCache[M]) DeleteByKey(ctx context.Context, key string) error

DeleteByKey 按 key 删除所有字段缓存(无需 model 实例)

多字段时使用 Redis Pipeline 批量 HDel,N 次网络往返合并为 1 次

func (*ModelKVCache[M]) GetFieldMany

func (c *ModelKVCache[M]) GetFieldMany(ctx context.Context, fieldName string, keys []string) map[string]string

GetFieldMany 批量读取 model 某字段的 KV 缓存(空 keys 或未注册字段返回 nil)

cachex.MustGetModelKV[models.GameLibraryModel]().GetFieldMany(ctx, "Name", gameIDs)

func (*ModelKVCache[M]) GetFieldsMany

func (c *ModelKVCache[M]) GetFieldsMany(ctx context.Context, fieldNames, keys []string) map[string]map[string]string

GetFieldsMany 批量读取 model 多个字段的 KV 缓存,用 Redis Pipeline 合并 N 个字段的 HMGet 为 1 次网络往返 返回 map[key]map[fieldName]string 嵌套结构(未命中字段不出现在内层 map 中)

性能:N 个字段 × M 个 key → 1 次 Pipeline(N 个 HMGet 命令),而非 N 次 HMGet 网络往返 适用场景:列表查询需同时回显多个字段(如 Name + Code + GameType + IconUrl)

注意:此方法跳过单字段的 localCache 读和 BatchLoader 回源,仅从 Redis 读取

  • 单字段场景自动降级为 GetFieldMany,保留三层兜底
  • 多字段场景 miss 的 key 不回源,需调用方自行处理空值

func (*ModelKVCache[M]) ResetLoadCache

func (c *ModelKVCache[M]) ResetLoadCache()

ResetLoadCache 重置共享 loadAll 缓存,下次 loadAll 强制从 DB 查询 适用于启动预热场景:Clear 后需要强制刷新 loadAll 缓存,避免读到清理前的旧数据

func (*ModelKVCache[M]) Set

func (c *ModelKVCache[M]) Set(ctx context.Context, m *M) error

Set 写入 model 的所有字段缓存(unsafe 提取 key 和各字段 value,零反射)

多字段时使用 Redis Pipeline 批量 HSET,N 次网络往返合并为 1 次; 单字段直接走原路径,避免 pipeline 开销

type MultiLevelCache

type MultiLevelCache[T any] struct {
	// contains filtered or unexported fields
}

MultiLevelCache 多级缓存(生产级别)

func NewMultiLevelCache

func NewMultiLevelCache[T any](redisClient redis.UniversalClient, config MultiLevelConfig) *MultiLevelCache[T]

NewMultiLevelCache 创建多级缓存

func (*MultiLevelCache[T]) Clear

func (m *MultiLevelCache[T]) Clear(ctx context.Context) error

Clear 清空所有缓存

func (*MultiLevelCache[T]) Delete

func (m *MultiLevelCache[T]) Delete(ctx context.Context, key string) error

Delete 删除缓存

func (*MultiLevelCache[T]) Get

func (m *MultiLevelCache[T]) Get(ctx context.Context, key string, loader func() (T, error)) (T, error)

Get 获取缓存(L1 → L2 → 加载器)

func (*MultiLevelCache[T]) GetStats

func (m *MultiLevelCache[T]) GetStats() map[string]int64

GetStats 获取统计信息

各计数独立原子读,不再持锁快照:返回值是各项的近似同期视图而非严格一致快照 (并发写入下 l1_hits 与 misses 可能相差一次计数)。统计用途不需要线性一致性, 而旧实现为此在每次 Get/Set 上加了一把全局锁,代价远超收益。

func (*MultiLevelCache[T]) InvalidateL1

func (m *MultiLevelCache[T]) InvalidateL1(key string)

InvalidateL1 使L1缓存失效

func (*MultiLevelCache[T]) Set

func (m *MultiLevelCache[T]) Set(ctx context.Context, key string, value T) error

Set 设置缓存到L1和L2

type MultiLevelConfig

type MultiLevelConfig struct {
	Namespace         string
	L1Size            int           // L1本地缓存大小
	L1TTL             time.Duration // L1缓存过期时间
	L2TTL             time.Duration // L2 Redis缓存过期时间
	EnableCompression bool          // 是否启用压缩
	SyncInterval      time.Duration // 同步间隔
}

MultiLevelConfig 多级缓存配置

type ObjectPool

type ObjectPool interface {
	// Start 启动池(冷启动预填充 + 周期补充任务),重复调用幂等
	Start(ctx context.Context) error
	// Stop 停止周期补充任务,正在进行的预填充尽快退出
	Stop() error
	// Name 返回池名称(全局唯一)
	Name() string
}

ObjectPool 对象池接口(非泛型,用于全局注册表存储)

业务侧的 *ObjectPoolManager[T] 实现此接口, StartAllObjectPools / StopAllObjectPools 通过此接口统一管理

type ObjectPoolConfig

type ObjectPoolConfig struct {
	Capacity        int            // 池容量(缓冲区大小),必填
	MinThreshold    int            // 低水位阈值,低于此值触发补充,默认 Capacity/3
	BatchSize       int            // 每次周期补充的批量上限,默认 Capacity/2
	ColdStartCount  int            // 冷启动同步预生成数量(保证启动即可用),默认 Capacity/8
	RefreshInterval time.Duration  // 补充检查间隔,默认 5s
	Logger          logger.ILogger // 日志器,未设置时回退到 globalLogger
}

ObjectPoolConfig 对象池配置

type ObjectPoolManager

type ObjectPoolManager[T any] struct {
	// contains filtered or unexported fields
}

ObjectPoolManager 泛型对象池管理器

包装一个 buffered channel 作为对象缓冲区,通过 factory 预生成对象 注册到全局表后由宿主统一启停;注册即启动,业务侧通常无需手动调 Start

func GetObjectPool

func GetObjectPool[T any](name string) (*ObjectPoolManager[T], error)

GetObjectPool 按名称获取已注册的对象池

func MustGetObjectPool

func MustGetObjectPool[T any](name string) *ObjectPoolManager[T]

MustGetObjectPool 按名称获取已注册的对象池,未注册时 panic(适合初始化阶段使用)

func RegisterObjectPool

func RegisterObjectPool[T any](name string, factory PoolFactory[T], opts ...ObjectPoolOption) *ObjectPoolManager[T]

RegisterObjectPool 注册对象池并立即启动(pbmo 风格)

使用者只需在初始化阶段调用一次,后续可通过 GetObjectPool[T](name) 获取实例 建议直接保存返回的 *ObjectPoolManager[T] 引用,避免每次查注册表 name 必须全局唯一,重复注册将 panic

pool := cachex.RegisterObjectPool[TempKeyPem]("temp_key_pool", factory,
    cachex.WithObjectPoolCapacity(64))

func (*ObjectPoolManager[T]) Len

func (m *ObjectPoolManager[T]) Len() int

Len 当前池中可用对象数量(观测用,可能随后变化)

func (*ObjectPoolManager[T]) Name

func (m *ObjectPoolManager[T]) Name() string

Name 返回池名称(实现 ObjectPool 接口)

func (*ObjectPoolManager[T]) Start

func (m *ObjectPoolManager[T]) Start(ctx context.Context) error

Start 启动池:同步预生成冷启动批量,再异步补齐并启动周期补充任务 重复调用幂等(已启动则直接返回 nil)

func (*ObjectPoolManager[T]) Stats

func (m *ObjectPoolManager[T]) Stats() PoolStats

Stats 返回池运行统计(观测用)

func (*ObjectPoolManager[T]) Stop

func (m *ObjectPoolManager[T]) Stop() error

Stop 停止周期补充任务(实现 ObjectPool 接口) 正在进行的预填充会在下一个生成循环检测到停止标记后退出

func (*ObjectPoolManager[T]) TryGet

func (m *ObjectPoolManager[T]) TryGet() (T, bool)

TryGet 非阻塞地从池中取一个对象 池空时返回 (零值, false),由调用方回退实时构造

type ObjectPoolOption

type ObjectPoolOption func(*ObjectPoolConfig)

ObjectPoolOption 对象池配置选项

func WithObjectPoolBatchSize

func WithObjectPoolBatchSize(n int) ObjectPoolOption

WithObjectPoolBatchSize 设置每次补充批量上限

func WithObjectPoolCapacity

func WithObjectPoolCapacity(n int) ObjectPoolOption

WithObjectPoolCapacity 设置池容量

func WithObjectPoolColdStartCount

func WithObjectPoolColdStartCount(n int) ObjectPoolOption

WithObjectPoolColdStartCount 设置冷启动同步预生成数量(0 表示纯异步)

func WithObjectPoolLogger

func WithObjectPoolLogger(l logger.ILogger) ObjectPoolOption

WithObjectPoolLogger 设置日志器(未设置时回退到 globalLogger)

func WithObjectPoolMinThreshold

func WithObjectPoolMinThreshold(n int) ObjectPoolOption

WithObjectPoolMinThreshold 设置低水位阈值

func WithObjectPoolRefreshInterval

func WithObjectPoolRefreshInterval(d time.Duration) ObjectPoolOption

WithObjectPoolRefreshInterval 设置补充检查间隔

type PersistMode

type PersistMode int

PersistMode 持久化模式

const (
	// PersistSync 同步持久化 - 只写 Redis,不启动消费者(生产者模式)
	// 适用场景:只负责发送消息的服务
	PersistSync PersistMode = iota

	// PersistAsync 异步持久化 - 先写内存,异步写 Redis,启动消费者(消费者模式)
	// 适用场景:快速响应,可容忍少量丢失
	PersistAsync

	// PersistHybrid 混合模式 - 先写 Redis,再刷内存,启动消费者(完整模式,推荐)
	// 适用场景:大多数需要可靠性和性能平衡的场景
	PersistHybrid
)

func (PersistMode) String

func (pm PersistMode) String() string

String 返回持久化模式的字符串表示

type PoolFactory

type PoolFactory[T any] func() (T, error)

PoolFactory 对象工厂函数:生成一个对象放入池 返回 error 时跳过该对象并记录日志,继续生成下一个

type PoolStats

type PoolStats struct {
	Name      string // 池名称
	Available int    // 当前可用数量
	Capacity  int    // 池容量
	Generated int64  // 累计生成数量
	Served    int64  // 累计命中数量
}

PoolStats 池运行统计

type PubSub

type PubSub struct {
	// contains filtered or unexported fields
}

PubSub Redis发布订阅封装

func NewPubSub

func NewPubSub(client redis.UniversalClient, opts ...PubSubOption) *PubSub

NewPubSub 创建发布订阅实例

func (*PubSub) BroadcastMessage

func (p *PubSub) BroadcastMessage(ctx context.Context, channels []string, message any) error

BroadcastMessage 广播消息到多个频道

func (*PubSub) Close

func (p *PubSub) Close() error

Close 关闭发布订阅

func (*PubSub) GetChannels

func (p *PubSub) GetChannels() []string

GetChannels 获取已订阅的频道列表

func (*PubSub) GetClient

func (p *PubSub) GetClient() redis.UniversalClient

GetClient 获取底层 Redis 客户端(用于高级操作)

func (*PubSub) GetStats

func (p *PubSub) GetStats() *PubSubStats

GetStats 获取统计信息

func (*PubSub) GetSubscribers

func (p *PubSub) GetSubscribers() int

GetSubscribers 获取活跃的订阅者数量

func (*PubSub) Publish

func (p *PubSub) Publish(ctx context.Context, channel string, message any) error

Publish 发布消息

func (*PubSub) RequestResponse

func (p *PubSub) RequestResponse(ctx context.Context, requestChannel, responseChannel string, request any, timeout time.Duration) (string, error)

RequestResponse 请求-响应模式(基于发布订阅)

func (*PubSub) ResolveChannel

func (p *PubSub) ResolveChannel(channel string) string

ResolveChannel 解析逻辑频道对应的物理频道名(含命名空间前缀) 供绕过 Publish/Subscribe 直接使用底层 Client 的场景(如 Pipeline 批量发布)调用, 确保发布与订阅命中同一个物理频道,消除"订阅带前缀、发布不带前缀"的频道错配

func (*PubSub) Subscribe

func (p *PubSub) Subscribe(channels []string, handler MessageHandler) (*Subscriber, error)

Subscribe 订阅频道

func (*PubSub) SubscribePattern

func (p *PubSub) SubscribePattern(patterns []string, handler MessageHandler) (*Subscriber, error)

SubscribePattern 订阅模式匹配的频道

func (*PubSub) Unsubscribe

func (p *PubSub) Unsubscribe(channels ...string) error

Unsubscribe 取消订阅

type PubSubConfig

type PubSubConfig struct {
	Namespace          string         // 命名空间
	MaxRetries         int            // 最大重试次数
	RetryDelay         time.Duration  // 重试延迟
	BufferSize         int            // 消息缓冲区大小
	Logger             logger.ILogger // 日志记录器(可选,不设置则使用 NoOpLogger)
	PingInterval       time.Duration  // 心跳间隔
	EnableCompression  bool           // 是否启用消息压缩(使用 gzip)
	CompressionMinSize int            // 压缩阈值(字节),小于此值不压缩,默认 1KB
	MaxWorkers         int            // 消息处理 worker 数量,防止 goroutine 泄漏,默认 20
	WorkerQueueSize    int            // worker 队列大小,默认 100
	StartRetryWindow   time.Duration  // 启动握手失败重试窗口:窗口内指数退避重试,耗尽返回最后错误;0 表示无限重试(仅 PubSub 关闭可打断),默认 30s
}

PubSubConfig 发布订阅配置

func DefaultPubSubConfig

func DefaultPubSubConfig() PubSubConfig

DefaultPubSubConfig 默认配置 Namespace 默认为空,即频道名不加前缀;需要隔离的模块通过 WithPubSubNamespace 显式设置

type PubSubOption

type PubSubOption func(*PubSubConfig)

PubSubOption 发布订阅配置项

func WithPubSubBufferSize

func WithPubSubBufferSize(n int) PubSubOption

WithPubSubBufferSize 设置消息缓冲区大小

func WithPubSubCompression

func WithPubSubCompression(enable bool) PubSubOption

WithPubSubCompression 是否启用消息压缩

func WithPubSubCompressionMinSize

func WithPubSubCompressionMinSize(n int) PubSubOption

WithPubSubCompressionMinSize 设置压缩阈值

func WithPubSubLogger

func WithPubSubLogger(l logger.ILogger) PubSubOption

WithPubSubLogger 设置日志记录器

func WithPubSubMaxRetries

func WithPubSubMaxRetries(n int) PubSubOption

WithPubSubMaxRetries 设置最大重试次数

func WithPubSubMaxWorkers

func WithPubSubMaxWorkers(n int) PubSubOption

WithPubSubMaxWorkers 设置消息处理 worker 数量

func WithPubSubNamespace

func WithPubSubNamespace(ns string) PubSubOption

WithPubSubNamespace 设置命名空间

func WithPubSubPingInterval

func WithPubSubPingInterval(d time.Duration) PubSubOption

WithPubSubPingInterval 设置心跳间隔

func WithPubSubRetryDelay

func WithPubSubRetryDelay(d time.Duration) PubSubOption

WithPubSubRetryDelay 设置重试延迟

func WithPubSubStartRetryWindow

func WithPubSubStartRetryWindow(d time.Duration) PubSubOption

WithPubSubStartRetryWindow 设置启动握手失败重试窗口 窗口内指数退避重试,耗尽后 Subscribe/Resubscribe 返回最后错误; 默认 30s,设为 0 表示无限重试,仅 PubSub 关闭可打断——适合长生命周期服务的订阅自愈

func WithPubSubWorkerQueueSize

func WithPubSubWorkerQueueSize(n int) PubSubOption

WithPubSubWorkerQueueSize 设置 worker 队列大小

type PubSubStats

type PubSubStats struct {
	ActiveSubscribers int      `json:"active_subscribers"`
	Channels          []string `json:"channels"`
	Patterns          []string `json:"patterns"`
}

PubSubStats 发布订阅统计

type QueueConfig

type QueueConfig struct {
	MaxRetries            int           // 最大重试次数
	RetryDelay            time.Duration // 重试延迟
	BatchSize             int           // 批处理大小
	LockTimeout           time.Duration // 分布式锁超时时间
	CleanupInterval       time.Duration // 清理间隔
	EnableDistributedLock bool          // 是否启用分布式锁
}

QueueConfig 队列配置

type QueueHandler

type QueueHandler struct {
	// contains filtered or unexported fields
}

QueueHandler Redis队列处理器

func NewQueueHandler

func NewQueueHandler(client redis.UniversalClient, namespace string, config QueueConfig) *QueueHandler

NewQueueHandler 创建队列处理器

func (*QueueHandler) AcquireLock

func (q *QueueHandler) AcquireLock(ctx context.Context, queueName string, workerID string) (bool, error)

AcquireLock 获取分布式锁

func (*QueueHandler) BatchDequeue

func (q *QueueHandler) BatchDequeue(ctx context.Context, queueName string, queueType QueueType, count int) ([]*QueueItem, error)

BatchDequeue 批量出队

func (*QueueHandler) Clear

func (q *QueueHandler) Clear(ctx context.Context, queueName string, queueType QueueType) error

Clear 清空队列

func (*QueueHandler) Contains

func (q *QueueHandler) Contains(ctx context.Context, queueName string, queueType QueueType, itemID string) (bool, error)

Contains 检查队列是否包含特定元素

func (*QueueHandler) Dequeue

func (q *QueueHandler) Dequeue(ctx context.Context, queueName string, queueType QueueType) (*QueueItem, error)

Dequeue 出队操作

func (*QueueHandler) DequeueNonBlocking

func (q *QueueHandler) DequeueNonBlocking(ctx context.Context, queueName string, queueType QueueType) (*QueueItem, error)

DequeueNonBlocking 非阻塞出队操作

func (*QueueHandler) Enqueue

func (q *QueueHandler) Enqueue(ctx context.Context, queueName string, queueType QueueType, item *QueueItem) error

Enqueue 入队操作

func (*QueueHandler) GetFailedItems

func (q *QueueHandler) GetFailedItems(ctx context.Context, queueName string, offset, limit int64) ([]*QueueItem, error)

GetFailedItems 获取失败的任务

func (*QueueHandler) GetStats

func (q *QueueHandler) GetStats(ctx context.Context, queueName string, queueType QueueType) (*QueueStats, error)

GetStats 获取队列统计信息

func (*QueueHandler) Length

func (q *QueueHandler) Length(ctx context.Context, queueName string, queueType QueueType) (int64, error)

Length 获取队列长度

func (*QueueHandler) Peek

func (q *QueueHandler) Peek(ctx context.Context, queueName string, queueType QueueType, count int) ([]*QueueItem, error)

Peek 查看队列头部元素(不移除)

func (*QueueHandler) ReleaseLock

func (q *QueueHandler) ReleaseLock(ctx context.Context, queueName string, workerID string) error

ReleaseLock 释放分布式锁

func (*QueueHandler) RetryFailed

func (q *QueueHandler) RetryFailed(ctx context.Context, queueName string, queueType QueueType, item *QueueItem) error

RetryFailed 重试失败的任务

type QueueItem

type QueueItem struct {
	ID         string      `json:"id"`          // 唯一标识
	Data       interface{} `json:"data"`        // 数据内容
	Priority   float64     `json:"priority"`    // 优先级(用于优先级队列)
	DelayTime  int64       `json:"delay_time"`  // 延时时间戳(用于延时队列)
	CreatedAt  int64       `json:"created_at"`  // 创建时间
	RetryCount int         `json:"retry_count"` // 重试次数
}

QueueItem 队列项

type QueueStats

type QueueStats struct {
	QueueName    string `json:"queue_name"`
	QueueType    string `json:"queue_type"`
	Length       int64  `json:"length"`
	DelayedCount int64  `json:"delayed_count,omitempty"`
	FailedCount  int64  `json:"failed_count"`
}

Statistics 获取队列统计信息

type QueueType

type QueueType string

QueueType 队列类型

const (
	QueueTypeFIFO     QueueType = "fifo"     // 先进先出队列
	QueueTypeLIFO     QueueType = "lifo"     // 后进先出队列(栈)
	QueueTypePriority QueueType = "priority" // 优先级队列
	QueueTypeDelayed  QueueType = "delayed"  // 延时队列
)

type RedisHandler

type RedisHandler struct {
	// contains filtered or unexported fields
}

RedisHandler 是 Redis 缓存的实现

func (*RedisHandler) BatchGet

func (h *RedisHandler) BatchGet(keys [][]byte) ([][]byte, []error)

BatchGet 批量获取

func (*RedisHandler) BatchGetWithCtx

func (h *RedisHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取多个键的值

func (*RedisHandler) Close

func (h *RedisHandler) Close() error

Close 实现 Handler 接口的 Close 方法

func (*RedisHandler) Del

func (h *RedisHandler) Del(k []byte) error

Del 删除缓存键

func (*RedisHandler) DelWithCtx

func (h *RedisHandler) DelWithCtx(ctx context.Context, k []byte) error

DelWithCtx 删除缓存键

func (*RedisHandler) Get

func (h *RedisHandler) Get(k []byte) ([]byte, error)

Get 获取缓存值

func (*RedisHandler) GetOrCompute

func (h *RedisHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取缓存值,如果不存在则计算并设置(简化版,不带context)

func (*RedisHandler) GetOrComputeWithCtx

func (h *RedisHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取缓存值,如果不存在则计算并设置

func (*RedisHandler) GetTTL

func (h *RedisHandler) GetTTL(k []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*RedisHandler) GetTTLWithCtx

func (h *RedisHandler) GetTTLWithCtx(ctx context.Context, k []byte) (time.Duration, error)

GetTTLWithCtx 获取键的剩余TTL

func (*RedisHandler) GetWithCtx

func (h *RedisHandler) GetWithCtx(ctx context.Context, k []byte) ([]byte, error)

GetWithCtx 获取缓存值

func (*RedisHandler) Set

func (h *RedisHandler) Set(k, v []byte) error

Set 设置缓存值

func (*RedisHandler) SetWithCtx

func (h *RedisHandler) SetWithCtx(ctx context.Context, k, v []byte) error

SetWithCtx 设置缓存值

func (*RedisHandler) SetWithTTL

func (h *RedisHandler) SetWithTTL(k, v []byte, ttl time.Duration) error

SetWithTTL 设置带TTL的缓存值

func (*RedisHandler) SetWithTTLAndCtx

func (h *RedisHandler) SetWithTTLAndCtx(ctx context.Context, k, v []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存值

func (*RedisHandler) Stats

func (h *RedisHandler) Stats() map[string]interface{}

Stats 返回Redis缓存统计信息

func (*RedisHandler) WithCtx

func (h *RedisHandler) WithCtx(ctx context.Context) *RedisHandler

type RistrettoConfig

type RistrettoConfig struct {
	NumCounters            int64                              // 计数器数量,用于跟踪访问频率
	MaxCost                int64                              // 最大缓存成本
	BufferItems            int64                              // Get 缓存的大小
	Metrics                bool                               // 是否启用缓存统计
	OnEvict                func(item *ristretto.Item[[]byte]) // 每次驱逐时调用
	OnReject               func(item *ristretto.Item[[]byte]) // 每次拒绝时调用
	OnExit                 func(val []byte)                   // 从缓存中移除值时调用
	ShouldUpdate           func(cur, prev []byte) bool        // 更新时的检查函数
	KeyToHash              func(key []byte) (uint64, uint64)  // 自定义键哈希算法
	Cost                   func(value []byte) int64           // 计算值的成本
	IgnoreInternalCost     bool                               // 是否忽略内部存储的成本
	TtlTickerDurationInSec int64                              // TTL 过期时清理键的时间间隔 (为0时=bucketDurationSecs)

	// AsyncWrites 写入后不等待 ristretto 写缓冲落地(放弃写后立即可读的确定性,换取吞吐)
	//
	// ristretto 的设计是写入经通道异步批量落地;默认实现在每次写后调用 cache.Wait(),
	// 把异步写退化为「同步等待内部协程排空」的往返。实测代价:
	//   串行 717.8ns → 269.7ns(2.66×)、并行 1099ns → 507.6ns(2.17×)、分配 3 → 1
	// 且这是 Ristretto 混合负载扩展性为负(0.87×)的根因,尽管它的读扩展性最好。
	//
	// 语义取舍:置 true 后 Set 返回不保证随后的 Get 立即可见(ristretto 本身的契约即如此)。
	// 默认 false,即保持既有「写后同步等待」行为——零值配置与历史调用方行为完全不变。
	AsyncWrites bool
}

Config 用于定制 Ristretto 缓存的配置

func NewDefaultRistrettoConfig

func NewDefaultRistrettoConfig() *RistrettoConfig

NewDefaultRistrettoConfig 创建一个新的ristretto配置实例

func (*RistrettoConfig) EnableMetrics

func (c *RistrettoConfig) EnableMetrics() *RistrettoConfig

EnableMetrics 启用缓存统计

func (*RistrettoConfig) SetBufferItems

func (c *RistrettoConfig) SetBufferItems(bufferItems int64) *RistrettoConfig

SetBufferItems 设置 Get 缓存的大小

func (*RistrettoConfig) SetCost

func (c *RistrettoConfig) SetCost(fn func(value []byte) int64) *RistrettoConfig

SetCost 设置计算值成本的函数

func (*RistrettoConfig) SetIgnoreInternalCost

func (c *RistrettoConfig) SetIgnoreInternalCost(ignore bool) *RistrettoConfig

SetIgnoreInternalCost 设置是否忽略内部存储的成本

func (*RistrettoConfig) SetKeyToHash

func (c *RistrettoConfig) SetKeyToHash(fn func(key []byte) (uint64, uint64)) *RistrettoConfig

SetKeyToHash 设置自定义键哈希算法

func (*RistrettoConfig) SetMaxCost

func (c *RistrettoConfig) SetMaxCost(maxCost int64) *RistrettoConfig

SetMaxCost 设置最大缓存成本

func (*RistrettoConfig) SetNumCounters

func (c *RistrettoConfig) SetNumCounters(numCounters int64) *RistrettoConfig

SetNumCounters 设置计数器数量

func (*RistrettoConfig) SetOnEvict

func (c *RistrettoConfig) SetOnEvict(fn func(item *ristretto.Item[[]byte])) *RistrettoConfig

SetOnEvict 设置驱逐时的回调函数

func (*RistrettoConfig) SetOnExit

func (c *RistrettoConfig) SetOnExit(fn func(val []byte)) *RistrettoConfig

SetOnExit 设置从缓存中移除值时的回调函数

func (*RistrettoConfig) SetOnReject

func (c *RistrettoConfig) SetOnReject(fn func(item *ristretto.Item[[]byte])) *RistrettoConfig

SetOnReject 设置拒绝时的回调函数

func (*RistrettoConfig) SetShouldUpdate

func (c *RistrettoConfig) SetShouldUpdate(fn func(cur, prev []byte) bool) *RistrettoConfig

SetShouldUpdate 设置更新时的检查函数

func (*RistrettoConfig) SetTtlTickerDurationInSec

func (c *RistrettoConfig) SetTtlTickerDurationInSec(duration int64) *RistrettoConfig

SetTtlTickerDurationInSec 设置 TTL 过期时间间隔

type RistrettoHandler

type RistrettoHandler struct {
	// contains filtered or unexported fields
}

RistrettoHandler 是 Ristretto 缓存的实现

func NewDefaultRistrettoHandler

func NewDefaultRistrettoHandler() (*RistrettoHandler, error)

NewDefaultRistrettoHandler 创建默认的 RistrettoHandler

func NewRistrettoHandler

func NewRistrettoHandler(config *RistrettoConfig) (*RistrettoHandler, error)

NewRistrettoHandler 创建新的 RistrettoHandler,支持自定义配置

func (*RistrettoHandler) BatchGet

func (h *RistrettoHandler) BatchGet(keys [][]byte) ([][]byte, []error)

func (*RistrettoHandler) BatchGetWithCtx

func (h *RistrettoHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取

func (*RistrettoHandler) Close

func (h *RistrettoHandler) Close() error

Close 实现 Handler 接口的 Close 方法

func (*RistrettoHandler) Del

func (h *RistrettoHandler) Del(k []byte) error

func (*RistrettoHandler) DelWithCtx

func (h *RistrettoHandler) DelWithCtx(ctx context.Context, k []byte) error

DelWithCtx 删除缓存

func (*RistrettoHandler) Get

func (h *RistrettoHandler) Get(k []byte) ([]byte, error)

Get 获取缓存值

func (*RistrettoHandler) GetOrCompute

func (h *RistrettoHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

func (*RistrettoHandler) GetOrComputeWithCtx

func (h *RistrettoHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取缓存值,如果不存在则计算并设置

func (*RistrettoHandler) GetTTL

func (h *RistrettoHandler) GetTTL(k []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*RistrettoHandler) GetTTLWithCtx

func (h *RistrettoHandler) GetTTLWithCtx(ctx context.Context, k []byte) (time.Duration, error)

GetTTLWithCtx 获取TTL

func (*RistrettoHandler) GetWithCtx

func (h *RistrettoHandler) GetWithCtx(ctx context.Context, k []byte) ([]byte, error)

GetWithCtx 获取缓存值

func (*RistrettoHandler) Set

func (h *RistrettoHandler) Set(k, v []byte) error

Set 设置缓存值

func (*RistrettoHandler) SetWithCtx

func (h *RistrettoHandler) SetWithCtx(ctx context.Context, k, v []byte) error

SetWithCtx 设置缓存

func (*RistrettoHandler) SetWithTTL

func (h *RistrettoHandler) SetWithTTL(k, v []byte, ttl time.Duration) error

func (*RistrettoHandler) SetWithTTLAndCtx

func (h *RistrettoHandler) SetWithTTLAndCtx(ctx context.Context, k, v []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存

func (*RistrettoHandler) Stats

func (h *RistrettoHandler) Stats() map[string]interface{}

Stats 返回缓存统计信息

type SQLDataLoader

type SQLDataLoader[K comparable, V any] struct {
	QueryFunc func(ctx context.Context) (map[K]V, error)
}

SQLDataLoader SQL数据加载器

func (*SQLDataLoader[K, V]) Load

func (s *SQLDataLoader[K, V]) Load(ctx context.Context) (map[K]V, error)

type Scheduler

type Scheduler interface {
	// Start 启动消费者(同一调度器重复调用返回 ErrDelayQueueRunning)
	Start(ctx context.Context) error
	// Stop 停止消费者并等待在途任务处理完成
	Stop() error
	// Name 返回调度器名称(全局唯一)
	Name() string
}

Scheduler 调度器接口(非泛型,用于全局注册表存储)

业务侧的 *SchedulerManager[T] 实现此接口, StartAllSchedulers / StopAllSchedulers 通过此接口统一管理

type SchedulerConfig

type SchedulerConfig struct {
	QueueName         string        // 队列名(必填,不同调度器用不同队列名隔离)
	Namespace         string        // Redis 键命名空间前缀,默认 "delayq"
	PollInterval      time.Duration // 消费者轮询间隔,默认 1s
	BatchSize         int64         // 每次轮询最多拉取的到期任务数,默认 10
	Concurrency       int           // 单实例内并发处理任务数,默认 5(Ordered=true 时忽略)
	MaxRetries        int           // 最大重试次数(不含首次执行),默认 3
	RetryDelay        time.Duration // 失败重试基础延迟,默认 5s(实际按指数退避)
	VisibilityTimeout time.Duration // 可见性超时:任务出队后多久未 ACK 视为失败回归队列,默认 5m
	Ordered           bool          // 顺序模式:同一 queue 内任务按到期时间串行处理
	MaxReadySize      int64         // ready 堆积告警阈值,超过时记录 Warn 日志,默认 10000(0 表示不检查)
}

SchedulerConfig 调度器配置

type SchedulerHandler

type SchedulerHandler[T any] func(ctx context.Context, task *DelayTask[T]) error

SchedulerHandler 任务处理函数类型 handler 返回 error 时任务会按指数退避重试,超过最大重试次数进入死信队列

type SchedulerManager

type SchedulerManager[T any] struct {
	// contains filtered or unexported fields
}

SchedulerManager 调度器管理器(泛型)

包装 DelayQueue[T],固定一个 queueName,提供简化的入队/取消/启停 API 通过 RegisterScheduler 注册到全局表,宿主服务统一启停

func GetScheduler

func GetScheduler[T any](name string) (*SchedulerManager[T], error)

GetScheduler 按名称获取已注册的调度器

func MustGetScheduler

func MustGetScheduler[T any](name string) *SchedulerManager[T]

MustGetScheduler 按名称获取已注册的调度器,未注册时 panic(适合初始化阶段使用)

func RegisterScheduler

func RegisterScheduler[T any](name string, handler SchedulerHandler[T], opts ...SchedulerOption) *SchedulerManager[T]

RegisterScheduler 注册调度器(pbmo 风格)

使用者只需在初始化阶段调用一次,后续可通过 GetScheduler[T](name) 获取实例 必须先调用 SetGlobalRedisClient 注入 Redis 客户端 name 必须全局唯一,重复注册将 panic

cachex.RegisterScheduler[MyData]("my_scheduler", handleFunc,
    cachex.WithSchedulerQueueName("core:my_queue"))

func (*SchedulerManager[T]) Cancel

func (m *SchedulerManager[T]) Cancel(ctx context.Context, key string) (bool, error)

Cancel 取消任务(按 Key),返回是否成功取消

func (*SchedulerManager[T]) DeadLength

func (m *SchedulerManager[T]) DeadLength(ctx context.Context) (int64, error)

DeadLength 死信队列长度

func (*SchedulerManager[T]) EnqueueAt

func (m *SchedulerManager[T]) EnqueueAt(ctx context.Context, task *DelayTask[T]) error

EnqueueAt 入队任务(到指定时间执行) 同一 Key 重复入队会覆盖 ExecuteAt,实现"重新调度"语义

func (*SchedulerManager[T]) EnqueueWithDelay

func (m *SchedulerManager[T]) EnqueueWithDelay(ctx context.Context, task *DelayTask[T], delay time.Duration) error

EnqueueWithDelay 入队任务(延迟指定时间后执行)

func (*SchedulerManager[T]) GetDeadTasks

func (m *SchedulerManager[T]) GetDeadTasks(ctx context.Context, offset, limit int64) ([]*DelayTask[T], error)

GetDeadTasks 查询死信队列任务

func (*SchedulerManager[T]) GetTask

func (m *SchedulerManager[T]) GetTask(ctx context.Context, key string) (*DelayTask[T], error)

GetTask 查询任务(按 Key)

func (*SchedulerManager[T]) Length

func (m *SchedulerManager[T]) Length(ctx context.Context) (int64, error)

Length 队列中待执行的任务数

func (*SchedulerManager[T]) Name

func (m *SchedulerManager[T]) Name() string

Name 返回调度器名称

func (*SchedulerManager[T]) Start

func (m *SchedulerManager[T]) Start(ctx context.Context) error

Start 启动消费者(实现 Scheduler 接口) 同一调度器重复调用返回 ErrDelayQueueRunning

func (*SchedulerManager[T]) Stop

func (m *SchedulerManager[T]) Stop() error

Stop 停止消费者并等待在途任务处理完成(实现 Scheduler 接口)

type SchedulerOption

type SchedulerOption func(*SchedulerConfig)

SchedulerOption 调度器配置选项

func WithSchedulerBatchSize

func WithSchedulerBatchSize(n int64) SchedulerOption

WithSchedulerBatchSize 设置批量拉取大小

func WithSchedulerConcurrency

func WithSchedulerConcurrency(n int) SchedulerOption

WithSchedulerConcurrency 设置并发数

func WithSchedulerMaxReadySize

func WithSchedulerMaxReadySize(n int64) SchedulerOption

WithSchedulerMaxReadySize 设置 ready 堆积告警阈值(0 表示不检查)

func WithSchedulerMaxRetries

func WithSchedulerMaxRetries(n int) SchedulerOption

WithSchedulerMaxRetries 设置最大重试次数

func WithSchedulerNamespace

func WithSchedulerNamespace(ns string) SchedulerOption

WithSchedulerNamespace 设置命名空间

func WithSchedulerOrdered

func WithSchedulerOrdered() SchedulerOption

WithSchedulerOrdered 启用顺序模式(同一 queue 内任务按到期时间串行处理)

func WithSchedulerPollInterval

func WithSchedulerPollInterval(d time.Duration) SchedulerOption

WithSchedulerPollInterval 设置轮询间隔

func WithSchedulerQueueName

func WithSchedulerQueueName(name string) SchedulerOption

WithSchedulerQueueName 设置队列名(必填)

func WithSchedulerRetryDelay

func WithSchedulerRetryDelay(d time.Duration) SchedulerOption

WithSchedulerRetryDelay 设置重试延迟

func WithSchedulerVisibilityTimeout

func WithSchedulerVisibilityTimeout(d time.Duration) SchedulerOption

WithSchedulerVisibilityTimeout 设置可见性超时(任务出队后多久未 ACK 回归队列)

type ShardedHandler

type ShardedHandler struct {
	// contains filtered or unexported fields
}

ShardedHandler 将缓存分成多个 shard,每个 shard 使用独立的 Handler 实例 适用于降低单锁争用或使用多实例后端的场景

func NewShardedHandler

func NewShardedHandler(factory func() Handler, shards int) *ShardedHandler

NewShardedHandler 使用 factory 创建 shards 个 Handler

func (*ShardedHandler) BatchGet

func (h *ShardedHandler) BatchGet(keys [][]byte) ([][]byte, []error)

BatchGet 批量获取

func (*ShardedHandler) BatchGetWithCtx

func (h *ShardedHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取多个键的值

func (*ShardedHandler) Close

func (h *ShardedHandler) Close() error

Close 关闭所有 shard

func (*ShardedHandler) Del

func (h *ShardedHandler) Del(key []byte) error

Del 删除键

func (*ShardedHandler) DelWithCtx

func (h *ShardedHandler) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 转发

func (*ShardedHandler) Get

func (h *ShardedHandler) Get(key []byte) ([]byte, error)

Get 获取缓存值

func (*ShardedHandler) GetOrCompute

func (h *ShardedHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取缓存值,如果不存在则计算并设置

func (*ShardedHandler) GetOrComputeWithCtx

func (h *ShardedHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取或计算值

func (*ShardedHandler) GetTTL

func (h *ShardedHandler) GetTTL(key []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*ShardedHandler) GetTTLWithCtx

func (h *ShardedHandler) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 转发

func (*ShardedHandler) GetWithCtx

func (h *ShardedHandler) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 转发

func (*ShardedHandler) Set

func (h *ShardedHandler) Set(key, value []byte) error

Set 设置缓存

func (*ShardedHandler) SetWithCtx

func (h *ShardedHandler) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 将请求转发到对应的shard

func (*ShardedHandler) SetWithTTL

func (h *ShardedHandler) SetWithTTL(key, value []byte, ttl time.Duration) error

SetWithTTL 设置带TTL的缓存

func (*ShardedHandler) SetWithTTLAndCtx

func (h *ShardedHandler) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 转发

func (*ShardedHandler) Stats

func (h *ShardedHandler) Stats() map[string]interface{}

Stats 返回所有分片的统计信息

type SmartCache

type SmartCache struct {
	// contains filtered or unexported fields
}

SmartCache 智能缓存 - 集成多种高级功能

func (*SmartCache) Close

func (c *SmartCache) Close() error

Close 关闭缓存

func (*SmartCache) Delete

func (c *SmartCache) Delete(ctx context.Context, key string) error

Delete 删除缓存

func (*SmartCache) Get

func (c *SmartCache) Get(ctx context.Context, key string) (interface{}, error)

Get 获取缓存(支持自动加载和刷新)

func (*SmartCache) GetOrSet

func (c *SmartCache) GetOrSet(ctx context.Context, key string, loader func() (interface{}, error)) (interface{}, error)

GetOrSet 获取或设置缓存(简化版) - 使用singleflight优化

func (*SmartCache) Set

func (c *SmartCache) Set(ctx context.Context, key string, value interface{}, ttl ...time.Duration) error

Set 设置缓存

func (*SmartCache) Subscribe

func (c *SmartCache) Subscribe(ctx context.Context, event string, handler func(data interface{})) (*Subscriber, error)

Subscribe 订阅缓存事件

type StringKeyCodec

type StringKeyCodec struct{}

StringKeyCodec string 键编解码器(恒等变换,零开销)

func (StringKeyCodec) Decode

func (StringKeyCodec) Decode(data string) (string, error)

func (StringKeyCodec) Encode

func (StringKeyCodec) Encode(key string) string

type Subscriber

type Subscriber struct {
	// contains filtered or unexported fields
}

Subscriber 订阅者

func SubscribeJSON

func SubscribeJSON[T any](p *PubSub, channels []string, handler TypedMessageHandler[T]) (*Subscriber, error)

SubscribeJSON 订阅JSON消息(泛型版本)

func (*Subscriber) GetChannels

func (s *Subscriber) GetChannels() []string

GetChannels 获取订阅的频道

func (*Subscriber) GetSubscriptionInfo

func (s *Subscriber) GetSubscriptionInfo() *SubscriptionInfo

GetSubscriptionInfo 获取订阅信息

func (*Subscriber) IsActive

func (s *Subscriber) IsActive() bool

IsActive 检查订阅是否活跃

func (*Subscriber) Resubscribe

func (s *Subscriber) Resubscribe() error

Resubscribe 重新订阅(如果已停止) 必须在 Stop() 之后调用。使用 stopMu 与 Stop 互斥,确保旧 goroutine 完全退出后才重置字段并启动新 goroutine,防止竞态和泄漏。

func (*Subscriber) Stop

func (s *Subscriber) Stop()

Stop 停止订阅(不从注册表中移除) 该方法会阻塞直到 messageLoop goroutine 完全退出,防止 goroutine 泄漏。 使用 stopMu 序列化 Stop/Resubscribe,避免竞态。

func (*Subscriber) Unsubscribe

func (s *Subscriber) Unsubscribe() error

Unsubscribe 取消订阅并从注册表中移除

type SubscriptionInfo

type SubscriptionInfo struct {
	IsPattern    bool         `json:"is_pattern"`
	IsActive     bool         `json:"is_active"`
	Channels     []string     `json:"channels"`
	ChannelCount int          `json:"channel_count"`
	Config       PubSubConfig `json:"config"`
}

SubscriptionInfo 订阅信息

type TwoLevelHandler

type TwoLevelHandler struct {
	L1           Handler
	L2           Handler
	WriteThrough bool // 如果 true,Set 同步写入 L1 和 L2;否则异步写入 L2
}

TwoLevelHandler 提供 L1/L2 两级缓存封装,兼容 Handler 接口 L1 通常是快速但容量有限的本地缓存(例如 LRU),L2 是容量更大或远程的缓存(例如 Ristretto/Redis)

func NewTwoLevelHandler

func NewTwoLevelHandler(l1, l2 Handler, writeThrough bool) *TwoLevelHandler

func (*TwoLevelHandler) BatchGet

func (h *TwoLevelHandler) BatchGet(keys [][]byte) ([][]byte, []error)

BatchGet 批量获取

func (*TwoLevelHandler) BatchGetWithCtx

func (h *TwoLevelHandler) BatchGetWithCtx(ctx context.Context, keys [][]byte) ([][]byte, []error)

BatchGetWithCtx 批量获取多个键的值

func (*TwoLevelHandler) Close

func (h *TwoLevelHandler) Close() error

func (*TwoLevelHandler) Del

func (h *TwoLevelHandler) Del(key []byte) error

Del 删除键

func (*TwoLevelHandler) DelWithCtx

func (h *TwoLevelHandler) DelWithCtx(ctx context.Context, key []byte) error

DelWithCtx 删除缓存

func (*TwoLevelHandler) Get

func (h *TwoLevelHandler) Get(key []byte) ([]byte, error)

Get 获取缓存值

func (*TwoLevelHandler) GetOrCompute

func (h *TwoLevelHandler) GetOrCompute(key []byte, ttl time.Duration, loader func() ([]byte, error)) ([]byte, error)

GetOrCompute 获取缓存值,如果不存在则计算并设置

func (*TwoLevelHandler) GetOrComputeWithCtx

func (h *TwoLevelHandler) GetOrComputeWithCtx(ctx context.Context, key []byte, ttl time.Duration, loader func(context.Context) ([]byte, error)) ([]byte, error)

GetOrComputeWithCtx 获取缓存值,如果不存在则计算并设置(带Context)

func (*TwoLevelHandler) GetTTL

func (h *TwoLevelHandler) GetTTL(key []byte) (time.Duration, error)

GetTTL 获取键的剩余TTL

func (*TwoLevelHandler) GetTTLWithCtx

func (h *TwoLevelHandler) GetTTLWithCtx(ctx context.Context, key []byte) (time.Duration, error)

GetTTLWithCtx 获取TTL

func (*TwoLevelHandler) GetWithCtx

func (h *TwoLevelHandler) GetWithCtx(ctx context.Context, key []byte) ([]byte, error)

GetWithCtx 获取缓存

func (*TwoLevelHandler) Set

func (h *TwoLevelHandler) Set(key, value []byte) error

Set 设置缓存

func (*TwoLevelHandler) SetWithCtx

func (h *TwoLevelHandler) SetWithCtx(ctx context.Context, key, value []byte) error

SetWithCtx 设置缓存

func (*TwoLevelHandler) SetWithTTL

func (h *TwoLevelHandler) SetWithTTL(key, value []byte, ttl time.Duration) error

SetWithTTL 设置带TTL的缓存

func (*TwoLevelHandler) SetWithTTLAndCtx

func (h *TwoLevelHandler) SetWithTTLAndCtx(ctx context.Context, key, value []byte, ttl time.Duration) error

SetWithTTLAndCtx 设置带TTL的缓存

func (*TwoLevelHandler) Stats

func (h *TwoLevelHandler) Stats() map[string]interface{}

Stats 返回两级缓存的统计信息

type TypedMessageHandler

type TypedMessageHandler[T any] func(ctx context.Context, channel string, message T) error

TypedMessageHandler 泛型消息处理器

type Uint64KeyCodec

type Uint64KeyCodec struct{}

Uint64KeyCodec uint64 键编解码器

func (Uint64KeyCodec) Decode

func (Uint64KeyCodec) Decode(data string) (uint64, error)

func (Uint64KeyCodec) Encode

func (Uint64KeyCodec) Encode(key uint64) string

type VersionTracker

type VersionTracker struct {
	// contains filtered or unexported fields
}

VersionTracker 资源版本追踪器 用于追踪任意资源的版本号,支持分布式环境下的版本变更检测 使用场景:配置热更新、连接池重建、缓存失效等

func NewVersionTracker

func NewVersionTracker(redisClient redis.UniversalClient, prefix string) *VersionTracker

NewVersionTracker 创建版本追踪器 prefix 为版本键的前缀,建议使用业务模块名,如 "product:"、"payment:"

func (*VersionTracker) BatchUpdateVersion

func (v *VersionTracker) BatchUpdateVersion(ctx context.Context, resourceIDs []string, version int64) error

BatchUpdateVersion 批量更新多个资源的版本号

func (*VersionTracker) BatchUpdateVersionWithNow

func (v *VersionTracker) BatchUpdateVersionWithNow(ctx context.Context, resourceIDs []string) error

BatchUpdateVersionWithNow 批量使用当前时间戳更新版本号

func (*VersionTracker) DeleteVersion

func (v *VersionTracker) DeleteVersion(ctx context.Context, resourceID string) error

DeleteVersion 删除资源版本记录

func (*VersionTracker) DeleteVersions

func (v *VersionTracker) DeleteVersions(ctx context.Context, resourceIDs []string) error

DeleteVersions 批量删除资源版本记录

func (*VersionTracker) GetOrCreateVersion

func (v *VersionTracker) GetOrCreateVersion(ctx context.Context, resourceID string) (int64, error)

GetOrCreateVersion 获取或创建版本号(如果不存在则设置为当前时间戳)

func (*VersionTracker) GetVersion

func (v *VersionTracker) GetVersion(ctx context.Context, resourceID string) (int64, error)

GetVersion 获取资源的当前版本号(从 Redis)

func (*VersionTracker) GetVersionKey

func (v *VersionTracker) GetVersionKey(resourceID string) string

GetVersionKey 获取资源版本的完整 Redis key(用 string + 替代 fmt.Sprintf,零分配)

func (*VersionTracker) HasChanged

func (v *VersionTracker) HasChanged(ctx context.Context, resourceID string, lastVersion int64) (bool, int64)

HasChanged 检查资源版本是否发生变化 lastVersion 为上次记录的版本号,返回 (是否变化, 最新版本号)

func (*VersionTracker) Touch

func (v *VersionTracker) Touch(ctx context.Context, resourceID string) error

Touch 触碰资源版本号(使其递增) 适用于配置变更后需要触发缓存失效的场景

func (*VersionTracker) TouchAll

func (v *VersionTracker) TouchAll(ctx context.Context, resourceIDs []string) error

TouchAll 触碰多个资源版本号

func (*VersionTracker) UpdateVersion

func (v *VersionTracker) UpdateVersion(ctx context.Context, resourceID string, version int64) error

UpdateVersion 更新资源的版本号 version 通常使用时间戳或递增序号

func (*VersionTracker) UpdateVersionWithNow

func (v *VersionTracker) UpdateVersionWithNow(ctx context.Context, resourceID string) error

UpdateVersionWithNow 使用当前时间戳更新版本号

Directories

Path Synopsis
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-19 20:53:00 * @FilePath: \go-toolbox\cachex\\examples\advanced_usage.go * @Description: go-cachex 高级功能使用示例 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-19 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-19 20:53:00 * @FilePath: \go-toolbox\cachex\\examples\advanced_usage.go * @Description: go-cachex 高级功能使用示例 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
ctxcache command
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 21:12:18 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 21:45:21 * @FilePath: \go-toolbox\cachex\\examples\ctxcache\advanced.go * @Description: * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 21:12:18 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 21:45:21 * @FilePath: \go-toolbox\cachex\\examples\ctxcache\advanced.go * @Description: * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
expiring command
* @Description: Expiring Cache 高级使用示例
* @Description: Expiring Cache 高级使用示例
interface_test command
lru command
lru_optimized command
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 22:45:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 22:45:00 * @FilePath: \go-toolbox\cachex\\examples\lru_optimized\basic.go * @Description: LRU优化版本客户端基础使用示例 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
* @Author: kamalyes 501893067@qq.com * @Date: 2025-11-09 22:45:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2025-11-09 22:45:00 * @FilePath: \go-toolbox\cachex\\examples\lru_optimized\basic.go * @Description: LRU优化版本客户端基础使用示例 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
ristretto command
sharded command
* @Description: Sharded Cache 高级使用示例
* @Description: Sharded Cache 高级使用示例
twolevel command
* @Description: TwoLevel Cache 高级使用示例
* @Description: TwoLevel Cache 高级使用示例

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL