github.com/GuanceCloud/cliutils@v1.1.21/diskcache/README.md (about)

     1  # diskcache
     2  
     3  diskcache 是一种类似 wal 的磁盘缓存,它有如下特性:
     4  
     5  - 支持并行读写
     6  - 支持分片大小控制
     7  - 支持单条数据大小控制
     8  - 支持磁盘大小控制(FIFO)
     9  
    10  限制:
    11  
    12  - 不支持随机读取,只支持按照 FIFO 的顺序来消费数据
    13  
    14  ## 实现算法
    15  
    16  ```
    17  Always put data to this file.
    18   |
    19   |   
    20   v   
    21  data 
    22   |    Rotate: if `data` full, move to tail[data.0000000(n+1)]
    23   `-----------------------------------------------------------.
    24                                                               |
    25  | data.00000000 | data.00000001 | data.00000002 | ....  <----`
    26        ^
    27        `----------------- Always read from this file(the file with smallest number)
    28  ```
    29  
    30  - 当前正在写入的文件 `data` 不会实时消费,如果最近没有写入(3s),读取操作会将 `data` rotate 一下并消费
    31  - 数据从 `data.00000001` 处开始消费(`Get`),如果队列上没有可消费的数据,`Get` 操作将返回 `ErrEOF`
    32  - `data` 写满之后,将会在队列尾部追加一个新的文件,并重新创建 `data` 写入
    33  
    34  ## 使用
    35  
    36  以下是基本的使用方式:
    37  
    38  ```golang
    39  import "github.com/GuanceCloud/diskcache"
    40  
    41  // Create new cache under /some/path
    42  c, err := diskcache.Open(WithPath("/some/path"))
    43  
    44  // Create new cache under /some/path, set batch size to 4MB
    45  c, err := diskcache.Open(WithPath("/some/path"), WithBatchSize(4*1024*1024))
    46  
    47  // Create new cache under /some/path, set cache capacity to 1GB
    48  c, err := diskcache.Open(WithPath("/some/path"), WithCapacity(1024*1024*1024))
    49  
    50  if err != nil {
    51  	log.Printf(err)
    52  	return
    53  }
    54  
    55  // Put data to
    56  data := []byte("my app data...")
    57  if err := c.Put(data); err != nil {
    58  	log.Printf(err)
    59  	return
    60  }
    61  
    62  if err := c.Get(func(x []byte) error {
    63  	// Do something with the cached data...
    64  	return nil
    65  	}); err != nil {
    66  	log.Printf(err)
    67  	return
    68  }
    69  
    70  // get cache metrics
    71  m := c.Metrics()
    72  log.Println(m.LineProto()) // get line-protocol format of metrics
    73  ```
    74  
    75  这种方式可以直接以并行的方式来使用,调用方无需针对这里的 diskcache 对象 `c` 做互斥处理。
    76  
    77  ## 通过 ENV 控制缓存 option
    78  
    79  支持通过如下环境变量来覆盖默认的缓存配置:
    80  
    81  | 环境变量                           | 描述                                                                                        |
    82  | ---                                | ---                                                                                         |
    83  | ENV_DISKCACHE_BATCH_SIZE           | 设置单个磁盘文件大小,单位字节,默认 64MB                                                   |
    84  | ENV_DISKCACHE_MAX_DATA_SIZE        | 限制单次写入的字节大小,避免意料之外的巨量数据写入,单位字节,默认不限制                    |
    85  | ENV_DISKCACHE_CAPACITY             | 限制缓存能使用的磁盘上限,一旦用量超过该限制,老数据将被移除掉。默认不限制                  |
    86  | ENV_DISKCACHE_NO_SYNC              | 禁用磁盘写入的 sync 同步,默认不开启。一旦开启,可能导致磁盘数据丢失问题                    |
    87  | ENV_DISKCACHE_NO_LOCK              | 禁用文件目录夹锁。默认是加锁状态,一旦不加锁,在同一个目录多开(`Open`)可能导致文件混乱    |
    88  | ENV_DISKCACHE_NO_POS               | 禁用磁盘写入位置记录,默认带有位置记录。一旦不记录,程序重启会导致部分数据重复消费(`Get`) |
    89  | ENV_DISKCACHE_NO_FALLBACK_ON_ERROR | 禁用错误回退机制                                                                            |
    90  
    91  
    92  ## Prometheus 指标
    93  
    94  所有指标可选的 label 列表如下:
    95  
    96  | label                | 取值               | 说明                                                          |
    97  | ---                  | ---                | ---                                                           |
    98  | no_fallback_on_error | true/false         | 是否关闭错误回退(即禁止 Get() 回调失败时,再次读到老的数据) |
    99  | no_lock              | true/false         | 是否关闭加锁功能(即允许一个 cache 目录同时被多次 `Open()`)  |
   100  | no_pos               | true/false         | 是否关闭 pos 功能                                             |
   101  | no_sync              | true/false         | 是否关闭同步写入功能                                          |
   102  | path                 | cache 所在磁盘目录 | cache 所在磁盘目录                                            |
   103  
   104  指标列表如下:
   105  
   106  | TYPE    | NAME                            | LABELS                                             | HELP                                                                     |
   107  | ---     | ---                             | ---                                                | ---                                                                      |
   108  | COUNTER | `diskcache_put_bytes_total`     | `path`                                             | Cache Put() bytes count                                                  |
   109  | COUNTER | `diskcache_get_total`           | `path`                                             | Cache Get() count                                                        |
   110  | COUNTER | `diskcache_wakeup_total`        | `path`                                             | Wakeup count on sleeping write file                                      |
   111  | COUNTER | `diskcache_get_bytes_total`     | `path`                                             | Cache Get() bytes count                                                  |
   112  | GAUGE   | `diskcache_capacity`            | `path`                                             | Current capacity(in bytes)                                               |
   113  | GAUGE   | `diskcache_max_data`            | `path`                                             | Max data to Put(in bytes), default 0                                     |
   114  | GAUGE   | `diskcache_batch_size`          | `path`                                             | Data file size(in bytes)                                                 |
   115  | GAUGE   | `diskcache_size`                | `path`                                             | Current cache size(in bytes)                                             |
   116  | GAUGE   | `diskcache_open_time`           | `no_fallback_on_error,no_lock,no_pos,no_sync,path` | Current cache Open time in unix timestamp(second)                        |
   117  | GAUGE   | `diskcache_last_close_time`     | `path`                                             | Current cache last Close time in unix timestamp(second)                  |
   118  | GAUGE   | `diskcache_datafiles`           | `path`                                             | Current un-readed data files                                             |
   119  | SUMMARY | `diskcache_get_latency`         | `path`                                             | Get() time cost(micro-second)                                            |
   120  | SUMMARY | `diskcache_put_latency`         | `path`                                             | Put() time cost(micro-second)                                            |
   121  | COUNTER | `diskcache_dropped_bytes_total` | `path`                                             | Dropped bytes during Put() when capacity reached.                        |
   122  | COUNTER | `diskcache_dropped_total`       | `path`                                             | Dropped files during Put() when capacity reached.                        |
   123  | COUNTER | `diskcache_rotate_total`        | `path`                                             | Cache rotate count, mean file rotate from data to data.0000xxx           |
   124  | COUNTER | `diskcache_remove_total`        | `path`                                             | Removed file count, if some file read EOF, remove it from un-readed list |
   125  | COUNTER | `diskcache_put_total`           | `path`                                             | Cache Put() count                                                        |
   126  
   127  ## 性能估算
   128  
   129  测试环境:
   130  
   131  - Model Name            : MacBook Pro
   132  - Model Identifier      : MacBookPro18,1
   133  - Chip                  : Apple M1 Pro
   134  - Total Number of Cores : 10 (8 performance and 2 efficiency)
   135  - Memory                : 16 GB
   136  
   137  > 详见测试用例 `TestConcurrentPutGetPerf`。
   138  
   139  单次写入的数据量在 100KB ~ 1MB 之间,分别测试单线程写入、多线程写入、多线程读写情况下的性能:
   140  
   141  | 测试情况   | worker | 性能(字节/毫秒) |
   142  | ---        | ---    | ---               |
   143  | 单线程写入 | 1      | 119708 bytes/ms   |
   144  | 多线程写入 | 10     | 118920 bytes/ms   |
   145  | 多线程读写 | 10+10  | 118920 bytes/ms   |
   146  
   147  综合下来,不管多线程读写还是单线程读写,其 IO 性能在当前的硬件上能达到 100MB/s 的速度。
   148  
   149  ## TODO
   150  
   151  - [ ] 支持一次 `Get()/Put()` 多个数据,提高加锁的数据吞吐量
   152  - [ ] 支持 `Get()` 出错时重试机制(`WithErrorRetry(n)`)
   153  - [ ] 可执行程序(*cmd/diskcache*)支持查看已有(可能正在被其它进程占用)diskcache 的存储情况