字符串命令
以下指令仅对string类型的key有效
键指令 | 作用 | 例子 | 返回值 | 序号 |
---|---|---|---|---|
SET | 设置指定 key 的值 | SET KEY_NAME VALUE | 在 Redis 2.6.12 以前版本, SET 命令总是返回 OK 。从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK | 0 |
GET | 获取指定 key 的值 | GET KEY_NAME | 返回 key 的值,如果 key 不存在时,返回 nil。 如果 key 不是字符串类型,那么返回一个错误 | 1 |
GETRANGE | 返回 key 中字符串值的子字符 | GETRANGE KEY_NAME start end | 截取得到的子字符串 | 2 |
GETSET | 将给定 key 的值设为 value ,并返回 key 的旧值(old value) | GETSET KEY_NAME VALUE | 返回给定 key 的旧值。 当 key 没有旧值时,即 key 不存在时,返回 nil 。 当 key 存在但不是字符串类型时,返回一个错误 | 3 |
GETBIT | 对 key 所储存的字符串值,获取指定偏移量上的位(bit) | GETBIT KEY_NAME OFFSET | 字符串值指定偏移量上的位(bit)。 当偏移量 OFFSET 比字符串值的长度大,或者 key 不存在时,返回 0 | 4 |
MGET | 获取所有(一个或多个)给定 key 的值 | MGET KEY1 KEY2 .. KEYN | 一个包含所有给定 key 的值的列表 | 5 |
SETBIT | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit) | Setbit KEY_NAME OFFSET | 指定偏移量原来储存的位 | 6 |
SETEX | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位) | SETEX KEY_NAME TIMEOUT VALUE | 设置成功时返回 OK | 7 |
SETNX | 只有在 key 不存在时设置 key 的值 | SETNX KEY_NAME VALUE | 设置成功,返回 true 。 设置失败,返回 false | 8 |
SETRANGE | 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始 | SETRANGE KEY_NAME OFFSET VALUE | 被修改后的字符串长度 | 9 |
STRLEN | 返回 key 所储存的字符串值的长度 | STRLEN KEY_NAME | 字符串值的长度。 当 key 不存在时,返回 0 | 10 |
MSET | 同时设置一个或多个 key-value 对 | MSET key1 value1 key2 value2 .. keyN valueN | 总是返回 OK | 11 |
MSETNX | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在 | MSETNX key1 value1 key2 value2 .. keyN valueN | 当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(如果有一个 key 已经存在),那么返回 0 | 12 |
PSETEX | 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位 | PSETEX key1 EXPIRY_IN_MILLISECONDS value1 | 设置成功时返回 OK | 13 |
INCR | 将 key 中储存的数字值增一 | INCR KEY_NAME | 执行 INCR 命令之后 key 的值 | 14 |
INCRBY | 将 key 所储存的值加上给定的增量值(increment) | INCRBY KEY_NAME INCR_AMOUNT | 加上指定的增量值之后, key 的值 | 15 |
INCRBYFLOAT | 将 key 所储存的值加上给定的浮点增量值(increment) | INCRBYFLOAT KEY_NAME INCR_AMOUNT | 执行命令之后 key 的值 | 16 |
DECR | 将 key 中储存的数字值减一 | DECR KEY_NAME | 执行命令之后 key 的值 | 17 |
DECRBY | key 所储存的值减去给定的减量值(decrement) | DECRBY KEY_NAME DECREMENT_AMOUNT | 减去指定减量值之后, key 的值 | 18 |
APPEND | 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾 | APPEND KEY_NAME NEW_VALUE | 追加指定值之后, key 中字符串的长度 | 19 |
BITCOUNT | 用来获取 key 的值中二进制是 1 的个数 | BITCOUNT KEY_NAME [start] [end] | key 的值中二进制是 1 的个数 | 20 |
BITFIELD | 在一次调用中同时对多个位范围进行操作:它接受一系列待执行的操作作为参数,并返回一个数组,数组中的每个元素就是对应操作的执行结果 | BITFIELD KEY_NAME [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] | 命令的返回值是一个数组,数组中的每个元素对应一个被执行的子命令。需要注意的是,OVERFLOW 子命令本身并不产生任何回复 | 21 |
BITPOS | 查找字符串中第一个设置为1或0的bit位 | BITPOS KEY_NAME bit [start] [end] |
代码实践
SET
// -1 永不过期
//err := RedisClient.Set(ctx,"keyName","0000",-1).Err()
err := RedisClient.Set(ctx,"keyName","0000",100*time.Second).Err() // 100秒有效期
if err != nil{
logrus.Error(err)
return
}
GET
result, err := RedisClient.Get(ctx, "name101").Result()
if err != nil {
logrus.Error(err)
return
}
logrus.Info("结果为->",result)
如果get的key不是string类型,则报错如下
ERRO[0000] WRONGTYPE Operation against a key holding the wrong kind of value
GETRANGE
result, err := RedisClient.GetRange(ctx, "name101", 1, 2).Result() // value为hello,结果是 "el"
if err != nil {
logrus.Error(err)
return
}
logrus.Info(result)
GETSET
result, err := RedisClient.GetSet(ctx, "name101", "value").Result()
if err != nil {
logrus.Error(err)
return
}
logrus.Info("原来的key为->", result) // 返回原来key的值
GETBIT
result, err := RedisClient.GetBit(ctx, "SetBitKey", 123123).Result()
if err != nil {
logrus.Error(err)
return
}
logrus.Infof("Key: SetBitKey |offset: %d |value: %v",123123,result)
result, err = RedisClient.GetBit(ctx, "SetBitKey", 12313).Result()
if err != nil {
logrus.Error(err)
return
}
logrus.Infof("Key: SetBitKey |offset: %d |value: %v",12313,result)
MGET
keys := []string{"name267","name102","name795","name302"}
result, err := RedisClient.MGet(ctx, keys...).Result()
if err != nil {
logrus.Error(err)
return
}
logrus.Info("value列表为->",result) // value的顺序和key的顺序保持一致
SETBIT
offset
参数必须大于或等于 0
,小于 2^32 (bit 映射被限制在 512 MB 之内)。对使用大的 offset
的 SETBIT 操作来说,内存分配可能造成 Redis 服务器被阻塞
result, err := RedisClient.SetBit(ctx, "SetBitKey", 123123, 1).Result()
err = RedisClient.SetBit(ctx, "SetBitKey", 12313, 0).Err()
if err != nil {
logrus.Error(err)
return
}
logrus.Info(result)
使用场景
http://neosu.info/posts/redis-bitmap.html#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF
-
场景:统计每天有多少活跃用户,或者有多少用户连续几天活跃。
使用日期作为key,用户id作为offset,如何活跃了就把bitmap二进制位设置成1。
127.0.0.1:6379> setbit active_20220503 {userID} 1 // 使用日期作为key,用户id作为offset 127.0.0.1:6379> bitcount active_20200509 // 某天的活跃用户
-
场景:用户在线状态
场景:提供接口查询用户是否在线(有上线和下线)
把用户id作为偏移量offset,在线就设置成1,不在线就设置成0。
127.0.0.1:6379> setbit online {userID} 1 //设置用户上线 127.0.0.1:6379> setbit online 9 0 //设置用户ID为9下线 127.0.0.1:6379> getbit online 9 // 查询用户ID为9在线状态 127.0.0.1:6379> bitcount online // 查询当前所有在线用户数量
-
场景:记录每个用户的签到记录
https://www.cnblogs.com/liang24/p/14449835.html
考虑到每月要重置连续签到次数,最简单的方式是按用户每月存一条签到数据。Key的格式为
u:sign:{uid}:{yyyMM}
,而Value则采用长度为4个字节的(32位)的BitMap(最大月份只有31天)。BitMap的每一位代表一天的签到,1表示已签,0表示未签。例如
u:sign:1225:202101
表示ID=6667的用户在2021年1月的签到记录# 用户1月6号签到 127.0.0.1:6379> setbit u:sign:6667:202101 5 1 # 偏移量是从0开始,所以要把6减1 # 检查1月6号是否签到 127.0.0.1:6379> getbit u:sign:6667:202101 5 # 偏移量是从0开始,所以要把6减1 # 统计1月份的签到次数 127.0.0.1:6379> bitcount u:sign:6667:202101 # 获取1月份前31天的签到数据 127.0.0.1:6379> BITFIELD u:sign:6667:202101 get u31 0 # 获取1月份首次签到的日期 127.0.0.1:6379> BITPOS u:sign:6667:202101 1 # 返回的首次签到的偏移量,加上1即为当月的某一天
SETEX
res, err := RedisClient.SetEX(ctx, "setExKeyName", "setExKeyName-value", 100*time.Second).Result()
if err != nil {
logrus.Error(err)
}
logrus.Info(res) // ok
SETNX
res, err := RedisClient.SetNX(ctx, "setExKeyName", "setExKeyName-value", 100*time.Second).Result()
if err != nil {
logrus.Error(err)
}
logrus.Info(res) // 设置成功则返回true,否则返回false
SETRANGE
RedisClient.Set(ctx, "demo", "222267 yeah!", -1)
res, err := RedisClient.SetRange(ctx, "demo", 8, "yep!").Result()
if err != nil {
logrus.Error(err)
}
logrus.Info("修改后的字符串长度->", res) // 被修改后的字符串长度
logrus.Info(RedisClient.Get(ctx, "demo"))
STRLEN
res,err := RedisClient.StrLen(ctx,"deasdasmo").Result()
if err != nil{
logrus.Error(err)
}
logrus.Infof("字符串长度为->%d",res) // 返回字符串长度,如果key不存在,则结果为0
MSet
res, err := RedisClient.MSet(ctx, "key1", "222", "key2", "333").Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%s", res) // 总是返回ok
logrus.Info(RedisClient.MGet(ctx, "key1", "key2"))
MSETNX
// 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在才能执行成功
res,err := RedisClient.MSetNX(ctx,"key4","333","key5","333").Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // 当所有 key 都成功设置,返回 true 。 如果所有给定 key 都设置失败(如果有一个 key 已经存在),那么返回 false
logrus.Info(RedisClient.MGet(ctx, "key1", "key2","key5"))
PSETEX
等同于 PExpire
RedisClient.Set(ctx,"key1","sss",-1)
res,err := RedisClient.PExpire(ctx,"key1",time.Millisecond*100000).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res)
INCR
RedisClient.Set(ctx,"key1","66",-1)
res,err := RedisClient.Incr(ctx,"key1").Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错
INCRBY
RedisClient.Set(ctx,"key1","57",-1)
res,err := RedisClient.IncrBy(ctx,"key1",10).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错
IncrByFloat
RedisClient.Set(ctx,"key1","57",-1)
res,err := RedisClient.IncrByFloat(ctx,"key1",10).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // value需要是一个浮点数类型,否则报错
DECR
RedisClient.Set(ctx,"key1","68",-1)
res,err := RedisClient.Decr(ctx,"key1").Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错
DECRBY
RedisClient.Set(ctx,"key1","69",-1)
res,err := RedisClient.DecrBy(ctx,"key1",2).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("写入结果->%v", res) // value需要是一个整数类型,否则报错
APPEND
RedisClient.Set(ctx,"key1","69",-1)
res,err := RedisClient.Append(ctx,"key1","23").Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("追加结果->%v", res) // 6923
logrus.Info(RedisClient.Get(ctx,"key1"))
BITCOUNT
RedisClient.SetBit(ctx,"SetBitKey",6,1)
RedisClient.SetBit(ctx,"SetBitKey",7,1)
count := redis.BitCount{Start: 0, End: -1}
res,err := RedisClient.BitCount(ctx,"SetBitKey",&count).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("二进制是 1 的个数->%v", res) // 2
BITFIELD
todo
BITPOS
RedisClient.SetBit(ctx, "SetBitKey", 6, 1)
RedisClient.SetBit(ctx, "SetBitKey", 7, 1)
logrus.Info(RedisClient.Get(ctx, "SetBitKey"))
res, err := RedisClient.BitPos(ctx, "SetBitKey", 1).Result()
if err != nil {
logrus.Error(err)
}
logrus.Infof("查找字符串中第一个设置为1或0的bit位->%v", res) // 6
docker run -p 9090:9090 -v /Users/adou_mini/Downloads/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
xx
https://www.redis.com.cn/commands/bitfield.html
大哥带带我吧