jcache

package module
v2.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2023 License: MIT Imports: 5 Imported by: 2

README

JCache 高可用的多级缓存集成方案库

说明

  • 该项目为golang库,golang项目引用该库即可使用。go get github.com/jerbe/jcache/v2
  • 此项目是模拟Redis开发的一个轻量的多级缓存集成方案。
  • 可同时运行多种驱动,互不干扰。
  • 支持Redis驱动,或自定义驱动,只要实现 driver.Cache 即可。
  • 内置内存缓存驱动。
  • 内存驱动支持分布式,基于ETCD的服务发现跟选举策略,会选出其中一台实例当做主节点,其余的为从节点。主节点的每次操作都会使用gRPC接口同步到其他从节点上;从节点的写操作会使用gRPC请求到主节点上再同步到其他从节点上。以尽量达到高可用和数据的一致性。

基本架构

现行阶段优先实现功能,未来可能会根据driver的权重指定优先获取顺序。 当前版本的优先顺序按实例化client时指定的driver顺序。

// 实例化一个以redis驱动为优先获取,内存驱动为后取的客户端
client := jcache.NewClient(driver.NewRedis(), driver.NewMemory())


// 实例化一个以内存驱动为优先获取,redis驱动为后取的客户端
client := jcache.NewClient(driver.NewMemory(), driver.NewRedis())
基本架构图

进度

  • Redis驱动支持
  • 本机内存驱动支持
    • 单机模式支持
    • 分布式模式支持
      • 从节点的增量同步
      • 节点的全量同步

案例

  go get github.com/jerbe/jcache/v2
import (
    "time"
	
    "github.com/jerbe/jcache/v2"
    "github.com/jerbe/jcache/v2/driver"
)

func main(){
	// 实例化一个以内存作为驱动的缓存客户端
    client := jcache.NewClient()

	// 实例化一个分布式的内存驱动缓存客户端
    cfg := driver.DistributeMemoryConfig{
		Port: 10080,         // 用于启动grpc服务端口,同机器请设置不同端口
        Prefix: "/prefix",   //根据自己的业务设置对应前缀
		// EtcdCfg 根据自己部署的ETCD服务设置对应配置
        EtcdCfg: clientv3.Config{
			Endpoints: []string{"127.0.0.1:2379"}
		}
    }
	client := driver.NewDistributeMemory(cfg)
	
	
	
    // 支持所有操作的客户端,包括 String,Hash,List 
	client := jcache.NewClient(driver.NewMemory())
	client.Set(context.Background(),"hello","world", time.Hour)
	client.Get(context.Background(),"hello")
	client.MGet(context.Background(),"hello","hi")
	...
		
	// 仅支持 String 操作的客户端 
	stringClient := jcache.NewStringClien(driver.NewMemory()); 
	stringClient.Set(context.Background(),"hello","world", time.Hour)
	stringClient.Get(context.Background(),"hello")
	stringClient.MGet(context.Background(),"hello","hi")
	...
	
	// 仅支持 Hash 操作的客户端
	hashClient := jcache.NewHashClient(driver.NewMemory()); 
	hashClient.HSet(context.Background(),"hello","world","boom")
	hashClient.HGet(context.Background(),"hello","world")
	...
	
	// 仅支持 List 操作的客户端 
	listClient := jcache.NewListClient(driver.NewMemory());
	listClient.Push(context.Background(),"hello","world")
	listClient.Pop(context.Background(),"hello")
	listClient.Shift(context.Background(),"hello")
}

Documentation

Index

Constants

View Source
const (
	// KeepTTL 保持原先的过期时间(TTL)
	KeepTTL = -1

	// DefaultEmptySetNXDuration 默认空对象设置过期时效
	DefaultEmptySetNXDuration = time.Second * 10

	// DefaultExpirationDuration 默认缓存过期时效
	DefaultExpirationDuration = time.Hour
)

Variables

View Source
var (
	ErrEmpty         = errors.New("empty")
	ErrNoCacheClient = errors.New("no cache client init")
	ErrNoRecord      = errors.New("no record")
)

Functions

func RandomExpirationDuration

func RandomExpirationDuration() time.Duration

RandomExpirationDuration 以 DefaultExpirationDuration 为基础,返回一个 DefaultExpirationDuration ± 30m 内的时间长度

Types

type Client

type Client struct {
	StringClient
	HashClient
	ListClient
	// contains filtered or unexported fields
}

func NewClient

func NewClient(drivers ...driver.Cache) *Client

func (*Client) Del

func (cli *Client) Del(ctx context.Context, keys ...string) error

