From 5c033d37fbb7c257cc8107eabc4c51c7049c408a Mon Sep 17 00:00:00 2001 From: doashenzzg Date: Wed, 6 Mar 2024 09:35:39 +0800 Subject: [PATCH] docs: update --- README.md | 96 +++++++++++++++++------------------ README_zh.md => README_en.md | 97 +++++++++++++++++++----------------- 2 files changed, 97 insertions(+), 96 deletions(-) rename README_zh.md => README_en.md (59%) diff --git a/README.md b/README.md index f3b7ea6..6b13bd7 100644 --- a/README.md +++ b/README.md @@ -5,33 +5,32 @@ License

-Translate to: [简体中文](README_zh.md) - -# Introduction -[jetcache-go](https://github.com/daoshenzzg/jetcache-go) is a general-purpose cache access framework based on -[go-redis/cache](https://github.com/go-redis/cache). It implements the core features of the Java version of -[JetCache](https://github.com/alibaba/jetcache), including: - -- ✅ Flexible combination of two-level caching: You can use memory, Redis, or your own custom storage method. -- ✅ The `Once` interface adopts the `singleflight` pattern, which is highly concurrent and thread-safe. -- ✅ By default, [sonic](https://github.com/bytedance/sonic) is used for encoding and decoding values. Optional [MsgPack](https://github.com/vmihailenco/msgpack) and native json. -- ✅ The default local cache implementation includes [TinyLFU](https://github.com/dgryski/go-tinylfu) and [FreeCache](https://github.com/coocood/freecache). -- ✅ The default distributed cache implementation is based on [go-redis/v8](https://github.com/redis/go-redis), and you can also customize your own implementation. -- ✅ You can customize the errNotFound error and use placeholders to prevent cache penetration by caching empty results. -- ✅ Supports asynchronous refreshing of distributed caches. -- ✅ Metrics collection: By default, it prints statistical metrics (QPM, Hit, Miss, Query, QueryFail) through logs. -- ✅ Automatic degradation of distributed cache query failures. -- ✅ The `MGet` interface supports the `Load` function. In a distributed caching scenario, the Pipeline mode is used to improve performance. - -# Installation -To start using the latest version of jetcache-go, you can import the library into your project: +Translations: [English](README_en.md) | [简体中文](README.md) + +# 介绍 +[jetcache-go](https://github.com/daoshenzzg/jetcache-go)是基于[go-redis/cache](https://github.com/go-redis/cache)拓展的通用缓存访问框架。 +实现了类似Java版[JetCache](https://github.com/alibaba/jetcache)的核心功能,包括: + +- ✅ 二级缓存自由组合:本地缓存、分布式缓存、本地缓存+分布式缓存 +- ✅ `Once`接口采用单飞(`singleflight`)模式,高并发且线程安全 +- ✅ 默认采用[sonic](https://github.com/bytedance/sonic)来编解码Value。可选[MsgPack](https://github.com/vmihailenco/msgpack)、原生`json` +- ✅ 本地缓存默认实现了[TinyLFU](https://github.com/dgryski/go-tinylfu)和[FreeCache](https://github.com/coocood/freecache) +- ✅ 分布式缓存默认实现了[go-redis/v8](https://github.com/redis/go-redis)的适配器,你也可以自定义实现 +- ✅ 可以自定义`errNotFound`,通过占位符替换,缓存空结果防止缓存穿透 +- ✅ 支持开启分布式缓存异步刷新 +- ✅ 指标采集,默认实现了通过日志打印各级缓存的统计指标(QPM、Hit、Miss、Query、QueryFail) +- ✅ 分布式缓存查询故障自动降级 +- ✅ `MGet`接口支持`Load`函数。带分布缓存场景,采用`Pipeline`模式实现 + +# 安装 +使用最新版本的jetcache-go,您可以在项目中导入该库: ```shell go get github.com/daoshenzzg/jetcache-go ``` -## Getting started +## 快速开始 -### Basic Usage +### ```go package cache_test @@ -163,7 +162,7 @@ func Example_mGetUsage() { } ``` -### Configure settings +### 配置选项 ```go // Options are used to store cache options. type Options struct { @@ -183,10 +182,9 @@ type Options struct { } ``` -### Cache metrics collection and statistics. -You can implement the `stats.Handler` interface and register it with the Cache component to customize metric collection, -for example, using [Prometheus](https://github.com/prometheus/client_golang) to collect metrics. We have provided a -default implementation that logs the statistical metrics, as shown below: +### 缓存指标收集和统计 +您可以实现`stats.Handler`接口并注册到Cache组件来自定义收集指标,例如使用[Prometheus](https://github.com/prometheus/client_golang) +采集指标。我们默认实现了通过日志打印统计指标,如下所示: ```shell 2023/09/11 16:42:30.695294 statslogger.go:178: [INFO] jetcache-go stats last 1m0s. cache | qpm| hit_ratio| hit| miss| query| query_fail @@ -197,7 +195,7 @@ bench_remote| 5153| 95.03%| 4897| 256| -| ------------+------------+------------+------------+------------+------------+------------ ``` -### Custom Logger +### 自定义日志 ```go import "github.com/daoshenzzg/jetcache-go/logger" @@ -205,7 +203,7 @@ import "github.com/daoshenzzg/jetcache-go/logger" logger.SetDefaultLogger(l logger.Logger) ``` -### Custom Encoding and Decoding +### 自定义编解码 ```go import ( "github.com/daoshenzzg/jetcache-go" @@ -216,36 +214,35 @@ import ( encoding.RegisterCodec(codec Codec) // Set your codec name -mycache := cache.New("any", +mycache := cache.New[string, any]("any", cache.WithRemote(...), cache.WithCodec(yourCodecName string)) ``` +### 使用场景说明 -### Usage Scenarios - -#### Automatic Cache Refresh -`jetcache-go` provides automatic cache refresh capability to prevent cache avalanche from hitting the database when the cache expires. Automatic refresh is suitable for scenarios with fewer keys, low real-time requirements, and high loading overhead. The above code specifies a refresh every minute, and stops refreshing after 1 hour if there is no access. If the cache is redis or the last level of a multi-level cache is redis, the cache loading behavior is globally unique, which means that only one server is refreshing at a time regardless of the number of servers, in order to reduce the load on the backend. +#### 自动刷新缓存 +`jetcache-go`提供了自动刷新缓存的能力,目的是为了防止缓存失效时造成的雪崩效应打爆数据库。对一些key比较少,实时性要求不高,加载开销非常大的缓存场景,适合使用自动刷新。上面的代码指定每分钟刷新一次,1小时如果没有访问就停止刷新。如果缓存是redis或者多级缓存最后一级是redis,缓存加载行为是全局唯一的,也就是说不管有多少台服务器,同时只有一个服务器在刷新,目的是为了降低后端的加载负担。 ```go mycache := cache.New[string, any](cache.WithName("any"), - // ... - // cache.WithRefreshDuration sets the asynchronous refresh interval - cache.WithRefreshDuration(time.Minute), - // cache.WithStopRefreshAfterLastAccess sets the time to cancel the refresh task after the cache key is not accessed + // ... + // cache.WithRefreshDuration 设置异步刷新时间间隔 + cache.WithRefreshDuration(time.Minute), + // cache.WithStopRefreshAfterLastAccess 设置缓存 key 没有访问后的刷新任务取消时间 cache.WithStopRefreshAfterLastAccess(time.Hour)) -// `Once` interface starts automatic refresh by `cache.Refresh(true)` +// `Once` 接口通过 `cache.Refresh(true)` 开启自动刷新 err := mycache.Once(ctx, key, cache.Value(obj), cache.Refresh(true), cache.Do(func(ctx context.Context) (any, error) { return mockDBGetObject(1) })) ``` -#### MGet Batch Query -`MGet` uses golang's Generics + Load function to provide a user-friendly way to batch query entities corresponding to IDs in multi-level cache. If the cache is redis or the last level of a multi-level cache is redis, Pipeline is used to implement read and write operations to improve performance. It is worth noting that for abnormal scenarios (IO exceptions, serialization exceptions, etc.), our design philosophy is to provide lossy services as much as possible to prevent penetration. +#### MGet批量查询 +`MGet` 通过 `golang`的泛型机制 + `Load` 函数,非常友好的多级缓存批量查询ID对应的实体。如果缓存是redis或者多级缓存最后一级是redis,查询时采用`Pipeline`实现读写操作,提升性能。需要说明是,针对异常场景(IO异常、序列化异常等),我们设计思路是尽可能提供有损服务,防止穿透。 ```go mycache := cache.New[int, *object](cache.WithName("any"), - // ... - cache.WithRemoteExpiry(time.Minute), - ) + // ... + cache.WithRemoteExpiry(time.Minute), + ) ctx := context.TODO() key := "mykey" @@ -256,9 +253,10 @@ ret := mycache.MGet(ctx, key, ids, func(ctx context.Context, ids []int) (map[int }) ``` -### Codec Selection -`jetcache-go` implements three serialization and deserialization (codec) methods by default: [sonic](https://github.com/bytedance/sonic)、[MsgPack](https://github.com/vmihailenco/msgpack), and native json. +#### Codec编解码选择 +`jetcache-go`默认实现了三种编解码方式,[sonic](https://github.com/bytedance/sonic)、[MsgPack](https://github.com/vmihailenco/msgpack)和原生`json`。 + +**选择指导:** -**Selection Guide:** -- **For high performance:** If the local cache hit rate is extremely high, but the deserialization operation of converting byte arrays to objects in the local cache consumes a lot of CPU, choose sonic. -- **For balance between performance and storage space:** Choose MsgPack. MsgPack uses MsgPack for serialization and deserialization, and snappy compression is used when the content exceeds 64 bytes. +- **追求编解码性能:** 例如本地缓存命中率极高,但本地缓存byte数组转对象的反序列化操作非常耗CPU,那么选择`sonic`。 +- **兼顾性能和极致的存储空间:** 选择`MsgPack`,MsgPack采用MsgPack编解码,内容>64个字节,会采用`snappy`压缩。 diff --git a/README_zh.md b/README_en.md similarity index 59% rename from README_zh.md rename to README_en.md index 3742d8c..32ea83b 100644 --- a/README_zh.md +++ b/README_en.md @@ -5,32 +5,33 @@ License

-Translations: [English](README.md) | [简体中文](README_zh.md) - -# 介绍 -[jetcache-go](https://github.com/daoshenzzg/jetcache-go)是基于[go-redis/cache](https://github.com/go-redis/cache)拓展的通用缓存访问框架。 -实现了类似Java版[JetCache](https://github.com/alibaba/jetcache)的核心功能,包括: - -- ✅ 二级缓存自由组合:本地缓存、分布式缓存、本地缓存+分布式缓存 -- ✅ `Once`接口采用单飞(`singleflight`)模式,高并发且线程安全 -- ✅ 默认采用[sonic](https://github.com/bytedance/sonic)来编解码Value。可选[MsgPack](https://github.com/vmihailenco/msgpack)、原生`json` -- ✅ 本地缓存默认实现了[TinyLFU](https://github.com/dgryski/go-tinylfu)和[FreeCache](https://github.com/coocood/freecache) -- ✅ 分布式缓存默认实现了[go-redis/v8](https://github.com/redis/go-redis)的适配器,你也可以自定义实现 -- ✅ 可以自定义`errNotFound`,通过占位符替换,缓存空结果防止缓存穿透 -- ✅ 支持开启分布式缓存异步刷新 -- ✅ 指标采集,默认实现了通过日志打印各级缓存的统计指标(QPM、Hit、Miss、Query、QueryFail) -- ✅ 分布式缓存查询故障自动降级 -- ✅ `MGet`接口支持`Load`函数。带分布缓存场景,采用`Pipeline`模式实现 - -# 安装 -使用最新版本的jetcache-go,您可以在项目中导入该库: +Translate to: [简体中文](README.md) + +# Introduction +[jetcache-go](https://github.com/daoshenzzg/jetcache-go) is a general-purpose cache access framework based on +[go-redis/cache](https://github.com/go-redis/cache). It implements the core features of the Java version of +[JetCache](https://github.com/alibaba/jetcache), including: + +- ✅ Flexible combination of two-level caching: You can use memory, Redis, or your own custom storage method. +- ✅ The `Once` interface adopts the `singleflight` pattern, which is highly concurrent and thread-safe. +- ✅ By default, [sonic](https://github.com/bytedance/sonic) is used for encoding and decoding values. Optional [MsgPack](https://github.com/vmihailenco/msgpack) and native json. +- ✅ The default local cache implementation includes [TinyLFU](https://github.com/dgryski/go-tinylfu) and [FreeCache](https://github.com/coocood/freecache). +- ✅ The default distributed cache implementation is based on [go-redis/v8](https://github.com/redis/go-redis), and you can also customize your own implementation. +- ✅ You can customize the errNotFound error and use placeholders to prevent cache penetration by caching empty results. +- ✅ Supports asynchronous refreshing of distributed caches. +- ✅ Metrics collection: By default, it prints statistical metrics (QPM, Hit, Miss, Query, QueryFail) through logs. +- ✅ Automatic degradation of distributed cache query failures. +- ✅ The `MGet` interface supports the `Load` function. In a distributed caching scenario, the Pipeline mode is used to improve performance. + +# Installation +To start using the latest version of jetcache-go, you can import the library into your project: ```shell go get github.com/daoshenzzg/jetcache-go ``` -## 快速开始 +## Getting started -### +### Basic Usage ```go package cache_test @@ -162,7 +163,7 @@ func Example_mGetUsage() { } ``` -### 配置选项 +### Configure settings ```go // Options are used to store cache options. type Options struct { @@ -172,7 +173,7 @@ type Options struct { codec string // Value encoding and decoding method. Default is "msgpack.Name". You can also customize it. errNotFound error // Error to return for cache miss. Used to prevent cache penetration. remoteExpiry time.Duration // Remote cache ttl, Default is 1 hour. - notFoundExpiry time.Duration // Duration for placeholder cache when there is a cache miss. Default is 1 minute. + notFoundExpiry time.Duration // Duration for placeholder cache when there is a cache miss. Default is 1 minute. offset time.Duration // Expiration time jitter factor for cache misses. refreshDuration time.Duration // Interval for asynchronous cache refresh. Default is 0 (refresh is disabled). stopRefreshAfterLastAccess time.Duration // Duration for cache to stop refreshing after no access. Default is refreshDuration + 1 second. @@ -182,9 +183,10 @@ type Options struct { } ``` -### 缓存指标收集和统计 -您可以实现`stats.Handler`接口并注册到Cache组件来自定义收集指标,例如使用[Prometheus](https://github.com/prometheus/client_golang) -采集指标。我们默认实现了通过日志打印统计指标,如下所示: +### Cache metrics collection and statistics. +You can implement the `stats.Handler` interface and register it with the Cache component to customize metric collection, +for example, using [Prometheus](https://github.com/prometheus/client_golang) to collect metrics. We have provided a +default implementation that logs the statistical metrics, as shown below: ```shell 2023/09/11 16:42:30.695294 statslogger.go:178: [INFO] jetcache-go stats last 1m0s. cache | qpm| hit_ratio| hit| miss| query| query_fail @@ -195,7 +197,7 @@ bench_remote| 5153| 95.03%| 4897| 256| -| ------------+------------+------------+------------+------------+------------+------------ ``` -### 自定义日志 +### Custom Logger ```go import "github.com/daoshenzzg/jetcache-go/logger" @@ -203,7 +205,7 @@ import "github.com/daoshenzzg/jetcache-go/logger" logger.SetDefaultLogger(l logger.Logger) ``` -### 自定义编解码 +### Custom Encoding and Decoding ```go import ( "github.com/daoshenzzg/jetcache-go" @@ -214,35 +216,36 @@ import ( encoding.RegisterCodec(codec Codec) // Set your codec name -mycache := cache.New[string, any]("any", +mycache := cache.New("any", cache.WithRemote(...), cache.WithCodec(yourCodecName string)) ``` -### 使用场景说明 -#### 自动刷新缓存 -`jetcache-go`提供了自动刷新缓存的能力,目的是为了防止缓存失效时造成的雪崩效应打爆数据库。对一些key比较少,实时性要求不高,加载开销非常大的缓存场景,适合使用自动刷新。上面的代码指定每分钟刷新一次,1小时如果没有访问就停止刷新。如果缓存是redis或者多级缓存最后一级是redis,缓存加载行为是全局唯一的,也就是说不管有多少台服务器,同时只有一个服务器在刷新,目的是为了降低后端的加载负担。 +### Usage Scenarios + +#### Automatic Cache Refresh +`jetcache-go` provides automatic cache refresh capability to prevent cache avalanche and database overload when cache misses occur. It is suitable for scenarios with a small number of keys, low real-time requirements, and high loading overhead. The code above specifies a refresh every minute, and stops refreshing after 1 hour without access. If the cache is Redis or the last level of a multi-level cache is Redis, the cache loading behavior is globally unique, which means that only one server is refreshing at a time regardless of the number of servers, to reduce the load on the backend. ```go mycache := cache.New[string, any](cache.WithName("any"), - // ... - // cache.WithRefreshDuration 设置异步刷新时间间隔 - cache.WithRefreshDuration(time.Minute), - // cache.WithStopRefreshAfterLastAccess 设置缓存 key 没有访问后的刷新任务取消时间 + // ... + // cache.WithRefreshDuration sets the asynchronous refresh interval + cache.WithRefreshDuration(time.Minute), + // cache.WithStopRefreshAfterLastAccess sets the time to cancel the refresh task after the cache key is not accessed cache.WithStopRefreshAfterLastAccess(time.Hour)) -// `Once` 接口通过 `cache.Refresh(true)` 开启自动刷新 +// `Once` interface starts automatic refresh by `cache.Refresh(true)` err := mycache.Once(ctx, key, cache.Value(obj), cache.Refresh(true), cache.Do(func(ctx context.Context) (any, error) { return mockDBGetObject(1) })) ``` -#### MGet批量查询 -`MGet` 通过 `golang`的泛型机制 + `Load` 函数,非常友好的多级缓存批量查询ID对应的实体。如果缓存是redis或者多级缓存最后一级是redis,查询时采用`Pipeline`实现读写操作,提升性能。需要说明是,针对异常场景(IO异常、序列化异常等),我们设计思路是尽可能提供有损服务,防止穿透。 +#### MGet Batch Query +`MGet` utilizes `golang generics` and the Load function to provide a user-friendly way to batch query entities corresponding to IDs in a multi-level cache. If the cache is Redis or the last level of a multi-level cache is Redis, `Pipeline` is used to implement read and write operations to improve performance. It's worth noting that for abnormal scenarios (IO exceptions, serialization exceptions, etc.), our design philosophy is to provide lossy services as much as possible to prevent cache penetration. ```go mycache := cache.New[int, *object](cache.WithName("any"), - // ... - cache.WithRemoteExpiry(time.Minute), - ) + // ... + cache.WithRemoteExpiry(time.Minute), + ) ctx := context.TODO() key := "mykey" @@ -253,10 +256,10 @@ ret := mycache.MGet(ctx, key, ids, func(ctx context.Context, ids []int) (map[int }) ``` -#### Codec编解码选择 -`jetcache-go`默认实现了三种编解码方式,[sonic](https://github.com/bytedance/sonic)、[MsgPack](https://github.com/vmihailenco/msgpack)和原生`json`。 +### Codec Selection +`jetcache-go` implements three serialization and deserialization (codec) methods by default: [sonic](https://github.com/bytedance/sonic)、[MsgPack](https://github.com/vmihailenco/msgpack), and native json. -**选择指导:** +**Selection Guide:** -- **追求编解码性能:** 例如本地缓存命中率极高,但本地缓存byte数组转对象的反序列化操作非常耗CPU,那么选择`sonic`。 -- **兼顾性能和极致的存储空间:** 选择`MsgPack`,MsgPack采用MsgPack编解码,内容>64个字节,会采用`snappy`压缩。 +- **For high-performance encoding and decoding:** If the local cache hit rate is extremely high, but the deserialization operation of converting byte arrays to objects in the local cache consumes a lot of CPU, choose `sonic`. +- **For balanced performance and extreme storage space:** Choose `MsgPack`, which uses MsgPack encoding and decoding. Content > 64 bytes will be compressed with `snappy`.