cache

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2025 License: MIT Imports: 3 Imported by: 0

README

Cache 包

cache 包提供了一个基于 ristretto 的高性能进程内缓存实现,支持基本的缓存操作和过期时间设置。

特性

  • 高性能进程内缓存(基于 ristretto)
  • 支持过期时间设置(TTL)
  • 支持泛型和类型安全
  • 支持全局缓存实例
  • 线程安全
  • 基于 LFU(最不经常使用)的驱逐策略
  • 自动内存管理

快速开始

基本使用
package main

import (
    "fmt"
    "time"
    "github.com/fsyyft-go/kit/cache"
)

func main() {
    // 初始化缓存
    if err := cache.InitCache(); err != nil {
        panic(err)
    }
    defer cache.Close()

    // 设置缓存
    cache.Set("key", "value")                    // 永不过期
    cache.SetWithTTL("temp", "value", time.Hour) // 1 小时后过期

    // 获取缓存
    if val, exists := cache.Get("key"); exists {
        fmt.Printf("value: %v\n", val)
    }

    // 获取带 TTL 的缓存
    if val, exists, ttl := cache.GetWithTTL("temp"); exists {
        fmt.Printf("值:%v,剩余时间:%v\n", val, ttl)
    }

    // 删除缓存
    cache.Delete("key")
}
使用泛型接口
// 创建类型安全的缓存包装器
strCache := cache.AsTypedCache[string](cache.NewCache())
intCache := cache.AsTypedCache[int](cache.NewCache())

// 类型安全的操作
strCache.Set("str", "hello")
intCache.Set("int", 42)

// 无需类型断言
str, exists := strCache.Get("str")
num, exists := intCache.Get("int")

配置选项

// 自定义配置
if err := cache.InitCache(
    cache.WithNumCounters(1e7),    // 跟踪的最大条目数(建议是实际条目数的 10 倍)
    cache.WithMaxCost(1<<30),      // 最大内存使用(字节)
    cache.WithBufferItems(64),     // 写入缓冲区大小
); err != nil {
    panic(err)
}
配置说明
  • NumCounters:缓存跟踪的最大条目数,建议设置为预期独特条目数的 10 倍
  • MaxCost:缓存的最大成本(可理解为最大条目数)
  • BufferItems:写入操作的缓冲区大小,更大的缓冲区会提高并发性能,但会使用更多内存

最佳实践

  1. 合理设置配置参数

    • NumCounters 建议设置为预期条目数的 10 倍
    • MaxCost 根据实际内存限制设置
    • BufferItems 默认值 64 适合大多数场景
  2. 使用类型安全的接口

    • 优先使用 TypedCache 避免类型断言
    • 为不同类型的数据创建专门的缓存实例
  3. 性能优化

    • 合理设置缓存大小避免频繁驱逐
    • 注意及时清理不需要的缓存项
    • 使用 Close 释放资源
  4. 错误处理

    • 总是检查 InitCache 的返回错误
    • 使用 defer Close() 确保资源释放
    • 检查 Get 操作的 exists 返回值

贡献

欢迎提交 Issue 和 Pull Request 来帮助改进这个包。

许可证

本项目采用 MIT License 许可证。详见 LICENSE 文件。

Documentation

Overview

Package cache 提供了一个统一的缓存接口和多种缓存实现。 这个包的主要特性包括:

  • 支持多种缓存后端(默认使用 ristretto)
  • 提供统一的缓存接口
  • 支持泛型和类型安全
  • 支持 TTL(生存时间)设置
  • 支持全局缓存实例
  • 线程安全

基本使用示例:

// 创建缓存实例
cache, err := cache.NewCache()  // 使用默认配置
if err != nil {
    panic(err)
}
defer cache.Close()

// 基本操作
cache.Set("key", "value")                    // 设置永不过期的值
cache.SetWithTTL("temp", "value", time.Hour) // 设置 1 小时后过期的值

// 获取值
if val, exists := cache.Get("key"); exists {
    fmt.Println(val)
}

// 获取带 TTL 的值
if val, exists, ttl := cache.GetWithTTL("temp"); exists {
    fmt.Printf("值:%v,剩余时间:%v\n", val, ttl)
}

更多示例请参考 example/cache 目录。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Clear

func Clear()

Clear 清空全局缓存。 如果全局缓存未初始化,该操作将被忽略。 这个操作会立即使所有缓存项失效。

func Close

func Close() error

Close 关闭全局缓存。 如果全局缓存未初始化,将返回 nil。 关闭后的全局缓存不应该再被使用。

返回值:

  • error:如果关闭过程中发生错误则返回错误

func Delete

func Delete(key interface{})

Delete 从全局缓存中删除值。 如果全局缓存未初始化,该操作将被忽略。

参数:

  • key:要删除的缓存键

func Get

func Get(key interface{}) (interface{}, bool)

