redisKit

package
v3.0.924 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2024 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package redisKit

Redis HyperLogLog

https://www.runoob.com/redis/redis-hyperloglog.html

Redis 如何使用 HyperLogLog

https://blog.csdn.net/SunnyYoona/article/details/124764009

Index

Constants

This section is empty.

Variables

View Source
var (
	NotSetupError = errorKit.Newf("haven’t been set up correctly")
)

Functions

func IsConsumerGroupNameAlreadyExistError

func IsConsumerGroupNameAlreadyExistError(err error) bool

IsConsumerGroupNameAlreadyExistError 适用场景: 创建Consumer group(XGroupCreate || XGroupCreateMkStream)时,返回error.

TODO: 涉及 github.com/redis/go-redis/v9 源码, 后续看有没有好的解决方法.

@return true: 错误是由 "指定group已经存在(无需重复创建)" 导致的.

func IsNoStreamOrNoGroupError added in v3.0.106

func IsNoStreamOrNoGroupError(err error) bool

IsNoStreamOrNoGroupError 适用场景: Consumer读取消息时,返回error.

TODO: 涉及 github.com/redis/go-redis/v9 源码, 后续看有没有好的解决方法.

@return true: 错误是由 "指定stream不存在" 或 "指定stream存在,但指定group不存在" 导致的.

func MustSetUp

func MustSetUp(config *Config)

MustSetUp

PS: 在使用go-redis连接Redis Cluster集群时,尽管通常仅需传入主节点的地址即可,但如果同时传入了所有主节点和从节点的地址,理论上不会造成任何问题。 客户端在连接时会首先尝试连接提供的地址列表中的任何一个节点,无论它是主节点还是从节点。一旦连接成功,客户端会通过与该节点交互获取整个集群的拓扑信息,包括所有主节点和从节点的详细情况。

func SetUp

func SetUp(config *Config) (err error)

Types

type Client

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

func GetClient

func GetClient() (*Client, error)

GetClient

前提: 成功调用 SetUp() || MustSetUp().

func NewClient

func NewClient(config *Config) (client *Client, err error)

NewClient 新建一个go-redis客户端(内置连接池,调用方无需额外考虑并发问题).

!!!: 每一个命令都会重新取得一个连接,执行后立即回收,而且回收到资源池的顺序类似于堆. https://www.cnblogs.com/yangqi7/p/13289232.html

连接哨兵集群的demo: https://blog.csdn.net/supery071/article/details/109491404

@return (1) 两个返回值,必定有一个为nil,另一个非nil;

(2) Cluster模式下,第1个返回值的类型: *redis.ClusterClient.

func (*Client) Append

func (client *Client) Append(ctx context.Context, key, value string) (int64, error)

Append

命令说明: Redis Append 命令用于为指定的 key 追加值。 (1) 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。 (2) 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。

@return 追加后值的长度

func (*Client) Close

func (client *Client) Close() error

func (*Client) DBSize

func (client *Client) DBSize(ctx context.Context) (int64, error)

DBSize

命令说明: 返回当前数据库的 key 的数量. 命令语法: DBSIZE 命令返回值: 当前数据库的 key 的数量.

func (*Client) Decr

func (client *Client) Decr(ctx context.Context, key string) (int64, error)

Decr

命令说明: Redis Decr 命令将 key 中储存的数字值减一。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。

func (*Client) DecrBy

func (client *Client) DecrBy(ctx context.Context, key string, decrement int64) (int64, error)

DecrBy

命令说明: Redis Decrby 命令将 key 所储存的值减去指定的减量值。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。

e.g. key存在&&value为"-9223372036854775808"(将返回error)

(context.Background(), "a") => 0 ERR increment or decrement would overflow

func (*Client) Del

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

Del

命令说明: 删除已存在的键。不存在的 key 会被忽略。 命令语法: DEL KEY_NAME 命令返回值: 被删除 key 的数量。

func (*Client) Eval

func (client *Client) Eval(ctx context.Context, script string, keys []string, args ...interface{}) (interface{}, error)

Eval

!!!: cluster集群模式下,使用lua脚本要注意(特别是涉及多个Redis key的情况),更多详见".info".

命令说明: 使用 Lua 解释器执行脚本 命令语法: EVAL script numkeys key [key ...] arg [arg ...]

func (*Client) EvalSha

func (client *Client) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) (interface{}, error)

EvalSha

!!!: cluster集群模式下,使用lua脚本要注意(特别是涉及多个Redis key的情况),更多详见".info". PS: 一般与 ScriptLoad 搭配使用.

命令说明: 根据给定的 sha1 校验码,执行缓存在服务器中的脚本 命令语法: EVALSHA sha1 numkeys key [key ...] arg [arg ...]

func (*Client) Exists

func (client *Client) Exists(ctx context.Context, keys ...string) (bool, error)

Exists

命令说明: 检查给定 key 是否存在. 命令语法: EXISTS KEY_NAME 命令返回值: 若 key 存在返回 1 ,否则返回 0.

func (*Client) Expire

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

Expire

