cache

package
v0.7.5 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

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 是经典的最近最少使用缓存:容量满时淘汰最久未使用的项。并发安全。

func NewLRU

func NewLRU[K comparable, V any](capacity int) *LRU[K, V]

NewLRU 创建容量为 capacity 的 LRU(capacity<=0 视为容量 1)。

func (*LRU[K, V]) Delete

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

Delete 删除一个键。

func (*LRU[K, V]) Get

func (c *LRU[K, V]) Get(key K) (V, bool)

Get 取值并将其标记为最近使用。

func (*LRU[K, V]) Len

func (c *LRU[K, V]) Len() int

Len 返回当前元素数。

func (*LRU[K, V]) Set

func (c *LRU[K, V]) Set(key K, value V)

Set 写入或更新;超出容量则淘汰队尾(最久未使用)。

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 之一(容量有界)。

func (*Loader[V]) Forget

func (l *Loader[V]) Forget(key string)

Forget 使某个 key 的缓存与在途 singleflight 失效(下次 Get 强制回源)。

func (*Loader[V]) Get

func (l *Loader[V]) Get(ctx context.Context, key string) (V, error)

Get 返回 key 对应的值:命中未过期缓存直接返回;否则经 singleflight 回源(同 key 并发合并)。

注意:singleflight 合并后,等待中的调用方共享同一次回源结果,其 ctx 取消不会中断 已在执行的 load;这是 singleflight 的固有行为,调用方应自行处理超时/取消后的返回值。

type LoaderOption

type LoaderOption func(*loaderCfg)

LoaderOption 配置 Loader。

func WithClock

func WithClock(now func() time.Time) LoaderOption

WithClock 注入时间源(测试用)。

func WithNegativeTTL

func WithNegativeTTL(d time.Duration) LoaderOption

WithNegativeTTL 设置失败结果的缓存时长(负缓存;<=0 表示不缓存错误)。

func WithTTL

func WithTTL(d time.Duration) LoaderOption

WithTTL 设置成功结果的缓存时长(<=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)。

func (*TinyLFU[K, V]) Delete

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

func (*TinyLFU[K, V]) Get

func (c *TinyLFU[K, V]) Get(key K) (V, bool)

func (*TinyLFU[K, V]) Len

func (c *TinyLFU[K, V]) Len() int

func (*TinyLFU[K, V]) Set

func (c *TinyLFU[K, V]) Set(key K, value V)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL