本文首发于公众号:Hunter后端

原文链接:Golang笔记之Redis

这一篇笔记主要介绍 Golang 连接和使用 Redis,以下是本篇笔记目录:

目录
  1. 安装模块
  2. 连接 Redis
  3. 字符串
  4. 哈希
  5. 列表
  6. 集合
  7. 有序集合
  8. 通用命令

1、安装模块

首先需要安装一下用到的第三方库:

go get github.com/go-redis/redis/v8

2、连接 Redis

接下来连接 Redis 并测试连接情况,如下是代码:

package main

import (
"context"
"fmt" "github.com/go-redis/redis/v8"
) var ctx = context.Background() func GetRedisClient() *redis.Client {
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
}) pong, err := redisClient.Ping(ctx).Result()
if err != nil {
fmt.Println("连接失败: ", err)
return nil
}
fmt.Println("连接成功: ", pong)
return redisClient
}

3、字符串

1. 字符串写入

字符串写入 Redis 的操作如下:

redisClient.Set(ctx, key, value, expire)

ctx 是 context 上下文,keyvalue 是需要设置的键和值,expire 是一个 time.Duration 类型,表示过期时间,如果设为小于等于 0 则表示永不过期。

下面是字符串写入 Redis 的使用示例:

func SetString(redisClient *redis.Client, ctx context.Context, key, value string, expire time.Duration) error {
err := redisClient.Set(ctx, key, value, expire).Err()
if err != nil {
fmt.Println("设置失败: ", err)
return err
}
fmt.Println("设置成功")
return nil
} func main(){
redisClient := GetRedisClient()
defer redisClient.Close()
ctx := context.Background()
key := "test_key"
value := "test_value"
err := SetString(redisClient, ctx, key, value, 10*time.Second)
if err != nil {
fmt.Printf("key:%s set value:%s, error:%v\n", key, value, err)
}
}

2. 字符串读取

从 Redis 中读取字符串的操作如下:

val, err := redisClient.Get(ctx, key).Result()

其中,val 为返回的值,err 表示读取过程中是否有错误。

这里需要注意下,如果对应的 key 没有值,也会返回 error,其结果是 redis.Nil,可以做一下单独的判断处理。

下面是一个使用示例:

func main(){
redisClient := GetRedisClient()
ctx := context.Background()
key := "test_key" val, err := redisClient.Get(ctx, key).Result()
if err != nil {
if err == redis.Nil {
fmt.Printf("key:%s, has no value\n", key)
} else {
fmt.Printf("get key:%s, error: %v\n", key, err)
}
}
fmt.Printf("key:%s, value:%s\n", key, val)
}

4、哈希

1. 写入

1) 单字段写入

哈希类型的数据单个字段写入的操作如下:

val, err := redisClient.HSet(ctx, key, field, value).Result()

这里返回的 val 类型是 int64,值表示设置成功写入的数量,HSet() 方法这里介绍的是单字段写入,后面再介绍多字段写入。

使用代码示例如下:

func HSetField(redisClient *redis.Client, ctx context.Context, key, field, value string) {
val, err := redisClient.HSet(ctx, key, field, value).Result()
if err != nil {
fmt.Println("哈希单个字段设置错误: ", err)
} else {
if val == 1 {
fmt.Println("哈希单个字段设置成功:", val)
} else {
fmt.Println("哈希单个字段更新成功:", val)
}
}
} func main() {
redisClient := GetRedisClient()
defer redisClient.Close() ctx := context.Background()
key := "test_hash_key" HSetField(redisClient, ctx, key, "field1", "value1")
}
2) 多字段写入

多字段写入可以使用 HMSet() 操作,但 HSet() 也支持多字段写入。

HMSet() 操作是一个已弃用的版本,为了兼容 Redis 3 版本。

HSet() 操作只有 Redis 4 及以上才支持多字段的写入。

使用 HMSet() 的代码的几种操作如下:

// 操作 1
val, err := redisClient.HMSet(ctx, key, "field1", "value1", "field2", "value2").Result() // 操作2
field_value_slice := []string{"field1", "value1", "field2", "value2"}
val, err := redisClient.HMSet(ctx, key, field_value_slice).Result() // 操作3
m := map[string]interface{}{"field1": "value1", "field2": "value2"}
val, err := redisClient.HMSet(ctx, key, m).Result()

这里支持输入的操作包括直接使用多个字符串,切片和 map,返回的结果 val 是 bool 类型,表示是否设置成功。

HSet() 支持的参数与 HMSet() 完全相同,但是返回的 val 是一个 int64,表示成功写入的字段数量。

以下是 HSet() 的操作示例:

// 操作 1
val, err := redisClient.HSet(ctx, key, "field1", "value1", "field2", "value2").Result() // 操作2
field_value_slice := []string{"field1", "value1", "field2", "value2"}
val, err := redisClient.HSet(ctx, key, field_value_slice).Result() // 操作3
m := map[string]interface{}{"field1": "value1", "field2": "value2"}
val, err := redisClient.HSet(ctx, key, m).Result()

这里返回的 val 是 int64 类型,表示成功写入数据的数量,如果更新字段,字段数量不会计入。

2. 读取

1) 单字段读取

哈希数据单个字段的读取用 HGet() 操作:

val, err := redisClient.HGet(ctx, key, field).Result()

获取的 val 就是对应字段的值。

这里有两种特殊情况,一种是 key 不存在,一种是 field 不存在。

key 或者 field 不存在和之前的字符串读取的 err 的值一样,是 redis.Nil

代码操作示例如下:

func HGetField(redisClient *redis.Client, ctx context.Context, key, field string) {
val, err := redisClient.HGet(ctx, key, field).Result()
if err != nil {
if err == redis.Nil {
fmt.Println("key 或者 field 不存在")
} else {
fmt.Println("哈希单个字段获取错误: ", err)
}
} else {
fmt.Println("哈希单个字段获取成功:", val)
}
fmt.Printf("%T, %v\n", val, val)
} func main() {
redisClient := GetRedisClient()
defer redisClient.Close() ctx := context.Background()
key := "test_hash_key" HGetField(redisClient, ctx, key, "field1")
}
2) 多字段读取

获取多个字段值

指定多个字段读取哈希数据用 HMGet() 操作,需要读取的多个 field 可以直接作为参数加在后面,也可以使用切片传入:

val, err := redisClient.HMGet(ctx, key, "field1", "field2", "field3", "field4").Result()

fields := []string{"field1", "field2", "field3", "field14"}
val, err := redisClient.HMGet(ctx, key, fields...).Result()

其返回的 val 是一个 []interface 结构,其中每个元素都是对应的 field 的 value,比如上面的操作结果如下:

[value11 value12 value2 <nil>]

对应的 field 没有 value 的话,其值就是 nil

在获取对应的 value 进行处理的时候需要转一下:

val[0].(string)

获取全部字段和值

如果想获取 key 下全部的 field 和对应的 value,可以使用 HGetAll(),其操作如下:

val := redisClient.HGetAll(ctx, key).Val()

返回的 val 类型是 map[string]string

fmt.Println(val)
// map[field1:value11 field2:value12 field3:value2]

获取全部字段

获取哈希数据下全部的 field 的操作如下:

fieldSlice := redisClient.HKeys(ctx, key).Val()

返回的数据是一个字符串切片 []string,如果对应的 key 没有数据,返回的结果是空的字符串切片。

获取全部值

获取哈希数据下全部 field 对应的 value 的操作如下:

valueSlice := redisClient.HVals(ctx, key).Val()

返回的数据是一个字符串切片 []string,如果 key 下没有数据,返回的结果是空的字符串切片。

获取字段长度

获取哈希数据下有多少个 field 的操作如下:

fieldLength := redisClient.HLen(ctx, key).Val()

返回的结果是一个 int64 类型。

3. 删除字段

如果要删除哈希数据下某一个或多个 field,可以使用 HDel() 方法。

// 删除一个 field
val := redisClient.HDel(ctx, key, "field1").Val() // 删除多个 field
val := redisClient.HDel(ctx, key, "field1", "field2", "field3").Val() // 删除多个 field
fieldSlice := []string{"field1", "field2"}
val := redisClient.HDel(ctx, key, fieldSlice...).Val()