命令说明: 设置 key 的过期时间,key 过期后将不再可用。单位以秒计。 命令语法: Expire KEY_NAME TIME_IN_SECONDS 命令返回值: 设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。

e.g. key不存在 => (false, nil) key存在 => (true, nil)

func (*Client) ExpireAt

func (client *Client) ExpireAt(ctx context.Context, key string, tm time.Time) (bool, error)

ExpireAt

命令说明: 以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间。key 过期后将不再可用。 命令语法: Expireat KEY_NAME TIME_IN_UNIX_TIMESTAMP 命令返回值: 设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。

func (*Client) FlushAll

func (client *Client) FlushAll(ctx context.Context) (string, error)

FlushAll

命令说明: 清空整个 Redis 服务器的数据(删除所有数据库的所有 key ). 命令语法: FLUSHALL 命令返回值: 总是返回 OK .

func (*Client) FlushAllAsync

func (client *Client) FlushAllAsync(ctx context.Context) (string, error)

FlushAllAsync 异步地.

func (*Client) FlushDB

func (client *Client) FlushDB(ctx context.Context) (string, error)

FlushDB

命令说明: 清空当前数据库中的所有 key. 命令语法: FLUSHDB 命令返回值: 总是返回 OK .

func (*Client) FlushDBAsync

func (client *Client) FlushDBAsync(ctx context.Context) (string, error)

FlushDBAsync 异步地.

func (*Client) GeoAdd

func (client *Client) GeoAdd(ctx context.Context, key string, geoLocation ...*redis.GeoLocation) (int64, error)

GeoAdd

命令说明: 存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中. 命令语法: GEOADD key longitude latitude member [longitude latitude member ...]

func (*Client) GeoDist

func (client *Client) GeoDist(ctx context.Context, key string, member1, member2, unit string) (float64, error)

GeoDist

命令说明: 用于返回两个给定位置之间的距离. 命令语法: GEODIST key member1 member2 [m|km|ft|mi]

func (*Client) GeoPos

func (client *Client) GeoPos(ctx context.Context, key string, members ...string) ([]*redis.GeoPos, error)

GeoPos

命令说明: 从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。 命令语法: GEOPOS key member [member ...]

func (*Client) Get

func (client *Client) Get(ctx context.Context, key string) (string, error)

Get

命令说明: 获取指定 key 的值。(如果 key 不存在,返回 nil;如果key 储存的值不是字符串类型,返回一个错误) 命令语法: GET KEY_NAME 命令返回值: 返回 key 的值,如果 key 不存在时,返回 nil。 如果 key 不是字符串类型,那么返回一个错误。

e.g. 当前db中不存在 传参key => ("", redis.Nil)

func (*Client) GetKeyWithPrefix

func (client *Client) GetKeyWithPrefix(key string) string

func (*Client) GetMode

func (client *Client) GetMode() Mode

func (*Client) GetPrefix

func (client *Client) GetPrefix() string

func (*Client) GetUniversalClient

func (client *Client) GetUniversalClient() redis.UniversalClient

GetUniversalClient 返回go-redis客户端

func (*Client) GetWithoutRedisNil

func (client *Client) GetWithoutRedisNil(ctx context.Context, key string) (string, error)

GetWithoutRedisNil 对 Get 进行封装(特殊处理): 当前db中不存在传参key时,返回 ("", nil).

PS: (1) 如果当前db中不存在传参key,将返回 ("", nil) (2) 如果不关心key是否存在,只关心值,可以调用此方法 (3) 如果对应value的类型不为string,会返回error: WRONGTYPE Operation against a key holding the wrong kind of value

func (*Client) HDel

func (client *Client) HDel(ctx context.Context, key string, fields ...string) (int64, error)

HDel

命令说明: 删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。 命令语法: HDEL KEY_NAME FIELD1.. FIELDN 命令返回值: 被成功删除字段的数量,不包括被忽略的字段。

func (*Client) HExists

func (client *Client) HExists(ctx context.Context, key, field string) (bool, error)

HExists

命令说明: 用于查看哈希表的指定字段是否存在 命令语法: HEXISTS KEY_NAME FIELD_NAME 命令返回值: 如果哈希表含有给定字段(field),返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。

PS: key和field,只要有一个不存在,返回值必定为(false, nil).

@param key 可以为"" @param field 可以为""

func (*Client) HGet

func (client *Client) HGet(ctx context.Context, key, field string) (string, error)

HGet

命令说明: 返回哈希表中指定字段的值。 命令语法: HGET KEY_NAME FIELD_NAME 命令返回值: 返回给定字段的值。如果给定的字段或 key 不存在时,返回 nil 。

func (*Client) HGetAll

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

HGetAll

命令说明:

返回哈希表中,所有的字段和值。
在返回值里,紧跟每个字段名(field name)之后是字段的值(value),所以返回值的长度是哈希表大小的两倍。

命令语法: HGETALL KEY_NAME 命令返回值: 以列表形式返回哈希表的字段及字段值。 若 key 不存在,返回空列表。

func (*Client) HKeys

func (client *Client) HKeys(ctx context.Context, key string) ([]string, error)

func (*Client) HScan

func (client *Client) HScan(ctx context.Context, key string, cursor uint64, match string, count int64) ([]string, uint64, error)

func (*Client) HSet

func (client *Client) HSet(ctx context.Context, key string, values ...interface{}) (int64, error)

HSet 将哈希表 key 中的字段 field 的值设为 value

命令说明:

为哈希表中的字段赋值 。
PS:
(1) 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
(2) 如果字段已经存在于哈希表中,旧值将被覆盖。

命令语法: HSET KEY_NAME FIELD VALUE 命令返回值: 如果字段是哈希表中的一个新建字段,并且值设置成功,返回 1 。 如果哈希表中域字段已经存在且旧值已被新值覆盖,返回 0 。

PS: (1) 3个传参都可以为""(3个全是""也可以); (2) 可以一次性设置多对 field 和 value.

@param key 如果db中不存在,会自动创建 @param values accepts values in following formats:

("myhash", "key1", "value1", "key2", "value2")
("myhash", []string{"key1", "value1", "key2", "value2"})
("myhash", map[string]interface{}{"key1": "value1", "key2": "value2"})

func (*Client) HSetNX

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

HSetNX 只有在 字段field 不存在时,设置哈希表字段的值

命令说明:

为哈希表中不存在的的字段赋值。
PS:
(1) 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
(2) 如果字段已经存在于哈希表中,操作无效。
(3) 如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。

命令语法: HSETNX KEY_NAME FIELD VALUE 命令返回值: 设置成功,返回 1 。 如果给定字段已经存在且没有操作被执行,返回 0 。

PS: (1) 如果field未存在,将返回: (true, nil). (2) 如果field已存在,将返回: (false, nil),且 此次设置哈希表字段的值 将无效.

@param key 如果db中不存在,会自动创建

func (*Client) Incr

func (client *Client) Incr(ctx context.Context, key string) (int64, error)

Incr

命令说明: Redis Incr 命令将 key 中储存的数字值增一。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。

@param key (1) 可以不存在

(2) 可以为""

e.g. key不存在

(context.Background(), "a") => 1 <nil>

e.g.1 key存在&&value为"1"

(context.Background(), "a") => 2 <nil>

e.g.2 key存在&&value为"-1000"

(context.Background(), "a") => -999 <nil>

e.g.3 key存在&&value为"9223372036854775807"(将返回error)

(context.Background(), "a") => 0 ERR increment or decrement would overflow

e.g.4 key存在&&value为"3.1415926"(将返回error)

(context.Background(), "a") => 0 ERR value is not an integer or out of range

e.g.5 key存在但类型为list(将返回error)

(context.Background(), "a") => 0 WRONGTYPE Operation against a key holding the wrong kind of value

func (*Client) IncrBy

func (client *Client) IncrBy(ctx context.Context, key string, value int64) (int64, error)

IncrBy

命令说明: Redis Incrby 命令将 key 中储存的数字加上指定的增量值。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。

func (*Client) IncrByFloat

func (client *Client) IncrByFloat(ctx context.Context, key string, value float64) (float64, error)

IncrByFloat

命令说明: Redis Incrbyfloat 命令为 key 中所储存的值加上指定的浮点数增量值。 (1) 如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。

func (*Client) IsStreamSupported

func (client *Client) IsStreamSupported(ctx context.Context) error

IsStreamSupported

PS: (1) 低版本Redis(<5)不支持Stream; (2) Tendis 2.6.0不支持Stream; (3) TongRDS(具体版本未知)支持Stream.

func (*Client) Keys deprecated

func (client *Client) Keys(ctx context.Context, pattern string) ([]string, error)

Keys

Deprecated: 当 KEYS命令 被用于处理一个大的数据库时,它可能会阻塞服务器达数秒之久。

e.g. db为空(或者不存在与 传参match 响应的key) => ([]string{}, nil)(第一个返回值不为nil)

func (*Client) LPop

func (client *Client) LPop(ctx context.Context, key string) (string, error)

LPop 移除并返回列表的第一个元素

PS: 如果移除后列表为空。将删除该key.

@return key不存在的情况,将返回 ("", redis.Nil)

func (*Client) LPush

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

LPush 将一个或多个值插入到列表头部

语法: LPUSH key value1 [value2]

@param key 不存在的话,会自动创建此key

func (*Client) LPushX

func (client *Client) LPushX(ctx context.Context, key string, values ...interface{}) (int64, error)

LPushX 将一个或多个值插入到列表头部

PS: (1) 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作; (2) 当 key 存在但不是列表类型时,返回一个错误。

@return key不存在的话,将返回 (0, nil)

func (*Client) MGet

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

MGet

命令说明: 返回所有(一个或多个)给定 key 的值。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。 命令语法: MGET KEY1 KEY2 .. KEYN 命令返回值: 一个包含所有给定 key 的值的列表。

func (*Client) MSet

func (client *Client) MSet(ctx context.Context, values ...interface{}) (bool, error)

MSet

命令说明: 同时设置一个或多个 key-value 对。 命令语法: MSET key1 value1 key2 value2 .. keyN valueN 命令返回值: 总是返回 OK 。

func (*Client) MSetNX

func (client *Client) MSetNX(ctx context.Context, values ...interface{}) (bool, error)

MSetNX

命令说明: 所有给定 key 都不存在时,同时设置一个或多个 key-value 对。 命令语法: MSETNX key1 value1 key2 value2 .. keyN valueN 命令返回值: 当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。

func (*Client) NewDistributedMutex

func (client *Client) NewDistributedMutex(name string, options ...redsync.Option) *redsync.Mutex

NewDistributedMutex 生成Redis分布式互斥锁.

Go 每日一库之 redis官网推荐的go版本的分布式锁:redsync

https://mp.weixin.qq.com/s/yXbEMTsZEgLWZuZgrFPXSg

图解redsync开源包,告诉你分布式锁为什么不仅仅是setnx

https://mp.weixin.qq.com/s/hI4bKjNB_20dGC4kZZxKsQ

PS: (1) 不可重入锁; (2) 更多详见"Redis分布式锁(多语言).docx"; (3) 写入Redis中键的默认TTL为: 8s. (4) Unlock:

如果持有锁的时间 > Redis键的TTL,此时 "解锁" 将返回 false, error(类型: *redsync.ErrTaken; 错误内容: lock already taken, locked nodes: [0]);

(5) Lock:

retry(获取锁失败后等一会,再尝试获取锁),相关配置: redsync.WithTries()、redsync.WithRetryDelay()、redsync.WithRetryDelayFunc()
retry整体周期内,如果获取锁失败,将返回error:
	(a) 类型: *redsync.ErrTaken; 错误内容: lock already taken, locked nodes: [0]
	(b) redsync.ErrFailed
e.g.
	PS: 尝试获取锁其实也要花一点时间.
	默认配置下,总计重试 32 次,第0次不等待,第1~31次在开始时等待随机时间([50, 250)ms).
	retry整体周期为 约4.8s(因为随机),还是获取不到则返回error.
e.g.1
	如果配置后,整体retry周期 > Redis中key的TTL,当上一个锁的key超时后,你就能获取到锁了(假如没有其他人也在抢锁).

@param name 建议以 "mutex:" 为前缀

e.g. 将TTL修改为30s(原8s) NewDistributedMutex("name", redsync.WithExpiry(time.Second * 30))

func (*Client) NewUniqueId

func (client *Client) NewUniqueId(ctx context.Context, key string) (string, error)

NewUniqueId 通过Redis生成唯一id.

PS: 返回值可以用作"分布式唯一id".

@param key (1) 可以不存在

(2) 可以为""

func (*Client) PFAdd

func (client *Client) PFAdd(ctx context.Context, key string, els ...interface{}) (int64, error)

PFAdd 添加指定元素到 HyperLogLog 中。

语法: PFADD key element [element ...]

func (*Client) PFCount

func (client *Client) PFCount(ctx context.Context, keys ...string) (int64, error)

PFCount 返回给定 HyperLogLog 的基数估算值。

语法: PFCOUNT key [key ...]

func (*Client) PFMerge

func (client *Client) PFMerge(ctx context.Context, dest string, keys ...string) (string, error)

PFMerge 将多个 HyperLogLog 合并为一个 HyperLogLog。

语法: PFMERGE destkey sourcekey [sourcekey ...]

func (*Client) PSubscribe

func (client *Client) PSubscribe(ctx context.Context, patterns ...string) *redis.PubSub

PSubscribe 模式的订阅(对频道的模糊匹配,通过*).

PS: 每个模式以 * 作为匹配符,e.g.

it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等);
news.* 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类.

命令说明: 命令订阅一个或多个符合给定模式的频道. 命令语法: PSUBSCRIBE pattern [pattern ...] 命令返回值: 接收到的信息.

e.g. 监听 所有db 中key的超时

!!!: 需要先配置好Redis并重启,详见"Redis.wps".
传参channels: "__keyevent@*__:expired"

func (*Client) Persist

func (client *Client) Persist(ctx context.Context, key string) (bool, error)

Persist

命令说明: 移除给定 key 的过期时间,使得 key 永不过期。 命令语法: PERSIST KEY_NAME 命令返回值: 当过期时间移除成功时,返回 1 。 如果 key 不存在或 key 没有设置过期时间,返回 0 。

func (*Client) Ping

func (client *Client) Ping(ctx context.Context) (string, error)

func (*Client) Pipeline

func (client *Client) Pipeline() redis.Pipeliner

Pipeline 管道

TODO: cluster集群模式下,使用pipeline有问题.

redis.Pipeliner实例调用Exec函数执行时,第二个返回值为error类型: (1) 假如管道中每条命令都正常执行,将返回nil; (2) 假如管道中某些命令报错了,将返回第一个报错命令的error实例.

func (*Client) Publish

func (client *Client) Publish(ctx context.Context, channel string, message interface{}) (int64, error)

Publish 发布.

参考: https://www.runoob.com/redis/pub-sub-publish.html

命令说明: 命令用于将信息发送到指定的频道 命令语法: PUBLISH channel message 命令返回值: 接收到信息的订阅者数量

@param channel 频道 @param message 消息(可以是 string 类型)

func (*Client) RandomKey

func (client *Client) RandomKey(ctx context.Context) (string, error)

RandomKey

命令说明: 从当前数据库中随机返回一个 key. 命令语法: RANDOMKEY 命令返回值: 当数据库不为空时,返回一个 key;当数据库为空时,返回 nil(windows 系统返回 null).

func (*Client) Rename

func (client *Client) Rename(ctx context.Context, key, newKey string) (string, error)

Rename

命令说明: 修改 key 的名称 。 命令语法: RENAME OLD_KEY_NAME NEW_KEY_NAME 命令返回值:

改名成功时提示 OK ,失败时候返回一个错误。
当 OLD_KEY_NAME 和 NEW_KEY_NAME 相同,或者 OLD_KEY_NAME 不存在时,返回一个错误。 当 NEW_KEY_NAME 已经存在时, RENAME 命令将覆盖旧值。

func (*Client) RenameNX

func (client *Client) RenameNX(ctx context.Context, key, newKey string) (bool, error)

RenameNX

命令说明: 在新的 key 不存在时修改 key 的名称 。 命令语法: RENAMENX OLD_KEY_NAME NEW_KEY_NAME 命令返回值: 修改成功时,返回 1 。 如果 NEW_KEY_NAME 已经存在,返回 0 。

func (*Client) SAdd

func (client *Client) SAdd(ctx context.Context, key string, members ...interface{}) (int64, error)

SAdd 将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略.

PS: (1) 假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合; (2) 当集合 key 不是集合类型时,返回一个错误.

@return 第1个返回值: 成功添加的成员的数量(已经在集合中的不算)

func (*Client) SIsMember

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

SIsMember 判断 member元素 是否是 key对应集合 的成员?

func (*Client) SMembers deprecated

func (client *Client) SMembers(ctx context.Context, key string) ([]string, error)

SMembers 返回集合中的所有的成员(不存在的集合 key 被视为空集合).

Deprecated: 当 SMEMBERS命令 被用于处理一个大的数据库时,它可能会阻塞服务器达数秒之久。

e.g. key不存在的情况 => ([]string{}, nil)

func (*Client) SMembersMap deprecated

func (client *Client) SMembersMap(ctx context.Context, key string) (map[string]struct{}, error)

SMembersMap

Deprecated: 当 SMEMBERS命令 被用于处理一个大的数据库时,它可能会阻塞服务器达数秒之久。

@return 第1个返回值: key为成员的值,value为空结构体(无意义)

e.g. key不存在的情况 => (map[string]struct{}{}, nil)

func (*Client) SPop

func (client *Client) SPop(ctx context.Context, key string) (string, error)

SPop 用于移除并返回集合(set)中的一个随机元素.

func (*Client) SPopN

func (client *Client) SPopN(ctx context.Context, key string, count int64) ([]string, error)

func (*Client) SRandMember

func (client *Client) SRandMember(ctx context.Context, key string) (string, error)

SRandMember 返回集合中 1个 随机数.

func (*Client) SRandMemberN

func (client *Client) SRandMemberN(ctx context.Context, key string, count int64) ([]string, error)

SRandMemberN 返回集合中 多个 随机数.

func (*Client) SRem

func (client *Client) SRem(ctx context.Context, key string, members ...interface{}) (int64, error)

SRem 移除集合中的一个或多个成员元素,不存在的成员元素会被忽略.

PS: (1) 移除后,如果集合为空,将自动删除 传参key. (2) 当 key 不是集合类型,返回一个错误.

@return 第1个返回值: 被成功移除的元素的数量,不包括被忽略的元素(集合中本来就不存在该元素)

func (*Client) SSubscribe

func (client *Client) SSubscribe(ctx context.Context, channels ...string) *redis.PubSub

SSubscribe

TODO: 目前还未在网上找到"SSUBSCRIBE"命令的相关说明,

func (*Client) Scan deprecated

func (client *Client) Scan(ctx context.Context, cursor uint64, match string, count int64) ([]string, uint64, error)

Scan 迭代当前数据库中的数据库键.

Deprecated: 建议直接使用 ScanFully.

PS: (1) scan命令也并不是完美的,它"返回的结果有可能重复",因此需要客户端"去重"; (2) 用于替代keys,因为keys在大数据量有性能问题; (3) 返回的[]string实例的长度可能会大于传参count,比如瞎传cursor的情况,编码时得注意.

@return 返回的error == nil的情况下,第1个返回值([]string)必定不为nil

e.g. db为空(|| db中不存在符合条件的key) (context.TODO(), 0, "*", 10) => ([]string{}, 0, nil)

func (*Client) ScanFully

func (client *Client) ScanFully(ctx context.Context, match string, count int64) ([]string, error)

ScanFully 对 Scan 进行了封装,用于替代 Keys 命令.

增量迭代命令的缺点:

因为在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素"提供有限的保证" (offer limited guarantees about the returned elements)。

PS: (1) 如果db为空,将返回: [] <nil> (2) redis cluster模式下,需要特殊处理(详见代码),否则:明明有数据的情况下,可能取不到数据,或者取到的数据不全(因为只找1个节点要).

@return 返回的error == nil的情况下,第1个返回值([]string)必定不为nil

e.g. db为空(|| db中不存在符合条件的key) (context.TODO(), "*", 10) => ([]string{}, nil)

func (*Client) ScriptLoad

func (client *Client) ScriptLoad(ctx context.Context, script string) (string, error)

ScriptLoad

命令说明: 将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本 命令语法: SCRIPT LOAD script 命令返回值: 给定脚本的 SHA1 校验码

func (*Client) Set

func (client *Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)

Set 设置指定key的值(string类型).

命令说明: 设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。 命令语法: SET KEY_NAME VALUE 命令返回值:

在 Redis 2.6.12 以前版本, SET 命令总是返回 OK 。
从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK 。

@param key 可以为"" @param value 支持的类型: string、[]byte、int、float64、bool(true: "1"; false: "0")...

不支持的类型(会返回error): map、自定义结构体...

@param expiration e.g. 120*time.Second 120s后过期

 	 0 						持久化的键(即TTL为-1),无论:键是否存在、存在的键是否有超时时间
 	 -1(即redis.KeepTTL)	(需要确保Redis版本 >= 6.0,否则会返回error: ERR syntax error)
							(a) 键存在:		保持已经存在的TTL
							(b) 键不存在:	持久化的键

func (*Client) SetEx deprecated

func (client *Client) SetEx(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)

SetEx

Deprecated: 个人感觉在 go-redis 中,使用 Set 就够了.

命令说明: 为指定的 key 设置值及其过期时间。。(如果 key 已经存在,SETEX 命令将会 替换旧的值 并 更新TTL) 命令语法: SETEX KEY_NAME TIMEOUT VALUE 命令返回值: 设置成功时返回 OK 。

func (*Client) SetNX

func (client *Client) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)

SetNX key不存在才会: 设置值 && 更新TTL

PS: 如果传参key已经存在,不会修改该key的TTL.

命令说明: 在指定的 key 不存在时,为 key 设置指定的值. 命令语法: SETNX KEY_NAME VALUE 命令返回值: 设置成功,返回 1 ;设置失败,返回 0 .

@return 第一个返回值代表: 是否设置成功

func (*Client) SetXX

func (client *Client) SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)

SetXX (与 SetNX 相反)key存在才会: 设置值 && 更新TTL

Redis的数据类型详解 https://blog.csdn.net/m0_53474063/article/details/112647028

func (*Client) Subscribe

func (client *Client) Subscribe(ctx context.Context, channels ...string) *redis.PubSub

Subscribe 频道的订阅(对频道的完全匹配).

PS: (1) 建议 起一个goroutine 来进行订阅操作. (2) *redis.PubSub实例的2种使用方法: (a) PubSub.Channel()(推荐)

(b) PubSub.ReceiveMessage()

(3) 取消订阅详见"_info.md".

命令说明: 订阅给定的一个或多个频道的信息. 命令语法: SUBSCRIBE channel [channel ...] 命令返回值: 接收到的信息.

e.g. 监听 db0 中key的超时

!!!: 需要先配置好Redis并重启,详见"Redis.wps".
传参channels: "__keyevent@0__:expired"

func (*Client) TTL

func (client *Client) TTL(ctx context.Context, key string) (time.Duration, error)

TTL

命令说明: 返回 key 的剩余过期时间. 命令语法: TTL KEY_NAME 命令返回值: (1) 当 key 不存在时,返回 -2

(2) 当 key 存在但没有设置剩余生存时间时(持久化键),返回 -1
(3) 否则,以毫秒为单位,返回 key 的剩余生存时间

func (*Client) TxPipeline

func (client *Client) TxPipeline() redis.Pipeliner

TxPipeline 事务管道

TODO: cluster集群模式下,使用pipeline有问题.

详见"Redis.docx".

func (*Client) Type

func (client *Client) Type(ctx context.Context, key string) (string, error)

Type

命令说明: 返回 key 所储存的值的类型. 命令语法: TYPE KEY_NAME 命令返回值:

none (key不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)

e.g. 传参key不存在的情况 => ("none", nil)

func (*Client) XAck

func (client *Client) XAck(ctx context.Context, stream, group string, ids ...string) (int64, error)

XAck [消费者] 将消息标记为"已处理".

PS: 并不会删除对应消息.

func (*Client) XAdd

func (client *Client) XAdd(ctx context.Context, a *redis.XAddArgs) (id string, err error)

XAdd [生产者] 添加消息到末尾.

PS: (1) 传参stream 不存在,会自动创建; (2) 传参stream 存在但类型不是 stream,会返回error: WRONGTYPE Operation against a key holding the wrong kind of value (3) e.g. 指定stream中已经有1w条消息

此时继续调用 XAdd 且 MaxLen == 100,成功执行后,该stream中只有100条消息(如果 Approx 为true,stream的实际长度可能略高于你设置的值).

语法: XADD key ID field value [field value ...] key: 队列名称,如果不存在就创建 ID: 消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性。 field value: 记录

@param a (1) 必需的字段: Stream、Values

	推荐的字段: MaxLen(防止消息堆积)、Approx(可选; true: stream的实际长度可能略高于你设置的值)
(2) Stream字段对应: Redis中的key(stream类型)
(3) 可选的ID字段,为 ""(默认) 则由Redis生成

@return id: 消息的id

e.g.

_, err := impl.client.XAdd(context.Background(), &redis.XAddArgs{
	Stream: topic,
	Values: map[string]interface{}{
		"tag":  tag,
		"data": data,
	},
})

func (*Client) XDel

func (client *Client) XDel(ctx context.Context, stream string, ids ...string) (int64, error)

XDel 删除Stream中的特定消息.

@return (1) 删除成功: 返回(1, nil)

(2) 删除失败: 返回(0, nil)(e.g. stream 和 id 对应的消息不存在)

func (*Client) XGroupCreate

func (client *Client) XGroupCreate(ctx context.Context, stream, group, start string) error

XGroupCreate 在 stream 中,创建消费者组Consumer Group.

命令: ("xgroup", "create", stream, group, start)

@return (1) 如果 stream 不存在的话,会返回error:

		ERR The XGROUP subcommand requires the key to exist. Note that for CREATE you may want to use the MKSTREAM option to create an empty stream automatically.
(2) stream 已经存在的情况下,如果 group 已经存在的话,会返回error(此种error建议忽略; 可以通过 IsConsumerGroupNameAlreadyExistError 判断):
		BUSYGROUP Consumer Group name already exists

func (*Client) XGroupCreateMkStream

func (client *Client) XGroupCreateMkStream(ctx context.Context, stream, group, start string) error

XGroupCreateMkStream 在 stream 中,创建消费者组Consumer Group(如果stream不存在,那么会自动创建一个空(长度为0)的stream).

PS: (1) 命令: ("xgroup", "create", stream, group, start, "mkstream")

MKSTREAM是一个可选子命令,如果指定了它,那么在创建消费者组的时候,如果stream不存在,那么会自动创建一个空(长度为0)的stream

@return stream存在的情况下,如果 group 已经存在的话,会返回error(此种error建议忽略; 可以通过 IsConsumerGroupNameAlreadyExistError 判断):

BUSYGROUP Consumer Group name already exists

@param stream 要创建的 消费者组的流 的名称(不存在的话,会自动创建一个空的(长度为0)的stream) @param group 要创建的 消费者组 的名称 @param start 起始 ID,可以是具体的 ID 或特殊的 "$"

e.g.
(1) "0": 从头开始消费
(2) "$": 从末尾开始消费(从流的最新消息开始)

func (*Client) XRead

func (client *Client) XRead(ctx context.Context, a *redis.XReadArgs) ([]redis.XStream, error)

func (*Client) XReadGroup

func (client *Client) XReadGroup(ctx context.Context, a *redis.XReadGroupArgs) ([]redis.XStream, error)

XReadGroup [消费者] 读取消费者组中的消息.("xreadgroup", "group")

PS: (1) case: stream 不存在(包括情况: 读到一半stream被人手动删了),

返回error: NOGROUP No such key '???' or consumer group '???' in XREADGROUP with GROUP option

(2) case: stream 存在 但 group 不存在,

返回error: NOGROUP No such key '???' or consumer group '???' in XREADGROUP with GROUP option

(3) 如果没有新消息,会"阻塞". (4) 推荐使用场景: 写个死循环(e.g.for{}),不停调用 XReadGroup,且中途无需sleep一会.

XReadGroupArgs结构体:

Group 		消费组名
Consumer	消费者名
Count		读取数量
Block		阻塞时间
Streams		要读取的所有Stream(!!!: (1) 数量应当>=2; (2) 最后一个元素应该是 ">")

e.g.

entries, err := impl.client.XReadGroup(context.Background(), &redis.XReadGroupArgs{
	Consumer: consumer,
	Group:    group,
	Streams:  []string{stream, ">"},
	Count:    10,
	//Block:    0,
	//NoAck:    false,
})

func (*Client) XReadStreams

func (client *Client) XReadStreams(ctx context.Context, streams ...string) ([]redis.XStream, error)

func (*Client) XTrimMaxLen added in v3.0.106

func (client *Client) XTrimMaxLen(ctx context.Context, key string, maxLen int64) (int64, error)

func (*Client) XTrimMaxLenApprox added in v3.0.106

func (client *Client) XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) (int64, error)

XTrimMaxLenApprox

与 XTrimMaxLen 类似,但是它不保证精确地达到指定的长度,而是尝试接近那个长度。这意味着在某些情况下,stream的实际长度可能略高于你设置的值。 这种策略在需要更高的性能而能接受一定误差的情况下很有用。

approx: 大约

func (*Client) XTrimMinID added in v3.0.106

func (client *Client) XTrimMinID(ctx context.Context, key string, minID string) (int64, error)

func (*Client) XTrimMinIDApprox added in v3.0.106

func (client *Client) XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) (int64, error)