Get 从全局缓存中获取值。 如果全局缓存未初始化,将返回 (nil, false)。

参数:

  • key:要获取的缓存键

返回值:

  • value:缓存的值,如果不存在则为 nil
  • exists:值是否存在且未过期

func GetWithTTL

func GetWithTTL(key interface{}) (interface{}, bool, time.Duration)

GetWithTTL 从全局缓存中获取值及其剩余过期时间。 如果全局缓存未初始化,将返回 (nil, false, 0)。

参数:

  • key:要获取的缓存键

返回值:

  • value:缓存的值,如果不存在则为 nil
  • exists:值是否存在且未过期
  • remainingTTL:剩余过期时间:
  • 如果值不存在或已过期,返回 0
  • 如果值永不过期,返回 -1
  • 否则返回实际的剩余时间

func InitCache

func InitCache(options ...Option) error

InitCache 初始化全局缓存实例。 这个函数使用 sync.Once 确保全局缓存只被初始化一次。 如果已经初始化过,该函数将不会执行任何操作。

参数:

  • options:可选的配置选项,如果不提供则使用默认配置

返回值:

  • error:如果初始化失败则返回错误

示例:

// 使用默认配置
if err := cache.InitCache(); err != nil {
    panic(err)
}
defer cache.Close()

// 使用自定义配置
if err := cache.InitCache(
    cache.WithNumCounters(1e7),
    cache.WithMaxCost(1<<30),
    cache.WithBufferItems(64),
); err != nil {
    panic(err)
}
defer cache.Close()

// 使用 CacheOptions 配置(迁移方式)
if err := cache.InitCache(cache.WithOptions(cache.DefaultConfig())...); err != nil {
    panic(err)
}
defer cache.Close()

func Set

func Set(key interface{}, value interface{}) bool

Set 设置全局缓存中的值。 如果全局缓存未初始化,将返回 false。

参数:

  • key:缓存键
  • value:要缓存的值

返回值:

  • bool:是否设置成功

func SetWithTTL

func SetWithTTL(key interface{}, value interface{}, ttl time.Duration) bool

SetWithTTL 设置全局缓存中的值,带过期时间。 如果全局缓存未初始化,将返回 false。

参数:

  • key:缓存键
  • value:要缓存的值
  • ttl:过期时间,如果 <= 0 则表示永不过期

返回值:

  • bool:是否设置成功

Types

type Cache

type Cache interface {
	// Get 获取缓存中的值。
	// 如果键不存在或已过期,exists 将返回 false。
	// 返回值:
	//   - value:缓存的值,如果不存在则为 nil
	//   - exists:值是否存在且未过期
	Get(key interface{}) (value interface{}, exists bool)

	// GetWithTTL 获取缓存中的值及其剩余过期时间。
	// 如果键不存在或已过期,exists 将返回 false。
	// 返回值:
	//   - value:缓存的值,如果不存在则为 nil
	//   - exists:值是否存在且未过期
	//   - remainingTTL:剩余过期时间:
	//     * 如果值不存在或已过期,返回 0
	//     * 如果值永不过期,返回 -1
	//     * 否则返回实际的剩余时间
	GetWithTTL(key interface{}) (value interface{}, exists bool, remainingTTL time.Duration)

	// Set 设置缓存值,该值永不过期。
	// 参数:
	//   - key:缓存键,可以是任意类型
	//   - value:要缓存的值,可以是任意类型
	// 返回值:
	//   - bool:是否设置成功
	Set(key interface{}, value interface{}) bool

	// SetWithTTL 设置带过期时间的缓存值。
	// 参数:
	//   - key:缓存键,可以是任意类型
	//   - value:要缓存的值,可以是任意类型
	//   - ttl:过期时间,如果 <= 0 则表示永不过期
	// 返回值:
	//   - bool:是否设置成功
	SetWithTTL(key interface{}, value interface{}, ttl time.Duration) bool

	// Delete 从缓存中删除指定的键。
	// 如果键不存在,该操作也会成功返回。
	// 删除后,该键的所有后续访问都将返回不存在。
	Delete(key interface{})

	// Clear 清空缓存中的所有内容。
	// 这个操作会立即使所有缓存项失效。
	// 在清空后,所有之前的键都将返回不存在。
	Clear()

	// Close 关闭缓存,释放相关资源。
	// 关闭后的缓存不应该再被使用。
	// 重复调用 Close 是安全的。
	Close() error
}

Cache 定义了统一的缓存接口。 这个接口提供了基本的缓存操作功能,可以通过不同的实现来支持不同的缓存后端。 所有的实现都必须保证线程安全。

func NewCache

func NewCache(options ...Option) (Cache, error)

