package
1.1.21
Repository: https://github.com/guancecloud/cliutils.git
Documentation: pkg.go.dev

# README

diskcache

diskcache 是一种类似 wal 的磁盘缓存,它有如下特性:

  • 支持并行读写
  • 支持分片大小控制
  • 支持单条数据大小控制
  • 支持磁盘大小控制(FIFO)

限制:

  • 不支持随机读取,只支持按照 FIFO 的顺序来消费数据

实现算法

Always put data to this file.
 |
 |   
 v   
data 
 |    Rotate: if `data` full, move to tail[data.0000000(n+1)]
 `-----------------------------------------------------------.
                                                             |
| data.00000000 | data.00000001 | data.00000002 | ....  <----`
      ^
      `----------------- Always read from this file(the file with smallest number)
  • 当前正在写入的文件 data 不会实时消费,如果最近没有写入(3s),读取操作会将 data rotate 一下并消费
  • 数据从 data.00000001 处开始消费(Get),如果队列上没有可消费的数据,Get 操作将返回 ErrEOF
  • data 写满之后,将会在队列尾部追加一个新的文件,并重新创建 data 写入

使用

以下是基本的使用方式:

import "github.com/GuanceCloud/diskcache"

// Create new cache under /some/path
c, err := diskcache.Open(WithPath("/some/path"))

// Create new cache under /some/path, set batch size to 4MB
c, err := diskcache.Open(WithPath("/some/path"), WithBatchSize(4*1024*1024))

// Create new cache under /some/path, set cache capacity to 1GB
c, err := diskcache.Open(WithPath("/some/path"), WithCapacity(1024*1024*1024))

if err != nil {
	log.Printf(err)
	return
}

// Put data to
data := []byte("my app data...")
if err := c.Put(data); err != nil {
	log.Printf(err)
	return
}

if err := c.Get(func(x []byte) error {
	// Do something with the cached data...
	return nil
	}); err != nil {
	log.Printf(err)
	return
}

// get cache metrics
m := c.Metrics()
log.Println(m.LineProto()) // get line-protocol format of metrics

这种方式可以直接以并行的方式来使用,调用方无需针对这里的 diskcache 对象 c 做互斥处理。

通过 ENV 控制缓存 option

支持通过如下环境变量来覆盖默认的缓存配置:

环境变量描述
ENV_DISKCACHE_BATCH_SIZE设置单个磁盘文件大小,单位字节,默认 64MB
ENV_DISKCACHE_MAX_DATA_SIZE限制单次写入的字节大小,避免意料之外的巨量数据写入,单位字节,默认不限制
ENV_DISKCACHE_CAPACITY限制缓存能使用的磁盘上限,一旦用量超过该限制,老数据将被移除掉。默认不限制
ENV_DISKCACHE_NO_SYNC禁用磁盘写入的 sync 同步,默认不开启。一旦开启,可能导致磁盘数据丢失问题
ENV_DISKCACHE_NO_LOCK禁用文件目录夹锁。默认是加锁状态,一旦不加锁,在同一个目录多开(Open)可能导致文件混乱
ENV_DISKCACHE_NO_POS禁用磁盘写入位置记录,默认带有位置记录。一旦不记录,程序重启会导致部分数据重复消费(Get
ENV_DISKCACHE_NO_FALLBACK_ON_ERROR禁用错误回退机制

Prometheus 指标

所有指标可选的 label 列表如下:

label取值说明
no_fallback_on_errortrue/false是否关闭错误回退(即禁止 Get() 回调失败时,再次读到老的数据)
no_locktrue/false是否关闭加锁功能(即允许一个 cache 目录同时被多次 Open()
no_postrue/false是否关闭 pos 功能
no_synctrue/false是否关闭同步写入功能
pathcache 所在磁盘目录cache 所在磁盘目录

指标列表如下:

TYPENAMELABELSHELP
COUNTERdiskcache_put_bytes_totalpathCache Put() bytes count
COUNTERdiskcache_get_totalpathCache Get() count
COUNTERdiskcache_wakeup_totalpathWakeup count on sleeping write file
COUNTERdiskcache_get_bytes_totalpathCache Get() bytes count
GAUGEdiskcache_capacitypathCurrent capacity(in bytes)
GAUGEdiskcache_max_datapathMax data to Put(in bytes), default 0
GAUGEdiskcache_batch_sizepathData file size(in bytes)
GAUGEdiskcache_sizepathCurrent cache size(in bytes)
GAUGEdiskcache_open_timeno_fallback_on_error,no_lock,no_pos,no_sync,pathCurrent cache Open time in unix timestamp(second)
GAUGEdiskcache_last_close_timepathCurrent cache last Close time in unix timestamp(second)
GAUGEdiskcache_datafilespathCurrent un-readed data files
SUMMARYdiskcache_get_latencypathGet() time cost(micro-second)
SUMMARYdiskcache_put_latencypathPut() time cost(micro-second)
COUNTERdiskcache_dropped_bytes_totalpathDropped bytes during Put() when capacity reached.
COUNTERdiskcache_dropped_totalpathDropped files during Put() when capacity reached.
COUNTERdiskcache_rotate_totalpathCache rotate count, mean file rotate from data to data.0000xxx
COUNTERdiskcache_remove_totalpathRemoved file count, if some file read EOF, remove it from un-readed list
COUNTERdiskcache_put_totalpathCache Put() count

性能估算

测试环境:

  • Model Name : MacBook Pro
  • Model Identifier : MacBookPro18,1
  • Chip : Apple M1 Pro
  • Total Number of Cores : 10 (8 performance and 2 efficiency)
  • Memory : 16 GB

详见测试用例 TestConcurrentPutGetPerf

单次写入的数据量在 100KB ~ 1MB 之间,分别测试单线程写入、多线程写入、多线程读写情况下的性能:

测试情况worker性能(字节/毫秒)
单线程写入1119708 bytes/ms
多线程写入10118920 bytes/ms
多线程读写10+10118920 bytes/ms

综合下来,不管多线程读写还是单线程读写,其 IO 性能在当前的硬件上能达到 100MB/s 的速度。

TODO

  • 支持一次 Get()/Put() 多个数据,提高加锁的数据吞吐量
  • 支持 Get() 出错时重试机制(WithErrorRetry(n)
  • 可执行程序(cmd/diskcache)支持查看已有(可能正在被其它进程占用)diskcache 的存储情况

# Functions

No description provided by the author
Open init and create a new disk cache.
ResetMetrics used to cleanup exist metrics of diskcache.
WithBatchSize set file size, default 64MB.
WithCapacity set cache capacity, default unlimited.
WithDirPermission set disk dir permission mode.
WithExtraCapacity add capacity to existing cache.
WithFilePermission set cache file permission mode.
WithMaxDataSize set max single data size, default 32MB.
WithNoFallbackOnError disable fallback on fn() error.
WithNoLock set .lock on or off.
WithNoPos set .pos on or off.
WithNoSync enable/disable sync on cache write.
WithPath set disk dirname.
WithWakeup set duration on wakeup(default 3s), this wakeup time used to shift current-writing-file to ready-to-reading-file.

# Constants

EOFHint labels a file's end.

# Variables

Invalid file header.
Get on no data cache.
Invalid cache filename.
Generic diskcache errors.
Data send to Put() exceed the maxDataSize.
Invalid read size.

# Structs

DiskCache is the representation of a disk cache.

# Type aliases

A CacheOption used to set various options on DiskCache.
Fn is the handler to eat cache from diskcache.