Golang BigCache 高效数据缓存

缓存概述

缓存是系统提升并发能力、降低时延的利器,根据存储介质和使用场景,我们一般又会使用本地缓存与分布式缓存两种手段。

本地缓存

本地缓存一般是在进程内的,最简单的,用 go 的 sync.Map 就能实现一个简单的并发安全的本地缓存了。常见的,将一些静态的、配置类的数据放置在本地缓存中,能有效降低到下游存储的压力。

分布式缓存

分布式缓存一般会用 redis 或 memcached 等分布式内存数据库来实现,能做到分布式、无状态。

安装工具包

github.com/allegro/bigcache/v3

BigCache 初始化

1. 简单初始化

import "github.com/allegro/bigcache/v3"
// 初始化缓存对象
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute))
// 设置缓存数据
cache.Set("my-unique-key", []byte("value"))
// 获取并打印缓存数据
entry, _ := cache.Get("my-unique-key")
fmt.Println(string(entry))

2. 自定义配置初始化

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/allegro/bigcache/v3"
)

func main() {
    config := bigcache.Config{
        // number of shards (must be a power of 2)
        // 碎片数 (必须为2的倍数)
        Shards: 1024,

        // time after which entry can be evicted
        // 缓存有效期
        LifeWindow: 10 * time.Minute,

        // Interval between removing expired entries (clean up).
        // If set to <= 0 then no action is performed.
        // Setting to < 1 second is counterproductive — bigcache has a one second resolution.
        // 清理过期变量间隔时间
        // If set to <= 0 then no action is performed.
        // 如果设置为0 不进行清理
        CleanWindow: 5 * time.Minute,

        // rps * lifeWindow, used only in initial memory allocation
        // 最大条目数
        MaxEntriesInWindow: 1000 * 10 * 60,

        // max entry size in bytes, used only in initial memory allocation
        // 最大条目大小(字节),仅用于初始内存分配
        MaxEntrySize: 500,

        // prints information about additional memory allocation
        // 打印有关附加内存分配的信息
        Verbose: true,

        // cache will not allocate more memory than this limit, value in MB
        // 缓存不会分配超过此限制的内存,以MB为单位
        HardMaxCacheSize: 8192,

        // callback fired when the oldest entry is removed because of its expiration time or no space left
        // 当最旧的条目因其过期时间或没有剩余空间而被删除时触发回调
        // for the new entry, or because delete was called. A bitmask representing the reason will be returned.
        // 对于新条目,或者因为调用了delete。将返回表示原因的位掩码。
        // Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
        // Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
        OnRemove: nil,

        // OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
        // OnRemoveWithReason 是在最早的条目因其过期时间或没有剩余空间而被删除时触发的回调
        OnRemoveWithReason: nil,
    }

    // 初始化缓存
    cache, initErr := bigcache.NewBigCache(config)
    if initErr != nil {
        log.Fatal(initErr)
    }
    // 设置缓存
    cache.Set("my-unique-key", []byte("test content ...99"))
    // 读取缓存
    if entry, err := cache.Get("my-unique-key"); err == nil {
        fmt.Println(string(entry))
    }
    // 延迟 10 秒第二次获取缓存
    time.Sleep(time.Second * 10)
    if entry, err := cache.Get("my-unique-key"); err == nil {
        fmt.Println("第2次获取缓存数据")
        fmt.Println(string(entry))
    }
}