3. 核心接口设计:缓存接口抽象与 Get/Set/Delete/DelPattern 定义

作为本地数据库缓存层的基石,接口抽象决定了上层应用与底层存储之间的耦合度。本章从“契约优先”原则出发,定义一套通用缓存接口,将Get、Set、Delete、DelPattern四个核心操作标准化,并给出实现的参考骨架。

3.1 接口设计原则

  • 最小完备性:四个方法即可覆盖绝大部分缓存场景(读、写、单删、批量删除)。
  • 实现无关:接口不暴露底层存储类型(内存、SQLite、RocksDB 等)。
  • 错误可传递:所有操作返回 error 或等效错误对象,支持调用方精细处理。

3.2 接口定义(以 Go 语言为例)

cache.go — 缓存接口抽象
package cache

import "context"

// Cache 定义本地缓存层的基础操作。
// Key 为字符串,Value 为任意可序列化类型(使用字节表示)。
type Cache interface {
    // Get 读取键对应的值,如果不存在返回 ErrMiss。
    Get(ctx context.Context, key string) ([]byte, error)

    // Set 写入键值对,ttl 为过期秒数(0 表示永不过期)。
    Set(ctx context.Context, key string, value []byte, ttl int64) error

    // Delete 删除单个键,无论是否存在都不算错误。
    Delete(ctx context.Context, key string) error

    // DelPattern 批量删除匹配某个前缀/模式的键。
    // pattern 语法由具体实现定义,常见为 glob 或前缀匹配。
    DelPattern(ctx context.Context, pattern string) error

    // Close 释放后端资源(连接、文件句柄等)。
    Close() error
}

// ErrMiss 是缓存未命中的标准错误。
var ErrMiss = errors.New("cache miss")
关键设计点:
① Get 返回 ErrMiss 而非空值,让调用方明确区分“不存在”与“空内容”。
② Delete 对于不存在的键不返回错误,方便幂等调用。
③ DelPattern 采用“模式字符串”而非闭包回调,确保接口可跨语言序列化。

3.3 接口方法对比表

方法输入输出语义
Getkey string(value []byte, error)读取单个键;未命中返回 ErrMiss
Setkey string, value []byte, ttl int64error写入键值对,设置 TTL(秒)
Deletekey stringerror删除单个键,不存在不报错
DelPatternpattern stringerror删除所有匹配 pattern 的键
Close无error关闭资源,清理连接

3.4 接口抽象结构图

下图展示缓存接口层与几种典型实现的关系:

缓存接口抽象与实现结构 Cache 接口 Get(ctx, key) Set(ctx, key, val, ttl) Delete(ctx, key) DelPattern(ctx, pattern) 具体实现(实现 Cache 接口) InMemoryCache 内部使用 sync.Map 支持 TTL 驱逐 SQLiteCache 单表 key/value/expire 支持模式匹配删除 FileCache 每个键存储为独立文件 DelPattern 使用 glob 客户端应用 → 只依赖 Cache 接口

3.5 实现流程与步骤

  1. 定义接口类型:按 3.2 节骨架编写 Cache 接口,包含四个核心方法与 Close。
  2. 选择底层存储:本章后续将用 SQLite 作为首个实现(第 4 章),也可先写一个内存桩实现用于测试。
  3. 实现 Get/Set:Get 从底层查询键,若不存在返回 ErrMiss;Set 写入并记录过期时间。
  4. 实现 Delete:执行删除操作,忽略不存在的键。
  5. 实现 DelPattern:遍历所有键,使用前缀/通配符匹配后逐条删除;注意事务一致性。
  6. 测试接口契约:编写单元测试覆盖正常、空、过期、模式匹配等场景。

3.6 调试与常见错误

⚠️ 常见陷阱
• Get 返回空 slice ([]byte{}) 与 nil 的语义混淆:建议统一用 ErrMiss 而非空值判断。
• DelPattern 如果使用 LIKE 操作,需要对模式中的 %、_ 做转义;最好限制为前缀匹配以避免正则注入。
• TTL 字段类型不一致:接口中统一为 int64 秒,实现内转换为毫秒或时间。

3.7 性能优化提示

  • 批量操作管化:对于 DelPattern 匹配大量键时,使用事务一次性提交删除,避免每条删除独立 I/O。
  • Get 的缓存行:底层实现可对热键增加内存 LRU 缓存(二级缓存),减少数据库访问。
  • 接口方法签名:若语言支持泛型(如 Go 1.18+),可将 Value 类型参数化,避免调用方反复序列化/反序列化。