eredis

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2022 License: MIT Imports: 30 Imported by: 1

README

eredis 组件使用指南

goproxy.cn Release Example Doc

1 简介

go-redis 进行了轻量封装,并提供了以下功能:

  • 规范了标准配置格式,提供了统一的 Load().Build() 方法。
  • 支持自定义拦截器
  • 提供了默认的 Debug 拦截器,开启 Debug 后可输出 Request、Response 至终端。
  • 提供了默认的 Metric 拦截器,开启后可采集 Prometheus 指标数据
  • 提供了默认的 OpenTelemetry 拦截器,开启后可采集 Tracing Span 数据
  • 提供了redis的分布式锁
  • 提供了redis的分布式锁的定时任务

2 说明

  • ego版本:ego@v1.0.1
  • eredis版本: eredis@1.0.1

3 使用方式

go get github.com/eezz10001/eredis

4 Redis配置

type config struct {
    Addrs                      []string      // Addrs 实例配置地址
    Addr                       string        // Addr stubConfig 实例配置地址
    Mode                       string        // Mode Redis模式 cluster|stub|sentinel
    MasterName                 string        // MasterName 哨兵主节点名称,sentinel模式下需要配置此项
    Password                   string        // Password 密码
    DB                         int           // DB,默认为0, 一般应用不推荐使用DB分片
    PoolSize                   int           // PoolSize 集群内每个节点的最大连接池限制 默认每个CPU10个连接
    MaxRetries                 int           // MaxRetries 网络相关的错误最大重试次数 默认8次
    MinIdleConns               int           // MinIdleConns 最小空闲连接数
    DialTimeout                time.Duration // DialTimeout 拨超时时间
    ReadTimeout                time.Duration // ReadTimeout 读超时 默认3s
    WriteTimeout               time.Duration // WriteTimeout 读超时 默认3s
    IdleTimeout                time.Duration // IdleTimeout 连接最大空闲时间,默认60s, 超过该时间,连接会被主动关闭
    Debug                      bool          // Debug开关, 是否开启调试,默认不开启,开启后并加上export EGO_DEBUG=true,可以看到每次请求,配置名、地址、耗时、请求数据、响应数据
    ReadOnly                   bool          // ReadOnly 集群模式 在从属节点上启用读模式
    SlowLogThreshold           time.Duration // 慢日志门限值,超过该门限值的请求,将被记录到慢日志中
    OnFail                     string        // OnFail panic|error
    EnableMetricInterceptor    bool          // 是否开启监控,默认开启
    EnableTraceInterceptor     bool          // 是否开启链路,默认开启
    EnableAccessInterceptor    bool          // 是否开启,记录请求数据
    EnableAccessInterceptorReq bool          // 是否开启记录请求参数
    EnableAccessInterceptorRes bool          // 是否开启记录响应参数
}

5 普通Redis查询

5.1 用户配置
# 常用的stub单实例配置示例
[redis.stub]
   debug = true # ego增加redis debug,打开后可以看到,配置名、地址、耗时、请求数据、响应数据
   mode = "stub" # 默认为stub单实例模式,可选"stub|cluster|sentinel"
   addr = "127.0.0.1:6379"

# cluster集群模式配置示例
[redis.cluster]
   debug = true
   mode = "cluster" # 设置为"cluster"模式,该模式下必须配置"addrs" 
   addrs = ["127.0.0.1:6379", "127.0.0.1:6380", "127.0.0.1:6381"]  # cluster模式下必须配置"addrs"

# sentinel哨兵模式配置示例
[redis.sentinel]
   debug = true
   mode = "sentinel" # 设置为"sentinel"模式,该模式下必须配置"addrs"和"masterName"
   addrs = ["127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381"] # sentinel模式下必须配置"addrs"
   masterName = "my-sentinel-master-name" # sentinel 模式下必须配置"masterName"
5.2 优雅的Debug

通过开启 debug 配置和命令行的 export EGO_DEBUG=true,我们就可以在测试环境里看到请求里的配置名、地址、耗时、请求数据、响应数据

image

5.3 用户代码

配置创建一个 redis 的配置项,其中内容按照上文配置进行填写。以上这个示例里这个配置key是redis.test

代码中创建一个 redis 实例 eredis.Load("key").Build(),代码中的 key 和配置中的 key 要保持一致。创建完 redis 实例后,就可以直接使用他对 redis 进行 crud

package main
     