Del 删除键

func (*Client) Exists

func (cli *Client) Exists(ctx context.Context, keys ...string) (int64, error)

Exists 判断某个Key是否存在

func (*Client) Expire

func (cli *Client) Expire(ctx context.Context, key string, expiration time.Duration) error

Expire 设置某个Key的TTL时长

func (*Client) ExpireAt

func (cli *Client) ExpireAt(ctx context.Context, key string, at time.Time) error

ExpireAt 设置某个key在指定时间内到期

type HashClient

type HashClient struct {
	// contains filtered or unexported fields
}

func NewHashClient

func NewHashClient(drivers ...driver.Hash) *HashClient

func (*HashClient) Del

func (cli *HashClient) Del(ctx context.Context, keys ...string) error

Del 删除键

func (*HashClient) Exists

func (cli *HashClient) Exists(ctx context.Context, keys ...string) (int64, error)

Exists 判断某个Key是否存在

func (*HashClient) Expire

func (cli *HashClient) Expire(ctx context.Context, key string, expiration time.Duration) error

Expire 设置某个Key的TTL时长

func (*HashClient) ExpireAt

func (cli *HashClient) ExpireAt(ctx context.Context, key string, at time.Time) error

ExpireAt 设置某个key在指定时间内到期

func (*HashClient) HDel

func (cli *HashClient) HDel(ctx context.Context, key string, fields ...string) error

HDel 删除hash数据

func (*HashClient) HExists

func (cli *HashClient) HExists(ctx context.Context, key, field string) (bool, error)

HExists 判断哈希表周公某个字段是否存在

func (*HashClient) HGet

func (cli *HashClient) HGet(ctx context.Context, key, field string) (string, error)

HGet 获取Hash表指定字段的值

func (*HashClient) HGetAll

func (cli *HashClient) HGetAll(ctx context.Context, key string) (map[string]string, error)

HGetAll 获取哈希表中所有的值,包括键/值

func (*HashClient) HGetAndScan

func (cli *HashClient) HGetAndScan(ctx context.Context, dst interface{}, key, field string) error

HGetAndScan 获取Hash表指定字段的值

func (*HashClient) HKeys

func (cli *HashClient) HKeys(ctx context.Context, key string) ([]string, error)

HKeys 获取Hash表的所有键

func (*HashClient) HKeysAndScan

func (cli *HashClient) HKeysAndScan(ctx context.Context, dst interface{}, key string) error

HKeysAndScan 获取Hash表的所有键并扫描到dst中

func (*HashClient) HLen

func (cli *HashClient) HLen(ctx context.Context, key string) (int64, error)

HLen 获取Hash表的所有键个数

func (*HashClient) HMGet

func (cli *HashClient) HMGet(ctx context.Context, key string, fields ...string) ([]interface{}, error)

HMGet 获取Hash表指定字段的值

func (*HashClient) HMGetAndScan

func (cli *HashClient) HMGetAndScan(ctx context.Context, dst interface{}, key string, fields ...string) error

HMGetAndScan 获取Hash表指定字段的值并扫描进入到dst中

func (*HashClient) HSet

func (cli *HashClient) HSet(ctx context.Context, key string, values ...interface{}) error

HSet 写入hash数据 接受以下格式的值: HSet("myhash", "key1", "value1", "key2", "value2")

HSet("myhash", []string{"key1", "value1", "key2", "value2"})

HSet("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"}) 使用“redis”标签播放结构。 type MyHash struct { Key1 string `redis:"key1"`; Key2 int `redis:"key2"` }

HSet("myhash", MyHash{"value1", "value2"}) 警告:redis-server >= 4.0 对于struct,可以是结构体指针类型,我们只解析标签为redis的字段。如果你不想读取该字段,可以使用 `redis:"-"` 标志来忽略它,或者不需要设置 redis 标签。对于结构体字段的类型,我们只支持简单的数据类型:string、int/uint(8,16,32,64)、float(32,64)、time.Time(to RFC3339Nano)、time.Duration(to Nanoseconds) ),如果是其他更复杂或者自定义的数据类型,请实现encoding.BinaryMarshaler接口。

func (*HashClient) HSetNX

func (cli *HashClient) HSetNX(ctx context.Context, key, field string, value interface{}) (bool, error)

HSetNX 哈希表设置某个字段的值,如果存在的话返回true

func (*HashClient) HVals

func (cli *HashClient) HVals(ctx context.Context, key string) ([]string, error)

HVals 获取Hash表的所有值

func (*HashClient) HValsAndScan

func (cli *HashClient) HValsAndScan(ctx context.Context, dst interface{}, key string) error

