Documentation
¶
Overview ¶
Package cache 提供有界内存缓存(带淘汰)与防击穿加载器,是 web/API 读路径的常用原语:
- Cache 接口:并发安全的 Get/Set/Delete/Len,容量有界、满了自动淘汰;
- LRU:经典最近最少使用(container/list),小巧、可预测;
- TinyLFU(W-TinyLFU):窗口 LRU + 主 SLRU + Count-Min 频率准入,命中率接近最优、抗扫描 (一次性大量冷 key 不会冲垮热点),内存开销极小(每 key 4-bit 频率计数);
- Loader:Cache + singleflight + TTL + 负缓存,一站式解决缓存穿透/击穿/雪崩(见 loader.go)。
边界(机制而非策略):容量、TTL、用 LRU 还是 TinyLFU、回源逻辑都由调用方定。纯标准库,泛型键值。
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache[K comparable, V any] interface { Get(key K) (V, bool) Set(key K, value V) Delete(key K) Len() int }
Cache 是并发安全、容量有界的缓存。达到容量后写入会触发淘汰。
type LRU ¶
type LRU[K comparable, V any] struct { // contains filtered or unexported fields }
LRU 是经典的最近最少使用缓存:容量满时淘汰最久未使用的项。并发安全。
type Loader ¶
type Loader[V any] struct { // contains filtered or unexported fields }
Loader 是防击穿的缓存加载器:在一个有界 Cache 之上叠加 singleflight(同 key 并发回源只打一次)、 TTL(过期惰性失效)与负缓存(失败也短暂缓存),一站式化解缓存穿透/击穿/雪崩。
- 穿透:load 失败结果按 negTTL 短暂缓存,挡住对不存在数据的反复回源(negTTL>0 时);
- 击穿:同一 key 的并发 miss 经 singleflight 合并,只有一个真正回源,其余等待其结果;
- 雪崩:容量有界的 Cache + 各自 TTL,避免同刻大量 key 同时失效冲垮下游(可配合抖动 TTL)。
键为 string(缓存回源多以 URL/ID 为键);值为泛型 V。并发安全。
func NewLRULoader ¶
func NewLRULoader[V any](capacity int, load func(ctx context.Context, key string) (V, error), opts ...LoaderOption) *Loader[V]
NewLRULoader 便捷构造:LRU(capacity) + Loader。
func NewLoader ¶
func NewLoader[V any](c Cache[string, item[V]], load func(ctx context.Context, key string) (V, error), opts ...LoaderOption) *Loader[V]
NewLoader 用给定的底层缓存 c 与回源函数 load 构造 Loader。 c 建议用 NewLRU / NewTinyLFU 之一(容量有界)。
type LoaderOption ¶
type LoaderOption func(*loaderCfg)
LoaderOption 配置 Loader。
func WithNegativeTTL ¶
func WithNegativeTTL(d time.Duration) LoaderOption
WithNegativeTTL 设置失败结果的缓存时长(负缓存;<=0 表示不缓存错误)。
type TinyLFU ¶
type TinyLFU[K comparable, V any] struct { // contains filtered or unexported fields }
TinyLFU 是 W-TinyLFU 缓存:小窗口 LRU(承接新写入的突发)+ 主 SLRU(probation/protected 两段)。 当窗口淘汰一个候选者时,用 Count-Min 频率与主区的淘汰victim 比较,频率更高才准入——于是 一次性涌入的大量冷 key(扫描)无法挤掉真正的热点。命中率通常显著高于纯 LRU,内存仅多一份草图。
func NewTinyLFU ¶
func NewTinyLFU[K comparable, V any](capacity int) *TinyLFU[K, V]
NewTinyLFU 创建容量为 capacity 的 W-TinyLFU(capacity<=0 视为 1)。