返回的 val 是 int64 类型,表示删除了多少个 field。

4. 检查字段是否存在

HExists() 方法可以用于检测某个字段是否存在。

val := redisClient.HExists(ctx, key, "field1").Val()

返回的结果是一个 bool 型,表示是否存在。

5、列表

1. 数据写入

1) RPush-从列表右边写入

RPush() 方法支持从列表右边写入一个或多个数据,使用示例如下:

// 右边推入一条数据
res := redisClient.RPush(ctx, key, "a").Val() // 右边推入多条数据
res := redisClient.RPush(ctx, key, "a", "b", "c").Val() // slice 形式推入多条数据
stringSlice := []string{"a", "b", "c"}
res := redisClient.RPush(ctx, key, stringSlice).Val()

返回的结果是一个 int64 类型,表示数据推入列表后,列表当前一共有多少个元素。

如果是从左边推入,则使用对应的 LPush() 方法。

注意: 这里需要注意一下从左边推入和右边推入的元素顺序,比如通用的是 ["a", "b", "c"],从右边推入的结果是 ["a", "b", "c"],但是从左边推入的结果是 ["c", "b", "a"]

还有个 LPushXRPushX 方法,表示仅当有 key 这个列表的时候可以写入数据,如果 key 不存在,则不会写入数据。

2) LInsert-在指定元素位置前后插入

LInsert() 方法支持在指定元素的前后插入一条数据,比如原始的列表数据是 ["a", "b", "c"],想要元素 b 前面插入一个元素,其操作如下:

res := redisClient.LInsert(ctx, key, "before", "b", "before_b").Val()

插入成功后列表的元素就会变成 ["a", "before_b", "b", "c"]

LInsert() 方法的第三个参数是可选的,可选值有 beforeafter 分别表示在指定元素的前面还是后面插入。

第四个参数是指定的元素,第五个参数是需要插入的元素。

方法的返回值是个 int64,表示插入成功后当前列表的元素总数。

而如果第四个参数指定的元素不存在,那么将找不到插入的位置,则会插入失败,返回的 res 的值就会是 -1,可以通过这个返回值监控是否插入成功。

3) LInsterBefore/LInsterAfter-在指定元素位置前/后插入

LInsterBefore()LInsterAfter() 则是 LInsert() 方法的指定版本,直接在方法层面确认了在指定元素前还是后插入元素。

比如在元素 c 前插入元素:

res := redisClient.LInsertBefore(ctx, key, "c", "before_c").Val()

返回的 res 是 int64,表示插入后当前列表的元素总和。

而如果指定的元素不存在,则会返回 -1。

2. 数据查看

1) LRange-指定范围查看数据

可以通过 LRange() 方法指定索引的范围来查看列表数据:

valueSlice, err := redisClient.LRange(ctx, key, 0, 1).Result()

输入的参数后两个为开始和结束索引,上面这个示例表示获取从 0 到 1 的闭区间列表数据。

返回两个值,valueSlice 是一个字符串切片,err 表示返回的错误

下面是使用示例:

valueSlice, err := redisClient.LRange(ctx, key, 0, 1).Result()
if err != nil {
fmt.Println("error: ", err)
} else {
fmt.Printf("%T, %v\n", valueSlice, valueSlice)
}

与之前的获取逻辑不太一样的地方是,如果 key 对应的列表数据不存在,err 值还是为 nil,只是返回的 valueSlice 是一个长度为 0 的字符串切片。

如果结束位置的索引大于列表的长度,也不会报错,而是会返回全部的列表数据。

而如果我们直接想获取全部的列表数据,可以把结束位置的索引值变成 -1:

valueSlice, err := redisClient.LRange(ctx, key, 0, -1).Result()
2) LIndex-指定索引查看数据

使用示例如下:

value, err := redisClient.LIndex(ctx, key, 1).Result()

返回的结果 value 为指定位置的元素。

LIndex() 方法支持负数索引,比如想获取倒数第二个元素可以如下操作:

value, err := redisClient.LIndex(ctx, key, -1).Result()

而如果指定的索引位置超出了列表的长度,则 err 信息会是 redis.Nil,下面是操作示例:

value, err := redisClient.LIndex(ctx, key, 8).Result()
if err != nil {
if err == redis.Nil {
fmt.Println("索引位置的结果不存在")
} else {
fmt.Println("error: ", err)
}
} else {
fmt.Printf("%T, %v\n", value, value)
}
3) LLen-查看列表长度

使用示例如下:

value := redisClient.LLen(ctx, key).Val()

返回的结果是一个 int64,表示列表长度,而过 key 不存在,则会返回 0。

3. 数据删除与修改

1) LPop-弹出最左边的元素

LPop() 方法的作用是弹出最左边的元素,操作示例如下:

val, err := redisClient.LPop(ctx, key).Result()

其中 val 是弹出的元素,是 string 类型。

如果列表已经为空,err 的值就是 redis.Nil

同理,如果是想弹出最右边的元素,可以使用 RPop() 方法。

2) LPopCount-从左边弹出指定数量的元素

使用示例如下:

val, err := redisClient.LPopCount(ctx, key, 5).Result()

返回的 val 是一个 []string,如果指定的 count,也就是第三个参数大于列表中的元素个数,则会将元素全部弹出。

如果列表中已经没有元素可以弹出了,err 的值是 redis.Nil

3) LRem-遍历删除指定个数的指定元素

其操作方法如下:

val, err := redisClient.LRem(ctx, key, 2, "c").Result()

上面的操作表示从列表左边开始删除 key 对应的列表中两个元素为 c 的元素,返回的 val 表示实际删除的个数。

如果我们想删除全部指定元素,可以将第三个参数设置为 0:

val, err := redisClient.LRem(ctx, key, 0, "c").Result()

上面的操作表示删除列表中全部元素为 c 的数据。

4) LTrim-按照索引范围修剪列表

操作代码如下:

val, err := redisClient.LTrim(ctx, key, 0, 2).Result()

上面的操作表示只保留列表中 0 到 2 的索引的三个元素,返回的 val 是 string 类型,内容为 OK 表示修剪成功。

5) LSet-指定位置修改元素

LSet() 方法表示修改指定位置的元素内容,比如需要修改索引为 1 的元素内容:

val, err := redisClient.LSet(ctx, key, 1, "index_1_change").Result()

返回的 val 是个字符串,内容 OK 表示修改成功,如果指定的索引超出了原有列表的范围,则会返回 err。

6、集合

1. 写入数据

往一个集合中写入的方法是 SAdd(),可以往里面写入单个或者多个元素:

// 写入单个元素
val := redisClient.SAdd(ctx, key, "a").Val() // 写入多个元素
stringSlice := []string{"d", "e"}
val := redisClient.SAdd(ctx, key, stringSlice).Val()

返回的结果 val 是 int64,表示写入的元素个数,如果元素之前已经在集合,则不会计入其中。

2. 读取数据

1) SMembers-获取集合全部元素

使用代码如下:

res, err := redisClient.SMembers(ctx, key).Result()

返回的 res 是一个 []string,内容为集合的全部元素。

如果 key 对应的集合不存在,返回的 res 为空切片。

2) SCard-获取集合元素总数

使用代码如下:

res, err := redisClient.SCard(ctx, key).Result()

返回的 res 类型是 int64,内容是 key 对应的集合的元素总数。

如果 key 对应的集合不存在,返回的 res 结果是 0。

3) SRandMember-随机取出集合中元素

使用代码如下:

res, err := redisClient.SRandMember(ctx, key).Result()
if err == redis.Nil {
fmt.Printf("key:%s 对应的集合不存在\n", key)
}

返回的 res 是集合中随机一个元素。

如果 key 对应的集合不存在,返回 err 的值是 redis.Nil

4) SRandMemberN-随机取出集合中 N 个元素

使用代码如下:

res, err := redisClient.SRandMemberN(ctx, key, 3).Result()

上面的代码表示从集合中随机取出 3 个元素,返回的 res 是 []string

如果 key 对应的集合不存在,返回的是一个空切片,err 为 nil

如果指定返回的元素个数大于集合总个数,则会返回全部集合元素。

3. 删除元素

1) SRem-移除指定元素

SRem() 方法可以用于移除指定的一个多个元素,使用示例如下:

// 删除一个指定元素
res, err := redisClient.SRem(ctx, key, "a").Result() // 删除多个指定元素
res, err := redisClient.SRem(ctx, key, "a", "b").Result() stringSlice := []string{"a", "b"}
res, err := redisClient.SRem(ctx, key, stringSlice).Result()

返回的结果 res 是一个 int64,表示移除的元素个数。

2) SPop-移除随机元素

SPop() 方法用于随机移除集合中的元素。

res, err := redisClient.SPop(ctx, key).Result()

res 是返回的移除的元素。

SPopN() 用于移除 N 个随机元素:

res, err := redisClient.SPopN(ctx, key, 2).Result()

返回的 res 是一个 []string

4. 集合间操作

1) SDiff-集合差集

SDiff() 方法用于求取集合之间的差集,使用示例如下:

redisClient.SAdd(ctx, "s1", "a", "b", "c")
redisClient.SAdd(ctx, "s2", "a") res, err := redisClient.SDiff(ctx, "s1", "s2").Result()

返回的 res 是一个 []string,是集合之间的差集。

SDiffStore() 可以将集合间的差集存储到一个新的 key 中,使用方法如下:

redisClient.SDiffStore(ctx, "s3", "s1", "s2")

上面的操作表示将 s1 和 s2 之间的差集存储到 s3 中。

2) SInter-集合交集

SInter() 方法用于求取集合之间的交集,使用示例如下:

redisClient.SAdd(ctx, "s1", "a", "b", "c")
redisClient.SAdd(ctx, "s2", "a") res, err := redisClient.SInter(ctx, "s1", "s2").Result()

返回的 res 是一个 []string,是集合之间的交集。

SInterStore() 可以将集合间的交集存储到一个新的 key 中,使用方法如下:

redisClient.SInterStore(ctx, "s3", "s1", "s2")

上面的操作表示将 s1 和 s2 之间的交集存储到 s3 中。

3) SUnion-集合并集

SUnion() 方法用于求取集合之间的并集,使用示例如下:

redisClient.SAdd(ctx, "s1", "a", "b", "c")
redisClient.SAdd(ctx, "s2", "a", "e") res, err := redisClient.SUnion(ctx, "s1", "s2").Result()

返回的 res 是一个 []string,是集合之间的并集。

SUnionStore() 可以将集合间的并集存储到一个新的 key 中,使用方法如下:

redisClient.SUnionStore(ctx, "s3", "s1", "s2")

上面的操作表示将 s1 和 s2 之间的并集存储到 s3 中。

7、有序集合

1. 数据写入

有序集合数据的写入可以使用 ZAdd(),使用的示例如下:

res, err := redisClient.ZAdd(ctx, key, &redis.Z{Score: 100, Member: "Golang"}).Result()

输入的第三个参数是 redis.Z 类型,其结构如下:

type Z struct {
Score float64
Member interface{}
}

Score 是元素用于排序的分数,Member 是有序集合的元素。

除了单个元素,还可以写入多个元素:

zList := []*redis.Z{
{Score: 101, Member: "Golang"},
{Score: 221, Member: "Python"},
{Score: 445, Member: "Java"},
}
res, err := redisClient.ZAdd(ctx, key, zList...)

返回的 res 类型是 int64,表示插入数据的个数。

2. 数据查询

1) ZRangeWithScores-返回指定排序范围的分值和元素

ZRangeWithScores() 方法用于返回指定排序范围的分值和元素,比如需要返回前三位的数据,使用示例如下:

res1, err := redisClient.ZRangeWithScores(ctx, key, 0, 2).Result()
for _, item := range res1 {
fmt.Printf("score:%f, member:%s\n", item.Score, item.Member)
}

其返回的 res1 类型是 []Z,数据按照 score 从小到大排列。

如果想要获取有序集合中全部元素,可以将指定的范围写成 0 和 -1:

res1, err := redisClient.ZRangeWithScores(ctx, key, 0, -1).Result()

通过,有一个逆序方法 ZRevRangeWithScores(),比如获取从最后往前三位的数据:

res1, err := redisClient.ZRangeWithScores(ctx, key, 0, 2).Result()
2) ZRange-返回指定排序范围的元素

ZRange() 方法用于返回指定排序范围的元素,,比如需要返回前三位的数据,使用示例如下:

res1, err := redisClient.ZRange(ctx, key, 0, 2).Result()

返回的 res1 类型是 []string,元素是有序集合的元素,按照 score 从小到大排列。

如果想要获取有序集合中全部元素,可以将指定的范围写成 0 和 -1。

同理,有一个逆序的获取方法 ZRevRange(),比如获取从最后往前三位的数据,操作如下:

res1, err := redisClient.ZRevRange(ctx, key, 0, 2).Result()
3) ZRangeByScore-返回指定 score 分值范围排序的元素

ZRangeByScore 传入的参数是 redis.ZRangeBy,其数据结构如下:

type ZRangeBy struct {
Min, Max string
Offset, Count int64
}

MinMax 表示 score 分值的范围,如果想获取这个范围内的全部元素,OffsetCount 参数置为 0 即可。

如果想要获取类似分页的操作,可以对 OffsetCount 进行赋值,Count 表示需要获取的总数,Offset 表示从 Min 开始的偏移量。

使用示例如下:

zRangeBy := &redis.ZRangeBy{
Min: "1",
Max: "500",
}
res1, err := redisClient.ZRangeByScore(ctx, key, zRangeBy).Result()

上面的示例表示获取 key 对应的有序集合 score 从 1 到 500 之间的全部元素,返回的 res1 类型是 []string

其对应的逆序获取方法为 ZRevRangeByScore(),操作示例如下:

res1, err := redisClient.ZRevRangeByScore(ctx, key, zRangeBy).Result()
4) ZScore-返回指定元素的 score

使用示例如下:

elementName := "Golang"
res1, err := redisClient.ZScore(ctx, key, elementName).Result()
if err != nil {
if err == redis.Nil {
fmt.Printf("key:%s 或者元素: %s 不存在\n", key, elementName)
} else {
fmt.Println("err: ", err)
}
} else {
fmt.Printf("key:%s, 元素:%s 的分值是%f\n", key, elementName, res1)
}

返回的 res1 类型是 float64,表示指定元素的 score,如果 key 或者指定的元素不存在,err 的值是 redis.Nil

另一个方法 ZMScore() 可以获取多个指定元素的 score:

elementSlice := []string{"Golang", "Python"}
res1, err := redisClient.ZMScore(ctx, key, elementSlice...).Result()

返回的 res1 是一个 []float64,返回的是对应的 elementSlice 对应位置元素的 score。

如果元素不存在,则对应的位置会返回 0。

5) ZRank-返回指定元素的排序数

使用代码示例如下:

elementName := "Golang"
res1, err := redisClient.ZRank(ctx, key, elementName).Result()
if err != nil {
if err == redis.Nil {
fmt.Printf("key:%s 或者元素: %s 不存在\n", key, elementName)
} else {
fmt.Println("err: ", err)
}
} else {
fmt.Printf("key:%s, 元素:%s 的排序是%d\n", key, elementName, res1)
}

返回的 res1 类型是 int64,表示指定元素的排序数,排序数从 0 开始,如果 key 或者指定的元素不存在,err 的值是 redis.Nil

ZRevRank() 方法表示逆序获取,使用方法和 ZRank() 方法一致:

res1, err := redisClient.ZRevRank(ctx, key, elementName).Result()
6) ZCard-返回指定 key 的元素总数

使用示例如下:

res1, err := redisClient.ZCard(ctx, key).Result()

ZCard() 方法返回指定 key 的元素总数,res1 类型是 int64,表示指定 key 的元素总数。

如果对应的 key 不存在,结果为 0,err 为 nil

7) ZCount-返回 key 指定 score 范围的元素总数

使用示例如下:

res1, err := redisClient.ZCount(ctx, key, "1", "4").Result()

ZCount() 方法输入的第三、四个参数是 score 分值的最小和最大值,类型是字符串。

返回的 res1 类型是 int64,如果 key 不存在,结果为 0。

3. 删除操作

1) ZRem-指定元素删除

ZRem() 方法用于有序集合指定元素删除操作,可以删除一个或多个元素:

res1, err := redisClient.ZRem(ctx, key, []string{"Java", "Golang"}).Result()

返回的 res1 类型是 int64,表示删除的元素个数。

2) ZRemRangeByScore-删除指定 score 范围内的元素

ZRemRangeByScore() 方法用于删除指定 score 范围内的元素,第三、四个参数是有序集合的 score 的最小值和最大值,类型是 string,使用示例如下:

res1, err := redisClient.ZRemRangeByScore(ctx, key, "0", "23").Result()

上述示例表示删除指定 key 的 score 在 0 到 23 之间的闭区间的元素,res1 类型是 int64,表示删除的元素个数。

3) ZRemRangeByRank-删除指定排序范围内的元素

ZRemRangeByRank() 方法用于删除指定排序范围内的元素,第三、四个参数是有序集合的排序位的范围,类型是 int64,比如向删除有序集合排在前两位的数据,操作如下:

res1, err := redisClient.ZRemRangeByRank(ctx, key, 0, 1).Result()

返回的 res1 类型是 int64,表示删除的元素个数。

4) ZPopMin-按照 score 从有序集合中弹出指定个数的元素

如果想按照 score 从小到大排列,弹出某个有序集合中排在前两位的元素,操作如下:

res1, err := redisClient.ZPopMin(ctx, key, 2).Result()
for _, item := range res1 {
fmt.Println(item.Score, item.Member)
}

返回的 res1 类型是 []Z

而如果想按照 score 从大到小排列并弹出指定个数的元素,可以使用 ZPopMax() 方法,使用方式与 ZPopMin() 方法一致。

8、 通用命令

1. Exists-判断 key 是否存在

Exists() 方法用于判断指定 key 是否存在,使用示例如下:

res, err := redisClient.Exists(ctx, "a").Result()

返回的 res 类型是 int64,如果指定 key 存在,则 res 为 1,否则为 0。

2. Expire-设置过期时间

Expire() 方法用于给指定 key 设置过期时间,使用示例如下:

res1, err := redisClient.Expire(ctx, key, 20*time.Minute).Result()

返回的 res1 类型是 bool,如果 key 存在且设置过期时间成功,返回的 res1 为 true,否则为 false

3. Del-删除 key

Del() 方法用于删除一个或多个 key,使用示例如下:

// 删除一个 key
res1, err := redisClient.Del(ctx, "d").Result() // 删除多个 key
res1, err := redisClient.Del(ctx, []string{"a", "b", "c"}...).Result()

返回的 res1 类型是 int64,表示删除的 key 的个数。

4. TTL-查看过期时间

TTL() 方法用于查看指定 key 的过期时间,使用示例如下:

res1, err := redisClient.TTL(ctx, "a").Result()
if err != nil {
fmt.Println("error: ", err)
return
}
if res1 == -1 {
fmt.Println("指定 key 永不过期")
} else if res1 == -2 {
fmt.Println("指定 key 不存在")
} else {
fmt.Println("key 在指定时间后过期: ", res1)
}