HValsAndScan 获取Hash表的所有值并扫如dst中

type ListClient

type ListClient struct {
	// contains filtered or unexported fields
}

func NewListClient

func NewListClient(drivers ...driver.List) *ListClient

func (*ListClient) Del

func (cli *ListClient) Del(ctx context.Context, keys ...string) error

Del 删除键

func (*ListClient) Exists

func (cli *ListClient) Exists(ctx context.Context, keys ...string) (int64, error)

Exists 判断某个Key是否存在

func (*ListClient) Expire

func (cli *ListClient) Expire(ctx context.Context, key string, expiration time.Duration) error

Expire 设置某个Key的TTL时长

func (*ListClient) ExpireAt

func (cli *ListClient) ExpireAt(ctx context.Context, key string, at time.Time) error

ExpireAt 设置某个key在指定时间内到期

func (*ListClient) LLen

func (cli *ListClient) LLen(ctx context.Context, key string) (int64, error)

LLen 返回列表长度

func (*ListClient) LPop

func (cli *ListClient) LPop(ctx context.Context, key string) (string, error)

LPop 移除并取出列表内的最后一个元素

func (*ListClient) LPopAndScan

func (cli *ListClient) LPopAndScan(ctx context.Context, dst interface{}, key string) error

LPopAndScan 通过扫描方式移除并取出列表内的最后一个元素

func (*ListClient) LPush

func (cli *ListClient) LPush(ctx context.Context, key string, data ...interface{}) error

LPush 推送数据

func (*ListClient) LRang

func (cli *ListClient) LRang(ctx context.Context, key string, start, stop int64) ([]string, error)

LRang 获取列表内的范围数据

func (*ListClient) LRangAndScan

func (cli *ListClient) LRangAndScan(ctx context.Context, dst interface{}, key string, start, stop int64) error

LRangAndScan 通过扫描方式获取列表内的范围内数据

func (*ListClient) LShift

func (cli *ListClient) LShift(ctx context.Context, key string) (string, error)

LShift 移除并取出列表内的第一个元素

func (*ListClient) LShiftAndScan

func (cli *ListClient) LShiftAndScan(ctx context.Context, dst interface{}, key string) error

LShiftAndScan 通过扫描方式移除并取出列表内的第一个元素

func (*ListClient) LTrim

func (cli *ListClient) LTrim(ctx context.Context, key string, start, stop int64) error

LTrim 获取列表内的范围数据

type StringClient

type StringClient struct {
	// contains filtered or unexported fields
}

func NewStringClient

func NewStringClient(drivers ...driver.String) *StringClient

func (*StringClient) CheckAndGet

func (cli *StringClient) CheckAndGet(ctx context.Context, key string) (string, error)

CheckAndGet 检测并获取数据

func (*StringClient) CheckAndScan

func (cli *StringClient) CheckAndScan(ctx context.Context, dst interface{}, key string) error

CheckAndScan 获取数据

func (*StringClient) Del

func (cli *StringClient) Del(ctx context.Context, keys ...string) error

Del 删除键

func (*StringClient) Exists

func (cli *StringClient) Exists(ctx context.Context, keys ...string) (int64, error)

Exists 判断某个Key是否存在

func (*StringClient) Expire

func (cli *StringClient) Expire(ctx context.Context, key string, expiration time.Duration) error

Expire 设置某个Key的TTL时长

func (*StringClient) ExpireAt

func (cli *StringClient) ExpireAt(ctx context.Context, key string, at time.Time) error

ExpireAt 设置某个key在指定时间内到期

func (*StringClient) Get

func (cli *StringClient) Get(ctx context.Context, key string) (string, error)

Get 获取数据

func (*StringClient) GetAndScan

func (cli *StringClient) GetAndScan(ctx context.Context, dst interface{}, key string) error

GetAndScan 获取并扫描

func (*StringClient) MGet

func (cli *StringClient) MGet(ctx context.Context, keys ...string) ([]interface{}, error)

MGet 获取多个Keys的值

func (*StringClient) MGetAndScan

func (cli *StringClient) MGetAndScan(ctx context.Context, dst interface{}, keys ...string) error

MGetAndScan 获取多个Keys的值并扫描进dst中

func (*StringClient) Set

func (cli *StringClient) Set(ctx context.Context, key string, data interface{}, expiration time.Duration) error

Set 设置数据

func (*StringClient) SetNX

func (cli *StringClient) SetNX(ctx context.Context, key string, data interface{}, expiration time.Duration) error

SetNX 设置数据,如果key不存在的话

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL