redis命令详解_redis常用命令大全

(43) 2024-08-27 19:01:01

背景:我记不住那么多命令,又是Linux命令,又是Git命令,又是kubernetes的命令,又是maven命令,又是redis命令。所谓好记性不如烂笔头,记下来吧。

这节我们学习位运算,算是redis我记不住的那些命令完结,后续会更新其他内容。

0. 基础知识(bitmap)

字符串: 从 frank到grank的转换,  f 的ascii码为“0110 0110”,g的ascii码为“0110 0111”,从左到右,从0开始,f和g的差异在于最后的1,所以我们使用setbit name 7 1 ,那我们想grank转换为grcnk呢???  也就是a变成c

127.0.0.1:6379> set name frank OK 127.0.0.1:6379> get name frank 127.0.0.1:6379> setbit name 7 1 0 127.0.0.1:6379> getbit name 7 1 127.0.0.1:6379> get name grank 127.0.0.1:6379> setbit name 22 1 0 127.0.0.1:6379> get name grcnk

这22是怎么算出来的呢?  22 = 2*8+6     a的ascii码为"0110 0001" ,   c的ascii码为“0110 0011”

gr为2*8是16位,而a和c的差异在第6位,所以得出22

二维的例子:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0

我们有一个10*10的矩阵,水平为x坐标,垂直为y坐标,即(x,y)则上述图中1的坐标为 (4,0)、 (4,1)、(4,2) 、(5,2)、 (5,3)、(5,4)、(5,5)、(6,5)  ,而在一个binary string中的偏移量offset是需要进行转换:

       offset = y * max_width + x   ,这里的max_width为10

coordinate坐标 offset偏移量
(4,0) 4
(4,1) 14
(4,2) 24
(5,2) 25
(5,3) 35
(5,4) 45
(5,5) 55
(6,5) 56

我们使用这个二位的矩阵做什么呢?  比如有一个游戏,在二维平面上通过上下左右键进行行走,我们需要记录玩家走的路径和走的步数,那我们如何做呢?  我们可以使用redis的bitwise来进行操作,假设玩家id为2 ,在第3关卡的第4个地图,那么 我们记录这个key为

player:2:episode:3:map:4

这个key标识了某个玩家在某关卡的某个地图的详细信息。

每当玩家走了一步,我们用setbit key offset 1,而bitcount来计算这个玩家走了多少步。

每次从redis中取出玩家的信息,就推算出他的路径和步数。

一. 位运算

0. setbit :   字符串是从左到右,从0开始,二维坐标则是从左到右,从下向上,从0开始

1. getbit : 获取某一个偏移量的值

2. bitcount : 获取二进制字符串的1的个数

3. bitop : 对一个或多个二进制位串执行包括 并and,或or,异或xor,非not,并将结果计算得出保存在dest-key键中

4.  bitpos : 获取第一个 1或0 的偏移量,redis version 7.0版本,格式: bitpos key bit start end  byte|bit   , 7.0版本以下为: bitpos key bit start end

返回值: 当有一个全0的字符串,寻找1则返回 -1

                当有一个全1的字符串,寻找0则返回字符串长度,为什么返回字符串长度? 比如全1字符串的长度为9,索引为0-8,所以从左到右算,0的索引是9,这也是为什么是字符串长度。

                从根本上说,如果你寻找0且没有指定范围或者只有start参数,那么会考虑在字符串的右侧添加0.

                然而,如果你寻找0且指定了范围如start和end。如果在指定的范围内没有找到0,则返回-1

5. bitfield 这个命令其实就是按照你的需求来分配的,可将多个字段存储在一个key中,即一个bitmap中,提升了内存的使用效率,特别是可用于实时的分析。例如你需要一个带符号数5位,位置在第100位到104位, i5 代表是5位有符号整型数字,100代表offset即偏移量(起始位置),15为你所设定的值,15的二进制值为(01111),注意这是补码的值,一定注意。可参考原码,反码和补码(复习)

计算机没有减法都是加法,补码出现不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数,即 5位带符号数(-16,+15)

第二种offset定位的方式是:使用“#”,从0开始,从左到右,这样的好处是不用手动的计算位数并且两个变量是紧紧挨着的。

还有一个是对溢出的控制,分为三种控制溢出的方式即wrap,sat,fail,默认为wrap

wrap是循环,即到了最大值再加1,则为最小值,依次循环。

sat是固定,即到了最大值则不再变化

fail是失败,即到了最大值再加1则此操作失败。

格式为:   bitfield mykey overflow wrap incrby u2  #0  1

bitfield最佳实践: 时序记录数据  ,文中是记录一天之内每分钟的温度,通过8位无符号数字,通过offset “#”进行定位,一分钟的温度所占用一个字节,一天总共占用1.44KB的大小

127.0.0.1:6379> BITFIELD bit-ts SET u8 #59 23 SET u8 #719 25
127.0.0.1:6379> bitfield mykey set i5 100 15 0 127.0.0.1:6379> getbit mykey 100 0 127.0.0.1:6379> getbit mykey 101 1 127.0.0.1:6379> getbit mykey 102 1 127.0.0.1:6379> getbit mykey 103 1 127.0.0.1:6379> getbit mykey 104 1 # 当对带符号的值 增加1,会出现溢出的情况,即 -16 # 但二进制位数显示是一致的,也就是说 10000 这是-16的补码,所以这里的值才为-16 127.0.0.1:6379> bitfield mykey incrby i5 100 1 -16 127.0.0.1:6379> getbit mykey 100 1 127.0.0.1:6379> getbit mykey 101 0 127.0.0.1:6379> getbit mykey 102 0 127.0.0.1:6379> getbit mykey 103 0 127.0.0.1:6379> getbit mykey 104 0 127.0.0.1:6379> bitfield mykey2 set i5 100 -16 0 127.0.0.1:6379> getbit mykey2 100 1 127.0.0.1:6379> getbit mykey2 101 0 127.0.0.1:6379> getbit mykey2 102 0 127.0.0.1:6379> getbit mykey2 103 0 127.0.0.1:6379> getbit mykey2 104 0 127.0.0.1:6379> bitfield mystring set i8 #0 100 set i8 #1 200 0 0 127.0.0.1:6379> getbit mystring 0 0 127.0.0.1:6379> getbit mystring 1 1 127.0.0.1:6379> getbit mystring 2 1 127.0.0.1:6379> getbit mystring 3 0 127.0.0.1:6379> getbit mystring 4 0 127.0.0.1:6379> getbit mystring 5 1 127.0.0.1:6379> getbit mystring 6 0 127.0.0.1:6379> getbit mystring 7 0 127.0.0.1:6379> 127.0.0.1:6379> getbit mystring 8 1 127.0.0.1:6379> getbit mystring 9 1 127.0.0.1:6379> getbit mystring 10 0 127.0.0.1:6379> getbit mystring 11 0 127.0.0.1:6379> getbit mystring 12 1 127.0.0.1:6379> getbit mystring 13 0 127.0.0.1:6379> getbit mystring 14 0 127.0.0.1:6379> getbit mystring 15 0 127.0.0.1:6379> bitfield mystring get i8 #1 -56 ()是补码,它的值为-56,而不是200,这是因为溢出了

6. getrange 获取区间内的值

7. strlen : 获取字符串的长度,单位为字节

完整示例:

# 0. 127.0.0.1:6379> setbit mybinarystring 4 1 0 127.0.0.1:6379> setbit mybinarystring 14 1 0 127.0.0.1:6379> setbit mybinarystring 24 1 0 127.0.0.1:6379> setbit mybinarystring 25 1 0 127.0.0.1:6379> setbit mybinarystring 35 1 0 127.0.0.1:6379> setbit mybinarystring 45 1 0 127.0.0.1:6379> setbit mybinarystring 55 1 0 127.0.0.1:6379> setbit mybinarystring 56 1 0 # 1. 127.0.0.1:6379> getbit mybinarystring 24 1 # 2. 127.0.0.1:6379> bitcount mybinarystring 8 # 3. 我们直接copy mybinarystring的值 127.0.0.1:6379> copy mybinarystring mybinarystring2 1 127.0.0.1:6379> bitop and result mybinarystring mybinarystring2 8 127.0.0.1:6379> getbit result 4 1 127.0.0.1:6379> bitop or result2 mybinarystring mybinarystring2 8 127.0.0.1:6379> getbit result2 4 1 127.0.0.1:6379> bitop xor result3 mybinarystring mybinarystring2 8 127.0.0.1:6379> getbit result3 55 0 127.0.0.1:6379> getbit result3 56 0 127.0.0.1:6379> bitop not result4 mybinarystring 8 127.0.0.1:6379> getbit result4 45 0 127.0.0.1:6379> getbit result4 44 1 # 4. 127.0.0.1:6379> bitpos result4 1 0 127.0.0.1:6379> set mykey "\xff\xf0\x00" OK 127.0.0.1:6379> get mykey ▒▒ 127.0.0.1:6379> bitpos mykey 0 12 127.0.0.1:6379> set mykey "\x00\xff\xf0" OK 127.0.0.1:6379> bitpos mykey 1 0 8 127.0.0.1:6379> bitpos mykey 1 2 16 127.0.0.1:6379> bitpos mykey 1 3 -1 127.0.0.1:6379> bitpos mykey 1 1 8 127.0.0.1:6379> bitpos mykey 1 0 -1 8 127.0.0.1:6379> bitpos mykey 1 0 1 8 127.0.0.1:6379> bitpos mykey 1 0 0 -1 # 我的redis的版本是6.0,所以会出现语法错误 127.0.0.1:6379> bitpos mykey 1 0 1 byte ERR syntax error 127.0.0.1:6379> bitpos mykey 1 0 1 bit ERR syntax error # 5. bitfield # 有一个在线游戏,需要记录每个玩家的金币数和杀敌数,这个游戏是让人痴迷的,长度为32位,使用 bitfield 可以存储这两个关键信息。 # 游戏初始化为每个玩家为1000金币 127.0.0.1:6379> BITFIELD player:1:stats SET u32 #0 1000 1) (integer) 0 # 当杀掉妖怪救出人质后将会增加50金币,并增加一个妖怪数量 127.0.0.1:6379> BITFIELD player:1:stats INCRBY u32 #0 50 INCRBY u32 #1 1 1) (integer) 1050 2) (integer) 1 # 花费999金币买一个装备 127.0.0.1:6379> BITFIELD player:1:stats INCRBY u32 #0 -999 1) (integer) 51 # 获取玩家的信息 127.0.0.1:6379> BITFIELD player:1:stats GET u32 #0 GET u32 #1 1) (integer) 51 2) (integer) 1 # overflow # sat 127.0.0.1:6379> bitfield mykey overflow sat incrby u2 300 1 1) (integer) 1 127.0.0.1:6379> bitfield mykey overflow sat incrby u2 300 1 1) (integer) 2 127.0.0.1:6379> bitfield mykey overflow sat incrby u2 300 1 1) (integer) 3 127.0.0.1:6379> bitfield mykey overflow sat incrby u2 300 1 1) (integer) 3 127.0.0.1:6379> bitfield mykey overflow sat incrby u2 300 1 1) (integer) 3 # wrap,这是默认值 127.0.0.1:6379> bitfield mykey overflow wrap incrby u2 400 1 1) (integer) 1 127.0.0.1:6379> 127.0.0.1:6379> bitfield mykey overflow wrap incrby u2 400 1 1) (integer) 2 127.0.0.1:6379> bitfield mykey overflow wrap incrby u2 400 1 1) (integer) 3 127.0.0.1:6379> bitfield mykey overflow wrap incrby u2 400 1 1) (integer) 0 127.0.0.1:6379> bitfield mykey overflow wrap incrby u2 400 1 1) (integer) 1 # 6. 获取这个key的区间的数字 127.0.0.1:6379> getrange mystring 0 15 "d\xc8" d 代表的ascii码,即 0110 0100 \xc8 代表十六进制,即 1100 1000 # 7. 获取这个key的长度,单位为字节 127.0.0.1:6379> strlen mystring 2

THE END

发表回复