Golang笔记之Redis的更多相关文章

  1. golang中使用Redis

    一.golang中安装Redis github地址:https://github.com/garyburd/redigo 文档地址:http://godoc.org/github.com/garybu ...

  2. golang笔记1

    golang笔记1 go代码是用包来组织的,每个包有一个或多个go文件组成,这些go文件文件放在一个文件夹中 每个源文件开始都用一个package声明,指明本源文件属于哪个包 pakage声明后紧跟这 ...

  3. Golang笔记(二)面向对象的设计

    Golang笔记(二)面向对象的设计 Golang本质还是面向过程的语言,但它实现了一些OOP的特性,包括抽象.封装.继承和多态. 抽象和封装 Golang和C语言一样以struct为数据结构核心,不 ...

  4. Golang笔记(一)简洁的语言风格

    Golang笔记(一)简洁的语言风格 概述 Golang继承了很多C语言的风格,寡人使用了十几年C语言,切换到Golang时上手很快,并且随着深入的使用,越来越喜欢这门语言.Golang最直观的感受是 ...

  5. 笔记-数据库-redis

    笔记-数据库-redis 1.      redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 stri ...

  6. 杂文笔记《Redis在万亿级日访问量下的中断优化》

    杂文笔记<Redis在万亿级日访问量下的中断优化> Redis在万亿级日访问量下的中断优化 https://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA= ...

  7. [Go] golang定时器与redis结合

    golang定时器与redis结合,每隔1秒ping一下,每隔20秒llen一下队列的长度 package main import ( "fmt" "time" ...

  8. SpringBoot学习笔记:Redis缓存

    SpringBoot学习笔记:Redis缓存 关于Redis Redis是一个使用ANSI C语言编写的免费开源.支持网络.可基于内存亦可以持久化的日志型.键值数据库.其支持多种存储类型,包括Stri ...

  9. redis相关笔记(三.redis设计与实现(笔记))

    redis笔记一 redis笔记二 redis笔记三 1.数据结构 1.1.简单动态字符串: 其属性有int len:长度,int free:空闲长度,char[] bur:字符数组(内容) 获取字符 ...

  10. spring boot 自学笔记(四) Redis集成—Jedis

    上一篇笔记Reddis集成,操作Redis使用的是RedisTemplate,但实际中还是有一大部分人习惯使用JedisPool和Jedis来操作Redis, 下面使用Jedis集成示例. 修改Red ...

随机推荐

  1. XXL-MQ v1.4.0 | 轻量级分布式消息队列

    Release Notes 1.[重构]XXL-MQ 核心代码重构,基于"存算分离"与"分区机制"设计思想.在轻量级.分布式的基础上,强化高吞吐.海量消息及水平 ...

  2. java springboot api接口导出xlsx(不使用easyexcle)

    说明 在上一个文章里说了,用了阿里巴巴的easyexcle会导致项目build后的jar包体积增大20MB左右,所以想了个曲线救国的方式 其中的\t是制表符,即tab键,\n是回车 你可以自己试着这样 ...

  3. 【转载】数论学习笔记(Blog of tyqtyq)

    from a famous oier \(\texttt{tyqtyq}\)请点链接tyqtyq~! - 博客园 (cnblogs.com) 数论分块 \(\sum_{i=1}^{n} \lfloor ...

  4. 【中英】【吴恩达课后测验】Course 4 -卷积神经网络 - 第四周测验

    [中英][吴恩达课后测验]Course 4 -卷积神经网络 - 第四周测验 - 特殊应用:人脸识别和神经风格转换 上一篇:[课程4 - 第三周编程作业]※※※※※ [回到目录]※※※※※下一篇:[待撰 ...

  5. k8s pod command使用

    简单说明 我们启pod服务时,有时需要在服务启动前做一些初始化的工作,这里可能会涉及多个shell命令以及判断执行,这里可以参考下面的步骤进行: command: ["/bin/bash&q ...

  6. 写Leetcode 对业务代码是帮助的

    业务中遇到的表结构以及场景如下: id name pid 1 A 0 2 A 1 3 A 2 4 B 0 5 B 4 6 B 5 7 C 0 8 D 7 9 E 8 是一个层级结构,名字可能相同,也可 ...

  7. Java集合--LinkedList源码可视化

    集合节点保存的都是对象的引用,而非具体值,文中案例仅仅为了方便实现原理的演示. 1. 底层数据结构 LinkedList 基于 双向链表 实现,内部通过 Node<E> 节点相互连接: p ...

  8. ArkUI-X跨平台应用改造指南

    现状与诉求 随着 HarmonyOS Next 5.0 版本正式发布,众多开发者基于 ArkTS 语言为 HarmonyOS Next 系统开发了大量应用,这极大地丰富了 HarmonyOS 的生态. ...

  9. sql注入绕过某waf

    简单布尔判断 直接输入and 1=1拦截 使用mysql黑魔法 and{a 1=1} and{a 1=2}不拦截 本地mysql测试语句正常执行 简单延时判断 and sleep(1) 简单测试后在( ...

  10. MongoDB入门实战教程(13)

    MongoDB的一大特色就在于其原生的横向扩展能力,具体体现就是分片集.本篇,我们来了解一下MongoDB分片集的机制及其原理. 1 为什么要分片? 我们都知道,在关系型数据库如MySQL中,当数据量 ...