import (
    "fmt"

    "github.com/eezz10001/ego"
    "github.com/eezz10001/eredis"
    "github.com/eezz10001/ego/core/elog"
)

// export EGO_DEBUG=true && go run main.go --config=config.toml
func main() {
    err := ego.New().Invoker(
        invokerRedis,
        testRedis,
    ).Run()
    if err != nil {
        elog.Panic("startup", elog.FieldErr(err))
    }
}

var eredisStubClient *eredis.Component
var eredisClusterClient *eredis.Component
var eredisSentinelClient *eredis.Component

func invokerRedis() error {
    // 读取"redis.stub"配置,并初始化redis stub component实例
    eredisStubClient = eredis.Load("redis.stub").Build()
    // 读取"redis.cluster"配置,并初始化redis cluster component实例
    eredisClusterClient = eredis.Load("redis.cluster").Build()
    // 读取"redis.sentinel"配置,并初始化redis sentinel component实例
    eredisSentinelClient = eredis.Load("redis.sentinel").Build()
    return nil
}

func testRedis() error {
    // 使用redis stub component进行set、get操作
    err := eredisStubClient.Set(context.Background(), "hello", "world", 0)
    if err != nil {
        log.Println(err)
    }
    str, err := eredisStubClient.Get(context.Background(), "hello")
    if err != nil {
        log.Println(err)
    }
    fmt.Println(str)

    // 使用redis cluster component进行set、get操作
    err := eredisClusterClient.Set(context.Background(), "hello", "world", 0)
    if err != nil {
        log.Println(err)
    }
    str, err := eredisClusterClient.Get(context.Background(), "hello")
    if err != nil {
        log.Println(err)
    }
    fmt.Println(str)
    return nil

    // 使用redis sentinel component进行set、get操作
    err := eredisSentinelClient.Set(context.Background(), "hello", "world", 0)
    if err != nil {
        log.Println(err)
    }
    str, err := eredisSentinelClient.Get(context.Background(), "hello")
    if err != nil {
        log.Println(err)
    }
    fmt.Println(str)
    return nil
}

6 Redis的日志

任何redis的请求都会记录redis的错误access日志,如果需要对redis的日志做定制化处理,可参考以下使用方式。

6.1 开启redis的access日志

线上在并发量不高,或者核心业务下可以开启全量access日志,这样方便我们排查问题

6.2 开启日志方式

在原有的redis配置中,加入以下三行配置,redis的日志里就会记录响应的数据

[redis.test]
enableAccessInterceptor=true       # 是否开启,记录请求数据
enableAccessInterceptorReq=true    # 是否开启记录请求参数
enableAccessInterceptorRes=true    # 是否开启记录响应参数

img.png

6.3 开启自定义日志字段的数据

在使用了ego的自定义字段功能export EGO_LOG_EXTRA_KEYS=X-Ego-Uid,将对应的数据塞入到context中,那么redis的access日志就可以记录对应字段信息。 参考 详细文档

func testRedis() error {
    ctx := context.Background()
    ctx = context.WithValue(ctx, "X-Ego-Uid", 9527)
    err := eredisClient.Set(ctx, "hello", "world", 0)
    fmt.Println("set hello", err)
    
    str, err := eredisClient.Get(ctx, "hello")
    fmt.Println("get hello", str, err)
    
    str, err = eredisClient.Get(ctx, "lee")
    fmt.Println("Get lee", errors.Is(err, eredis.Nil), "err="+err.Error())
    
    return nil
}

7 Redis的定时任务锁

// export EGO_DEBUG=true && go run main.go --config=config.toml
func main() {
	err := ego.New().Invoker(initRedis).Cron(cronJob()).Run()
	if err != nil {
		elog.Panic("startup", elog.FieldErr(err))
	}
}

func initRedis() error {
	redis = eredis.Load("redis.test").Build()
	return nil
}

func cronJob() ecron.Ecron {
	locker := ecronlock.DefaultContainer().Build(ecronlock.WithClient(redis))
	cron := ecron.Load("cron.default").Build(
		ecron.WithLock(locker.NewLock("ego-component:cronjob:syncXxx")),
		ecron.WithJob(helloWorld),
	)
	return cron
}

func helloWorld(ctx context.Context) error {
	log.Println("cron job running")
	return nil
}

8 Redis监控数据

img.png img.png img.png

Documentation

Index

Constants

View Source
const (
	// ClusterMode using clusterClient
	ClusterMode string = "cluster"
	// StubMode using stubClient
	StubMode string = "stub"
	// SentinelMode using Failover sentinel client
	SentinelMode string = "sentinel"
)
View Source
const (
	// ErrInvalidParams  is returned when parameters is invalid.
	ErrInvalidParams = Err("invalid params")

	// ErrNotObtained is returned when a Lock cannot be obtained.
	ErrNotObtained = Err("redislock: not obtained")

	// ErrLockNotHeld is returned when trying to release an inactive Lock.
	ErrLockNotHeld = Err("redislock: lock not held")

	//Nil reply returned by Redis when key does not exist.
	Nil = redis.Nil
)
View Source
const PackageName = "component.eredis"

Variables

This section is empty.

Functions

func DefaultConfig

func DefaultConfig() *config

DefaultConfig default config ...

Types

type Component

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

Component client (cmdable and config)

func (*Component) Client

func (r *Component) Client() redis.Cmdable

Client returns a universal redis client(ClusterClient, StubClient or SentinelClient), it depends on you config.

func (*Component) Close

func (r *Component) Close() (err error)

Close closes the cluster client, releasing any open resources.

It is rare to Close a ClusterClient, as the ClusterClient is meant to be long-lived and shared between many goroutines.

func (*Component) Cluster

func (r *Component) Cluster() *redis.ClusterClient

Cluster try to get a redis.ClusterClient

func (*Component) Decr

func (r *Component) Decr(ctx context.Context, key string) (int64, error)

Decr redis自减

func (*Component) DecrBy

func (r *Component) DecrBy(ctx context.Context, key string, decrement int64) (int64, error)

Decr redis自减特定的值

func (*Component) Del

func (r *Component) Del(ctx context.Context, key string) (int64, error)

Del redis删除

func (*Component) Exists

func (r *Component) Exists(ctx context.Context, key string) (bool, error)

Exists 键是否存在

func (*Component) Expire

func (r *Component) Expire(ctx context.Context, key string, expiration time.Duration) (bool, error)

Expire 设置过期时间

func (*Component) GeoAdd

func (r *Component) GeoAdd(ctx context.Context, key string, location *redis.GeoLocation) (int64, error)

GeoAdd 写入地理位置

func (*Component) GeoRadius

func (r *Component) GeoRadius(ctx context.Context, key string, longitude, latitude float64, query *redis.GeoRadiusQuery) ([]redis.GeoLocation, error)

GeoRadius 根据经纬度查询列表

func (*Component) Get

func (r *Component) Get(ctx context.Context, key string) (string, error)

Get

func (*Component) GetBytes

func (r *Component) GetBytes(ctx context.Context, key string) ([]byte, error)

GetBytes

func (*Component) GetEx

func (r *Component) GetEx(ctx context.Context, key string, expire time.Duration) (string, error)

GETEX

func (*Component) HDel

func (r *Component) HDel(ctx context.Context, key string, field ...string) error

HDel ...

func (*Component) HGet

func (r *Component) HGet(ctx context.Context, key string, fields string) (string, error)

HGet 从redis获取hash单个值

func (*Component) HGetAll

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

HGetAll 从redis获取hash的所有键值对

func (*Component) HIncrBy

func (r *Component) HIncrBy(ctx context.Context, key string, field string, incr int) (int64, error)

HIncrBy 哈希field自增

func (*Component) HKeys

func (r *Component) HKeys(ctx context.Context, key string) ([]string, error)

HKeys 获取hash的所有域

func (*Component) HLen

func (r *Component) HLen(ctx context.Context, key string) (int64, error)

HLen 获取hash的长度

func (*Component) HMGet

func (r *Component) HMGet(ctx context.Context, key string, fileds []string) ([]interface{}, error)

func (*Component) HMGetMap

func (r *Component) HMGetMap(ctx context.Context, key string, fields []string) (map[string]string, error)

HMGetMap 批量获取hash值,返回map

func (*Component) HMGetString

func (r *Component) HMGetString(ctx context.Context, key string, fileds []string) ([]string, error)

HMGet 批量获取hash值

func (*Component) HMSet

func (r *Component) HMSet(ctx context.Context, key string, hash map[string]interface{}, expire time.Duration) error

HMSet 设置redis的hash

func (*Component) HSet

func (r *Component) HSet(ctx context.Context, key string, field string, value interface{}) error

HSet hset

func (*Component) Incr

func (r *Component) Incr(ctx context.Context, key string) (int64, error)

Incr redis自增

func (*Component) IncrBy

func (r *Component) IncrBy(ctx context.Context, key string, increment int64) (int64, error)

IncrBy 将 key 所储存的值加上增量 increment 。

func (*Component) LIndex

func (r *Component) LIndex(ctx context.Context, key string, idx int64) (string, error)

LIndex ...

func (*Component) LLen

func (r *Component) LLen(ctx context.Context, key string) (int64, error)

LLen ...

func (*Component) LPush

func (r *Component) LPush(ctx context.Context, key string, values ...interface{}) (int64, error)

LPush 将一个或多个值 value 插入到列表 key 的表头

func (*Component) LRange

func (r *Component) LRange(ctx context.Context, key string, start, stop int64) ([]string, error)

LRange 获取列表指定范围内的元素

func (*Component) LRem

func (r *Component) LRem(ctx context.Context, key string, count int64, value interface{}) (int64, error)

LRem ...

func (*Component) LTrim

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

LTrim ...

func (*Component) LockClient

func (r *Component) LockClient() *lockClient

LockClient gets default distributed Lock client

func (*Component) MGet

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

MGets ...

func (*Component) MGetString

func (r *Component) MGetString(ctx context.Context, keys ...string) ([]string, error)

MGet ...

func (*Component) Ping

func (r *Component) Ping(ctx context.Context) (string, error)

Ping

func (*Component) RPop

func (r *Component) RPop(ctx context.Context, key string) (string, error)

RPop 移除并返回列表 key 的尾元素。

func (*Component) RPush

func (r *Component) RPush(ctx context.Context, key string, values ...interface{}) (int64, error)

RPush 将一个或多个值 value 插入到列表 key 的表尾(最右边)。

func (*Component) SAdd

func (r *Component) SAdd(ctx context.Context, key string, member ...interface{}) (int64, error)

SAdd 向set中添加成员

func (*Component) SIsMember

func (r *Component) SIsMember(ctx context.Context, key string, member interface{}) (bool, error)

SIsMember ...

func (*Component) SMembers

func (r *Component) SMembers(ctx context.Context, key string) ([]string, error)

SMembers 返回set的全部成员

func (*Component) SRem

func (r *Component) SRem(ctx context.Context, key string, member interface{}) (int64, error)

SRem ...

func (*Component) Sentinel

func (r *Component) Sentinel() *redis.Client

Sentinel try to get a redis Failover Sentinel client

func (*Component) Set

func (r *Component) Set(ctx context.Context, key string, value interface{}, expire time.Duration) error

Set 设置redis的string

func (*Component) SetEX

func (r *Component) SetEX(ctx context.Context, key string, value interface{}, expire time.Duration) error

SetEX ...

func (*Component) SetNX

func (r *Component) SetNX(ctx context.Context, key string, value interface{}, expire time.Duration) error

SetNX ...

func (*Component) SetNx

func (r *Component) SetNx(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)

SetNx 设置redis的string 如果键已存在

func (*Component) Stub

func (r *Component) Stub() *redis.Client

Stub try to get a redis.client

func (*Component) TTL

func (r *Component) TTL(ctx context.Context, key string) (time.Duration, error)

TTL 查询过期时间

func (*Component) Type

func (r *Component) Type(ctx context.Context, key string) (string, error)

Type ...

func (*Component) ZAdd

func (r *Component) ZAdd(ctx context.Context, key string, members ...*redis.Z) (int64, error)

ZAdd 将一个或多个 member 元素及其 score 值加入到有序集 key 当中

func (*Component) ZCard

func (r *Component) ZCard(ctx context.Context, key string) (int64, error)

ZCard 获取有序集合的基数

func (*Component) ZCount

func (r *Component) ZCount(ctx context.Context, key string, min, max string) (int64, error)

ZCount 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。

func (*Component) ZRange

func (r *Component) ZRange(ctx context.Context, key string, start, stop int64) ([]string, error)

ZRange ...

func (*Component) ZRangeByScore

func (r *Component) ZRangeByScore(ctx context.Context, key string, opt *redis.ZRangeBy) ([]string, error)

ZRangeByScore ...

func (*Component) ZRangeByScoreWithScores

func (r *Component) ZRangeByScoreWithScores(ctx context.Context, key string, opt *redis.ZRangeBy) ([]redis.Z, error)

ZRangeByScoreWithScores ...

func (*Component) ZRangeWithScores

func (r *Component) ZRangeWithScores(ctx context.Context, key string, start, stop int64) ([]redis.Z, error)

ZRangeWithScores ...

func (*Component) ZRem

