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 ¶
- Variables
- func IsConsumerGroupNameAlreadyExistError(err error) bool
- func IsNoStreamOrNoGroupError(err error) bool
- func MustSetUp(config *Config)
- func SetUp(config *Config) (err error)
- type Client
- func (client *Client) Append(ctx context.Context, key, value string) (int64, error)
- func (client *Client) Close() error
- func (client *Client) DBSize(ctx context.Context) (int64, error)
- func (client *Client) Decr(ctx context.Context, key string) (int64, error)
- func (client *Client) DecrBy(ctx context.Context, key string, decrement int64) (int64, error)
- func (client *Client) Del(ctx context.Context, keys ...string) (int64, error)
- func (client *Client) Eval(ctx context.Context, script string, keys []string, args ...interface{}) (interface{}, error)
- func (client *Client) EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) (interface{}, error)
- func (client *Client) Exists(ctx context.Context, keys ...string) (bool, error)
- func (client *Client) Expire(ctx context.Context, key string, expiration time.Duration) (bool, error)
- func (client *Client) ExpireAt(ctx context.Context, key string, tm time.Time) (bool, error)
- func (client *Client) FlushAll(ctx context.Context) (string, error)
- func (client *Client) FlushAllAsync(ctx context.Context) (string, error)
- func (client *Client) FlushDB(ctx context.Context) (string, error)
- func (client *Client) FlushDBAsync(ctx context.Context) (string, error)
- func (client *Client) GeoAdd(ctx context.Context, key string, geoLocation ...*redis.GeoLocation) (int64, error)
- func (client *Client) GeoDist(ctx context.Context, key string, member1, member2, unit string) (float64, error)
- func (client *Client) GeoPos(ctx context.Context, key string, members ...string) ([]*redis.GeoPos, error)
- func (client *Client) Get(ctx context.Context, key string) (string, error)
- func (client *Client) GetKeyWithPrefix(key string) string
- func (client *Client) GetMode() Mode
- func (client *Client) GetPrefix() string
- func (client *Client) GetUniversalClient() redis.UniversalClient
- func (client *Client) GetWithoutRedisNil(ctx context.Context, key string) (string, error)
- func (client *Client) HDel(ctx context.Context, key string, fields ...string) (int64, error)
- func (client *Client) HExists(ctx context.Context, key, field string) (bool, error)
- func (client *Client) HGet(ctx context.Context, key, field string) (string, error)
- func (client *Client) HGetAll(ctx context.Context, key string) (map[string]string, error)
- func (client *Client) HKeys(ctx context.Context, key string) ([]string, error)
- func (client *Client) HScan(ctx context.Context, key string, cursor uint64, match string, count int64) ([]string, uint64, error)
- func (client *Client) HSet(ctx context.Context, key string, values ...interface{}) (int64, error)
- func (client *Client) HSetNX(ctx context.Context, key, field string, value interface{}) (bool, error)
- func (client *Client) Incr(ctx context.Context, key string) (int64, error)
- func (client *Client) IncrBy(ctx context.Context, key string, value int64) (int64, error)
- func (client *Client) IncrByFloat(ctx context.Context, key string, value float64) (float64, error)
- func (client *Client) IsStreamSupported(ctx context.Context) error
- func (client *Client) Keys(ctx context.Context, pattern string) ([]string, error)deprecated
- func (client *Client) LPop(ctx context.Context, key string) (string, error)
- func (client *Client) LPush(ctx context.Context, key string, values ...interface{}) (int64, error)
- func (client *Client) LPushX(ctx context.Context, key string, values ...interface{}) (int64, error)
- func (client *Client) MGet(ctx context.Context, keys ...string) ([]interface{}, error)
- func (client *Client) MSet(ctx context.Context, values ...interface{}) (bool, error)
- func (client *Client) MSetNX(ctx context.Context, values ...interface{}) (bool, error)
- func (client *Client) NewDistributedMutex(name string, options ...redsync.Option) *redsync.Mutex
- func (client *Client) NewUniqueId(ctx context.Context, key string) (string, error)
- func (client *Client) PFAdd(ctx context.Context, key string, els ...interface{}) (int64, error)
- func (client *Client) PFCount(ctx context.Context, keys ...string) (int64, error)
- func (client *Client) PFMerge(ctx context.Context, dest string, keys ...string) (string, error)
- func (client *Client) PSubscribe(ctx context.Context, patterns ...string) *redis.PubSub
- func (client *Client) Persist(ctx context.Context, key string) (bool, error)
- func (client *Client) Ping(ctx context.Context) (string, error)
- func (client *Client) Pipeline() redis.Pipeliner
- func (client *Client) Publish(ctx context.Context, channel string, message interface{}) (int64, error)
- func (client *Client) RandomKey(ctx context.Context) (string, error)
- func (client *Client) Rename(ctx context.Context, key, newKey string) (string, error)
- func (client *Client) RenameNX(ctx context.Context, key, newKey string) (bool, error)
- func (client *Client) SAdd(ctx context.Context, key string, members ...interface{}) (int64, error)
- func (client *Client) SIsMember(ctx context.Context, key string, member interface{}) (bool, error)
- func (client *Client) SMembers(ctx context.Context, key string) ([]string, error)deprecated
- func (client *Client) SMembersMap(ctx context.Context, key string) (map[string]struct{}, error)deprecated
- func (client *Client) SPop(ctx context.Context, key string) (string, error)
- func (client *Client) SPopN(ctx context.Context, key string, count int64) ([]string, error)
- func (client *Client) SRandMember(ctx context.Context, key string) (string, error)
- func (client *Client) SRandMemberN(ctx context.Context, key string, count int64) ([]string, error)
- func (client *Client) SRem(ctx context.Context, key string, members ...interface{}) (int64, error)
- func (client *Client) SSubscribe(ctx context.Context, channels ...string) *redis.PubSub
- func (client *Client) Scan(ctx context.Context, cursor uint64, match string, count int64) ([]string, uint64, error)deprecated
- func (client *Client) ScanFully(ctx context.Context, match string, count int64) ([]string, error)
- func (client *Client) ScriptLoad(ctx context.Context, script string) (string, error)
- func (client *Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)
- func (client *Client) SetEx(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)deprecated
- func (client *Client) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)
- func (client *Client) SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error)
- func (client *Client) Subscribe(ctx context.Context, channels ...string) *redis.PubSub
- func (client *Client) TTL(ctx context.Context, key string) (time.Duration, error)
- func (client *Client) TxPipeline() redis.Pipeliner
- func (client *Client) Type(ctx context.Context, key string) (string, error)
- func (client *Client) XAck(ctx context.Context, stream, group string, ids ...string) (int64, error)
- func (client *Client) XAdd(ctx context.Context, a *redis.XAddArgs) (id string, err error)
- func (client *Client) XDel(ctx context.Context, stream string, ids ...string) (int64, error)
- func (client *Client) XGroupCreate(ctx context.Context, stream, group, start string) error
- func (client *Client) XGroupCreateMkStream(ctx context.Context, stream, group, start string) error
- func (client *Client) XRead(ctx context.Context, a *redis.XReadArgs) ([]redis.XStream, error)
- func (client *Client) XReadGroup(ctx context.Context, a *redis.XReadGroupArgs) ([]redis.XStream, error)
- func (client *Client) XReadStreams(ctx context.Context, streams ...string) ([]redis.XStream, error)
- func (client *Client) XTrimMaxLen(ctx context.Context, key string, maxLen int64) (int64, error)
- func (client *Client) XTrimMaxLenApprox(ctx context.Context, key string, maxLen, limit int64) (int64, error)
- func (client *Client) XTrimMinID(ctx context.Context, key string, minID string) (int64, error)
- func (client *Client) XTrimMinIDApprox(ctx context.Context, key string, minID string, limit int64) (int64, error)
- func (client *Client) ZAdd(ctx context.Context, key string, members ...redis.Z) (int64, error)
- func (client *Client) ZCard(ctx context.Context, key string) (int64, error)
- func (client *Client) ZCount(ctx context.Context, key, min, max string) (int64, error)
- func (client *Client) ZRangeByScore(ctx context.Context, key string, opt *redis.ZRangeBy) ([]string, error)
- func (client *Client) ZRangeByScoreWithScores(ctx context.Context, key string, opt *redis.ZRangeBy) ([]redis.Z, error)
- func (client *Client) ZRem(ctx context.Context, key string, members ...interface{}) (int64, error)
- func (client *Client) ZRevRangeByScore(ctx context.Context, key string, opt *redis.ZRangeBy) ([]string, error)
- func (client *Client) ZRevRangeByScoreWithScores(ctx context.Context, key string, opt *redis.ZRangeBy) ([]redis.Z, error)
- type ClusterConfig
- type Config
- type Mode
- type SentinelConfig
- type SingleConfig
Constants ¶
This section is empty.
Variables ¶
var (
NotSetupError = errorKit.Newf("haven’t been set up correctly")
)
Functions ¶
func IsConsumerGroupNameAlreadyExistError ¶
IsConsumerGroupNameAlreadyExistError 适用场景: 创建Consumer group(XGroupCreate || XGroupCreateMkStream)时,返回error.
TODO: 涉及 github.com/redis/go-redis/v9 源码, 后续看有没有好的解决方法.
@return true: 错误是由 "指定group已经存在(无需重复创建)" 导致的.
func IsNoStreamOrNoGroupError ¶ added in v3.0.106
IsNoStreamOrNoGroupError 适用场景: Consumer读取消息时,返回error.
TODO: 涉及 github.com/redis/go-redis/v9 源码, 后续看有没有好的解决方法.
@return true: 错误是由 "指定stream不存在" 或 "指定stream存在,但指定group不存在" 导致的.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
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 ¶
Append
命令说明: Redis Append 命令用于为指定的 key 追加值。 (1) 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。 (2) 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
@return 追加后值的长度
func (*Client) Decr ¶
Decr
命令说明: Redis Decr 命令将 key 中储存的数字值减一。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。
func (*Client) DecrBy ¶
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) 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 ¶
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 ¶
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 ¶
FlushAll
命令说明: 清空整个 Redis 服务器的数据(删除所有数据库的所有 key ). 命令语法: FLUSHALL 命令返回值: 总是返回 OK .
func (*Client) FlushAllAsync ¶
FlushAllAsync 异步地.
func (*Client) FlushDBAsync ¶
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 ¶
Get
命令说明: 获取指定 key 的值。(如果 key 不存在,返回 nil;如果key 储存的值不是字符串类型,返回一个错误) 命令语法: GET KEY_NAME 命令返回值: 返回 key 的值,如果 key 不存在时,返回 nil。 如果 key 不是字符串类型,那么返回一个错误。
e.g. 当前db中不存在 传参key => ("", redis.Nil)
func (*Client) GetKeyWithPrefix ¶
func (*Client) GetUniversalClient ¶
func (client *Client) GetUniversalClient() redis.UniversalClient
GetUniversalClient 返回go-redis客户端
func (*Client) GetWithoutRedisNil ¶
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 ¶
HDel
命令说明: 删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。 命令语法: HDEL KEY_NAME FIELD1.. FIELDN 命令返回值: 被成功删除字段的数量,不包括被忽略的字段。
func (*Client) HExists ¶
HExists
命令说明: 用于查看哈希表的指定字段是否存在 命令语法: HEXISTS KEY_NAME FIELD_NAME 命令返回值: 如果哈希表含有给定字段(field),返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。
PS: key和field,只要有一个不存在,返回值必定为(false, nil).
@param key 可以为"" @param field 可以为""
func (*Client) HGet ¶
HGet
命令说明: 返回哈希表中指定字段的值。 命令语法: HGET KEY_NAME FIELD_NAME 命令返回值: 返回给定字段的值。如果给定的字段或 key 不存在时,返回 nil 。
func (*Client) HGetAll ¶
HGetAll
命令说明:
返回哈希表中,所有的字段和值。 在返回值里,紧跟每个字段名(field name)之后是字段的值(value),所以返回值的长度是哈希表大小的两倍。
命令语法: HGETALL KEY_NAME 命令返回值: 以列表形式返回哈希表的字段及字段值。 若 key 不存在,返回空列表。
func (*Client) HSet ¶
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 ¶
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 ¶
IncrBy
命令说明: Redis Incrby 命令将 key 中储存的数字加上指定的增量值。 (1) 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。 (2) 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 (3) 本操作的值限制在 64 位(bit)有符号数字表示之内(范围: [math.MinInt64, math.MaxInt64],即[-9223372036854775808, 9223372036854775807])。
func (*Client) IncrByFloat ¶
IncrByFloat
命令说明: Redis Incrbyfloat 命令为 key 中所储存的值加上指定的浮点数增量值。 (1) 如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。
func (*Client) IsStreamSupported ¶
IsStreamSupported
PS: (1) 低版本Redis(<5)不支持Stream; (2) Tendis 2.6.0不支持Stream; (3) TongRDS(具体版本未知)支持Stream.
func (*Client) LPop ¶
LPop 移除并返回列表的第一个元素
PS: 如果移除后列表为空。将删除该key.
@return key不存在的情况,将返回 ("", redis.Nil)
func (*Client) LPush ¶
LPush 将一个或多个值插入到列表头部
语法: LPUSH key value1 [value2]
@param key 不存在的话,会自动创建此key
func (*Client) LPushX ¶
LPushX 将一个或多个值插入到列表头部
PS: (1) 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作; (2) 当 key 存在但不是列表类型时,返回一个错误。
@return key不存在的话,将返回 (0, nil)
func (*Client) MGet ¶
MGet
命令说明: 返回所有(一个或多个)给定 key 的值。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。 命令语法: MGET KEY1 KEY2 .. KEYN 命令返回值: 一个包含所有给定 key 的值的列表。
func (*Client) MSet ¶
MSet
命令说明: 同时设置一个或多个 key-value 对。 命令语法: MSET key1 value1 key2 value2 .. keyN valueN 命令返回值: 总是返回 OK 。
func (*Client) MSetNX ¶
MSetNX
命令说明: 所有给定 key 都不存在时,同时设置一个或多个 key-value 对。 命令语法: MSETNX key1 value1 key2 value2 .. keyN valueN 命令返回值: 当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。
func (*Client) NewDistributedMutex ¶
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 ¶
NewUniqueId 通过Redis生成唯一id.
PS: 返回值可以用作"分布式唯一id".
@param key (1) 可以不存在
(2) 可以为""
func (*Client) PFMerge ¶
PFMerge 将多个 HyperLogLog 合并为一个 HyperLogLog。
语法: PFMERGE destkey sourcekey [sourcekey ...]
func (*Client) PSubscribe ¶
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 ¶
Persist
命令说明: 移除给定 key 的过期时间,使得 key 永不过期。 命令语法: PERSIST KEY_NAME 命令返回值: 当过期时间移除成功时,返回 1 。 如果 key 不存在或 key 没有设置过期时间,返回 0 。
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 ¶
RandomKey
命令说明: 从当前数据库中随机返回一个 key. 命令语法: RANDOMKEY 命令返回值: 当数据库不为空时,返回一个 key;当数据库为空时,返回 nil(windows 系统返回 null).
func (*Client) Rename ¶
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 ¶
RenameNX
命令说明: 在新的 key 不存在时修改 key 的名称 。 命令语法: RENAMENX OLD_KEY_NAME NEW_KEY_NAME 命令返回值: 修改成功时,返回 1 。 如果 NEW_KEY_NAME 已经存在,返回 0 。
func (*Client) SAdd ¶
SAdd 将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略.
PS: (1) 假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合; (2) 当集合 key 不是集合类型时,返回一个错误.
@return 第1个返回值: 成功添加的成员的数量(已经在集合中的不算)
func (*Client) SRandMember ¶
SRandMember 返回集合中 1个 随机数.
func (*Client) SRandMemberN ¶
SRandMemberN 返回集合中 多个 随机数.
func (*Client) SRem ¶
SRem 移除集合中的一个或多个成员元素,不存在的成员元素会被忽略.
PS: (1) 移除后,如果集合为空,将自动删除 传参key. (2) 当 key 不是集合类型,返回一个错误.
@return 第1个返回值: 被成功移除的元素的数量,不包括被忽略的元素(集合中本来就不存在该元素)
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 ¶
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 ¶
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) 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 ¶
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 ¶
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 ¶
Type
命令说明: 返回 key 所储存的值的类型. 命令语法: TYPE KEY_NAME 命令返回值:
none (key不存在) string (字符串) list (列表) set (集合) zset (有序集) hash (哈希表)
e.g. 传参key不存在的情况 => ("none", nil)
func (*Client) XAdd ¶
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 ¶
XDel 删除Stream中的特定消息.
@return (1) 删除成功: 返回(1, nil)
(2) 删除失败: 返回(0, nil)(e.g. stream 和 id 对应的消息不存在)
func (*Client) XGroupCreate ¶
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 ¶
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) 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) XTrimMaxLen ¶ added in v3.0.106
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) XTrimMinIDApprox ¶ added in v3.0.106
func (*Client) ZAdd ¶
ZAdd
命令说明: 将一个或多个成员元素及其分数值加入到有序集当中。
(1) 如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。 (2) 分数值可以是 整数值 或 双精度浮点数。 (3) 如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。 (4) 当 key 存在但不是有序集类型时,返回一个错误。
命令语法: ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN 命令返回值: 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
func (*Client) ZCard ¶
ZCard
命令说明: 计算集合中元素的数量。 命令语法: ZCARD KEY_NAME 命令返回值: 当 key 存在且是有序集类型时,返回有序集的基数。 当 key 不存在时,返回 0。
func (*Client) ZCount ¶
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 ¶
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] 命令返回值: 指定区间内,带有分数值(可选)的有序集成员的列表。
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"` }
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 ¶
Source Files ¶
- client.go
- command_connect.go
- command_geo.go
- command_hash.go
- command_hyper_log_log.go
- command_key.go
- command_list.go
- command_publish.go
- command_script.go
- command_server.go
- command_set.go
- command_string.go
- command_subscribe.go
- command_zset.go
- config.go
- consts.go
- mutex.go
- pipeline.go
- setup.go
- stream.go
- stream_consumer.go
- stream_create.go
- stream_error.go
- stream_producer.go
- stream_trim.go
- unique_id.go