NewCache 创建一个新的缓存实例。 使用 Option 模式配置缓存参数,如果没有提供任何选项,将使用默认配置:

  • NumCounters:1000 万(适合跟踪 100 万个不同的键)
  • MaxCost:1GB(适合存储较大的数据集)
  • BufferItems:64(提供良好的并发性能)

参数:

  • options:可选的配置选项,如果不提供则使用默认配置

返回值:

  • Cache:缓存接口实现
  • error:如果创建失败则返回错误

示例:

// 使用默认配置
cache, err := cache.NewCache()
if err != nil {
    panic(err)
}
defer cache.Close()

// 使用自定义配置
cache, err := cache.NewCache(
    cache.WithNumCounters(1e7),
    cache.WithMaxCost(1<<30),
    cache.WithBufferItems(64),
)
if err != nil {
    panic(err)
}
defer cache.Close()

type CacheOptions

type CacheOptions struct {
	// NumCounters 定义了缓存跟踪的最大条目数。
	// 这个数字应该是预期独特条目数的大约 10 倍。
	// 例如,如果预计会有 1 万个不同的键,则应设置为 10 万。
	NumCounters int64

	// MaxCost 定义了缓存的最大成本。
	// 对于简单的缓存使用场景,这可以理解为最大条目数。
	// 当缓存达到这个限制时,最少使用的项目将被驱逐。
	MaxCost int64

	// BufferItems 定义了在写入操作时的缓冲大小。
	// 更大的缓冲区会导致更好的并发性能,但会使用更多的内存。
	// 对于大多数场景,默认值 64 是合适的。
	BufferItems int64
}

CacheOptions 定义了缓存的配置选项。 这些配置项会影响缓存的性能和资源使用。

type Option

type Option func(*CacheOptions)

Option 定义了缓存配置的函数选项。

func WithBufferItems

func WithBufferItems(bufferItems int64) Option

WithBufferItems 设置写入操作时的缓冲大小。 更大的缓冲区会导致更好的并发性能,但会使用更多的内存。

func WithMaxCost

func WithMaxCost(maxCost int64) Option

WithMaxCost 设置缓存的最大成本。 对于简单的缓存使用场景,这可以理解为最大条目数。

func WithNumCounters

func WithNumCounters(numCounters int64) Option

WithNumCounters 设置缓存跟踪的最大条目数。 numCounters 应该是预期独特条目数的大约 10 倍。

type TypedCache

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

TypedCache 是一个泛型包装器,提供类型安全的缓存操作。 通过泛型参数 T 指定缓存值的类型,避免了手动类型断言。 这个包装器适用于需要类型安全的场景,例如:

  • 存储特定类型的数据
  • 避免运行时类型错误
  • 提供更好的 IDE 支持

func AsTypedCache

func AsTypedCache[T any](cache Cache) *TypedCache[T]

AsTypedCache 将缓存转换为类型安全的包装器。 参数:

  • cache:底层的缓存实现

返回值:

  • *TypedCache[T]:类型安全的缓存包装器

示例:

baseCache := cache.NewCache()
strCache := cache.AsTypedCache[string](baseCache)
intCache := cache.AsTypedCache[int](baseCache)

func (*TypedCache[T]) Clear

func (tc *TypedCache[T]) Clear()

Clear 清空缓存中的所有内容。 这个操作与底层缓存的 Clear 操作相同。

func (*TypedCache[T]) Close

func (tc *TypedCache[T]) Close() error

Close 关闭缓存,释放相关资源。 这个操作与底层缓存的 Close 操作相同。

func (*TypedCache[T]) Delete

func (tc *TypedCache[T]) Delete(key interface{})

Delete 从缓存中删除指定的键。 这个操作与底层缓存的 Delete 操作相同。

func (*TypedCache[T]) Get

func (tc *TypedCache[T]) Get(key interface{}) (value T, exists bool)

Get 获取缓存中的值,并进行类型转换。 如果键不存在、已过期或类型不匹配,exists 将返回 false。 返回的值已经是正确的类型,无需进行类型断言。

func (*TypedCache[T]) GetWithTTL

func (tc *TypedCache[T]) GetWithTTL(key interface{}) (value T, exists bool, remainingTTL time.Duration)

GetWithTTL 获取缓存中的值及其剩余过期时间,并进行类型转换。 如果键不存在、已过期或类型不匹配,exists 将返回 false。 返回的值已经是正确的类型,无需进行类型断言。

func (*TypedCache[T]) Set

func (tc *TypedCache[T]) Set(key interface{}, value T) bool

Set 设置缓存值,该值永不过期。 参数值必须匹配泛型类型 T,这在编译时就能保证。

func (*TypedCache[T]) SetWithTTL

func (tc *TypedCache[T]) SetWithTTL(key interface{}, value T, ttl time.Duration) bool

SetWithTTL 设置带过期时间的缓存值。 参数值必须匹配泛型类型 T,这在编译时就能保证。

Jump to

Keyboard shortcuts

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