func (r *Component) ZRem(ctx context.Context, key string, members ...interface{}) (int64, error)

ZRem 从zset中移除变量

func (*Component) ZRemRangeByRank

func (r *Component) ZRemRangeByRank(ctx context.Context, key string, start, stop int64) (int64, error)

ZRemRangeByRank 移除有序集合中给定的排名区间的所有成员

func (*Component) ZRevRange

func (r *Component) ZRevRange(ctx context.Context, key string, start, stop int64) ([]string, error)

ZRevRange 倒序获取有序集合的部分数据

func (*Component) ZRevRangeByScore

func (r *Component) ZRevRangeByScore(ctx context.Context, key string, opt *redis.ZRangeBy) ([]string, error)

ZRevRangeByScore ...

func (*Component) ZRevRangeByScoreWithScores

func (r *Component) ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *redis.ZRangeBy) ([]redis.Z, error)

ZRevRangeByScoreWithScores ...

func (*Component) ZRevRangeWithScores

func (r *Component) ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) ([]redis.Z, error)

ZRevRangeWithScores ...

func (*Component) ZRevRank

func (r *Component) ZRevRank(ctx context.Context, key string, member string) (int64, error)

ZRevRank ...

func (*Component) ZScore

func (r *Component) ZScore(ctx context.Context, key string, member string) (float64, error)

ZScore 获取有序集合成员 member 的 score 值

type Container

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

func DefaultContainer

func DefaultContainer() *Container

DefaultContainer 定义了默认Container配置

func Load

func Load(key string) *Container

Load 载入配置,初始化Container

func (*Container) Build

func (c *Container) Build(options ...Option) *Component

Build 构建Component

func (*Container) Printf

func (c *Container) Printf(ctx context.Context, format string, v ...interface{})

type Err

type Err string

func (Err) Error

func (e Err) Error() string

type Lock

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

Lock represents an obtained, distributed Lock.

func (*Lock) Key

func (l *Lock) Key() string

Key returns the redis key used by the Lock.

func (*Lock) Metadata

func (l *Lock) Metadata() string

Metadata returns the metadata of the Lock.

func (*Lock) Refresh

func (l *Lock) Refresh(ctx context.Context, ttl time.Duration, opts ...LockOption) error

Refresh extends the Lock with a new TTL. May return ErrNotObtained if refresh is unsuccessful.

func (*Lock) Release

func (l *Lock) Release(ctx context.Context) error

Release manually releases the Lock. May return ErrLockNotHeld.

func (*Lock) TTL

func (l *Lock) TTL(ctx context.Context) (time.Duration, error)

TTL returns the remaining time-to-live. Returns 0 if the Lock has expired.

func (*Lock) Token

func (l *Lock) Token() string

Token returns the token value set by the Lock.

type LockOption

type LockOption func(c *lockOption)

func WithLockOptionMetadata

func WithLockOptionMetadata(md string) LockOption

func WithLockOptionRetryStrategy

func WithLockOptionRetryStrategy(retryStrategy RetryStrategy) LockOption

type Option

type Option func(c *Container)

func WithAddr

func WithAddr(addr string) Option

WithAddr set address

func WithAddrs

func WithAddrs(addrs []string) Option

WithAddrs set addresses

func WithCluster

func WithCluster() Option

WithStub set mode to "cluster"

func WithPassword

func WithPassword(password string) Option

WithPassword set password

func WithSentinel

func WithSentinel() Option

WithStub set mode to "sentinel"

func WithStub

func WithStub() Option

WithStub set mode to "stub"

type RetryStrategy

type RetryStrategy interface {
	// NextBackoff returns the next backoff duration.
	NextBackoff() time.Duration
}

RetryStrategy allows to customise the Lock retry strategy.

func ExponentialBackoffRetry

func ExponentialBackoffRetry(min, max time.Duration) RetryStrategy

ExponentialBackoffRetry strategy is an optimization strategy with a retry time of 2**n milliseconds (n means number of times). You can set a minimum and maximum value, the recommended minimum value is not less than 16ms.

func LimitRetry

func LimitRetry(s RetryStrategy, max int) RetryStrategy

LimitRetry limits the number of retries to max attempts.

func LinearBackoffRetry

func LinearBackoffRetry(backoff time.Duration) RetryStrategy

LinearBackoffRetry allows retries regularly with customized intervals

func NoRetry

func NoRetry() RetryStrategy

--------------------------------No Retry----------------------------------- NoRetry acquire the Lock only once.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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