func (*Client) ZAdd

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

ZAdd

命令说明: 将一个或多个成员元素及其分数值加入到有序集当中。

(1) 如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。
(2) 分数值可以是 整数值 或 双精度浮点数。
(3) 如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
(4) 当 key 存在但不是有序集类型时,返回一个错误。

命令语法: ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN 命令返回值: 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。

func (*Client) ZCard

func (client *Client) ZCard(ctx context.Context, key string) (int64, error)

ZCard

命令说明: 计算集合中元素的数量。 命令语法: ZCARD KEY_NAME 命令返回值: 当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0。

func (*Client) ZCount

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

ZCount

命令说明: 计算有序集合中指定分数区间的成员数量。 命令语法: ZCOUNT key min max 命令返回值: 分数值在 min 和 max 之间的成员的数量。

func (*Client) ZRangeByScore

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

ZRangeByScore

命令说明:

返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。
具有相同分数值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。
默认情况下,区间的取值使用闭区间 (小于等于或大于等于),你也可以通过给参数前增加 ( 符号来使用可选的开区间 (小于或大于)。

命令语法: ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 命令返回值: 指定区间内,带有分数值(可选)的有序集成员的列表。

func (*Client) ZRangeByScoreWithScores

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

ZRangeByScoreWithScores

详见: ZRangeByScore,命令中有 WITHSCORES.

func (*Client) ZRem

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

ZRem

命令说明: 移除有序集中的一个或多个成员,不存在的成员将被忽略。(当 key 存在但不是有序集类型时,返回一个错误。) 命令语法: ZREM key member [member ...] 命令返回值: 被成功移除的成员的数量,不包括被忽略的成员。

func (*Client) ZRevRangeByScore

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

ZRevRangeByScore

命令说明:

返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。
具有相同分数值的成员按字典序的逆序(reverse lexicographical order )排列。
除了成员按分数值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE 命令一样。

命令语法: ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 命令返回值: 指定区间内,带有分数值(可选)的有序集成员的列表。

func (*Client) ZRevRangeByScoreWithScores

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

ZRevRangeByScoreWithScores

详见: ZRevRangeByScore,命令中有 WITHSCORES.

type ClusterConfig

type ClusterConfig struct {
	// Addrs
	/*
		A seed list of host:port addresses of cluster nodes.
		可以是: 所有的 master 的地址,
		也可以是: 所有的 master + slave 的地址(推荐).
	*/
	Addrs []string `json:"addrs" yaml:"addrs" validate:"required,gte=2,unique,dive,hostname_port"`

	UseReplicasForReadOperations bool `json:"useReplicasForReadOperations" yaml:"useReplicasForReadOperations"`
}

type Config

type Config struct {
	UserName string `json:"userName" yaml:"userName"`
	// Password
	/*
	  如果Redis有密码,此处配置必须配置;
	  如果Redis无密码,此处配置配不配置皆可(配置了也不会报错).
	*/
	Password  string `json:"password" yaml:"password"`
	KeyPrefix string `json:"keyPrefix" yaml:"keyPrefix"`

	Mode Mode `json:"mode" yaml:"mode" validate:"oneof=single sentinel cluster"`

	Single *SingleConfig `json:"single" yaml:"single" validate:"required_if=Mode single"`
	//MasterSlave *MasterSlaveConfig `json:"masterSlave" yaml:"masterSlave" validate:"required_if=Mode masterSlave"`
	Sentinel *SentinelConfig `json:"sentinel" yaml:"sentinel" validate:"required_if=Mode sentinel"`
	Cluster  *ClusterConfig  `json:"cluster" yaml:"cluster" validate:"required_if=Mode cluster"`
}

func (*Config) Simplify

func (config *Config) Simplify()

Simplify 简化配置.

func (*Config) Validate added in v3.0.73

func (config *Config) Validate() error

Validate

@param config 可能为nil

type Mode

type Mode string

Mode Redis的集群模式

const (
	// ModeSingle 单点
	ModeSingle Mode = "single"
	// ModeMasterSlave 主从集群
	ModeMasterSlave Mode = "masterSlave"
	// ModeSentinel 哨兵集群
	ModeSentinel Mode = "sentinel"
	// ModeCluster cluster集群
	ModeCluster Mode = "cluster"

	// DefaultMasterName 哨兵模式下,默认的MasterName
	DefaultMasterName = "mymaster"
)

type SentinelConfig

type SentinelConfig struct {
	// MasterName The master name.
	MasterName string `json:"masterName" yaml:"masterName"`

	// Addrs A seed list of host:port addresses of sentinel nodes.
	Addrs []string `json:"addrs" yaml:"addrs" validate:"required,gte=2,unique,dive,hostname_port"`

	DB int `json:"db" yaml:"db" validate:"gte=0"`
}

type SingleConfig

type SingleConfig struct {
	// Addr address(host:port)
	Addr string `json:"addr" yaml:"addr" validate:"hostname_port"`

	// DB Database to be selected after connecting to the server.
	DB int `json:"db" yaml:"db" validate:"gte=0"`
}

Jump to

Keyboard shortcuts

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