redis
在redis里面其实分为16个库得,你的key创建在那个区域里面,其他区域是看不到得,至于为什么非要分为16,估计类似hash 16位的逻辑一样吧,参考java hashmap<16>
string
在redis 里面是可以用使用 help 的
可以看到关于string 操作的各种命令
127.0.0.1:16379[8]> help @string
tips: 下面是清空redis库,建议上线之后将这两个操作重新命名
## 清空redis 数据
127.0.0.1:16379> FLUSHALL
## 清空DB
127.0.0.1:16379> flushdb
我们看下set 的基本设置,一般我们都会用 set a b ,get a 得出来 b
127.0.0.1:16379> help set
SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]
summary: Set the string value of a key
since: 1.0.0
group: string
The SET command supports a set of options that modify its behavior:
EX seconds – Set the specified expire(期满时间) time, in seconds.秒
PX milliseconds – Set the specified expire time, in milliseconds.毫秒
NX – Only set the key if it does not already exist.只能新建。不存在时设置 ,创建分布式锁的时候可以用上
XX – Only set the key if it already exist.存在时设置,只能更新
KEEPTTL – Retain the time to live associated with the key.保留与秘钥关联的生存时间
append 追加字符串
127.0.0.1:16379> append k1 " word"
(integer) 10
127.0.0.1:16379> get k1
"hello word"
GETRANGE截取字符串
127.0.0.1:16379> GETRANGE k1 6 -1
"word"
127.0.0.1:16379> GETRANGE k1 0 -1
"hello word"
这里-1 是正反向索引问题,负数是反向索引
SETRANGE 覆盖操作
127.0.0.1:16379> get k1
"hello word"
127.0.0.1:16379> SETRANGE k1 6 zjj
(integer) 10
127.0.0.1:16379> get k1
"hello zjjd"
STRLEN 获取字符长度
127.0.0.1:16379> get k1
"hello zjjd"
127.0.0.1:16379> STRLEN k1
(integer) 10
上面都是对redis string 基本操作
set 是那个分组就得出type 是什么类型
# 这个时候获取上面k1类型得出string
127.0.0.1:16379> type k1
string
127.0.0.1:16379> FLUSHALL
OK
127.0.0.1:16379> set k1 99
OK
127.0.0.1:16379> type k1
string
127.0.0.1:16379> help set
SET key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|XX] [GET]
summary: Set the string value of a key
since: 1.0.0
group: string
OBJECT encoding查看用户编码类型
127.0.0.1:16379> set k2 hello
OK
127.0.0.1:16379> get k2
"hello"
127.0.0.1:16379> OBJECT encoding k2
"embstr"
127.0.0.1:16379> OBJECT encoding k1
"int"
这个时候有个问题是,redis 里面并没有 int 类型!其实在redis 里面可以判断encoding,判断如果是 int 就可以使用 incr
INCR 加 1 操作
INCRBY 加22 操作
INCRBYFLOAT 加0.5操作
127.0.0.1:16379> INCR k1
(integer) 100
127.0.0.1:16379> INCRBY k1 22
(integer) 122
127.0.0.1:16379> INCRBYFLOAT k1 0.5
"99.5"
DECR 减1 操作
DECRBY 减22操作
127.0.0.1:16379> DECR k1
(integer) 121
127.0.0.1:16379> DECRBY k1 22
(integer) 99
这里穿插一个知识点,二进制安全
127.0.0.1:16379> set k3 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
OK
127.0.0.1:16379> STRLEN k3
(integer) 39
127.0.0.1:16379> OBJECT encoding k3
"embstr"
127.0.0.1:16379> APPEND k3 jjjjj
(integer) 44
127.0.0.1:16379> OBJECT encoding k3
"raw"
127.0.0.1:16379> set k2 9
OK
127.0.0.1:16379> STRLEN k2
(integer) 1
127.0.0.1:16379> APPEND k2 999
(integer) 4
127.0.0.1:16379> get k2
"9999"
127.0.0.1:16379> OBJECT encoding k2
"raw"
127.0.0.1:16379> incr k2
(integer) 10000
127.0.0.1:16379> OBJECT encoding k2
"int"
127.0.0.1:16379> STRLEN k2
(integer) 5
127.0.0.1:16379> set k3 a
OK
127.0.0.1:16379> get k3
"a"
127.0.0.1:16379> STRLEN k3
(integer) 1
127.0.0.1:16379> append k3 中
(integer) 4
127.0.0.1:16379> STRLEN k3
(integer) 4
外界对redis 进行操作时,只拿了字节流,并没有拿字符流,因为要避免数据的破坏,双方客户端要统一编解码,不同语言对整形的宽度是不一样的,容易出现节段溢出错误。就比如我们在不同语言交互的时候,更偏向于json,xml。如果使用序列化,大家就要增加一个编码器解码器,编码器解码器不一样的话,你这边认为int 是4 我这边认为是2个,你存了,我这边取出的时候直接溢出了,所以要统计编码
这个时候是redis自己做的预判断,减少排错可以直接使用 incr
127.0.0.1:16379> set k5 5
OK
127.0.0.1:16379> OBJECT encoding k5
int
xshell 在utf-8下展示 中为 3个字符长度
127.0.0.1:16379> set k2 中
OK
127.0.0.1:16379> get k2
"\xe4\xb8\xad"
127.0.0.1:16379> strlen k2
(integer) 3
xshell GBK下展示 中为2个字符长度
127.0.0.1:16379> set k3 中
OK
127.0.0.1:16379> get k3
"\xd6\xd0"
127.0.0.1:16379> STRLEN k3
(integer) 2
退出重进,如果不加--raw redis默认使用ASCII 码,携带raw会读改客户端使用的编码集,这个时候我的
xshell默认在utf-8 上面,所以k3乱码,hbase 也是这样的。长度是不会变化的
redis-cli -p 16379 --raw
127.0.0.1:16379> get k3
א
127.0.0.1:16379> get k2
中
GETSET set新的值返回老的值,这个操作减少一次io操作
127.0.0.1:16379> set k1 hello
OK
127.0.0.1:16379> get k1
hello
127.0.0.1:16379> GETSET k1 word
hello
msetnx 多个数值操作
127.0.0.1:16379> msetnx k1 a k2 b
1
127.0.0.1:16379> mget k1 k2
a
b
这一步失败了,是redis为了保存原子性操作,失败都失败
127.0.0.1:16379> MSETnx k2 c k3 d
0
127.0.0.1:16379> mget k1 k2 k3
a
b
bitmap
127.0.0.1:16379> help setbit
SETBIT key offset value
summary: Sets or clears the bit at offset in the string value stored at key
since: 2.2.0
group: string
offset 代表二进制位便一辆并非字节的
科普:一个字节有8个二进制位
setbit 操作二进制位
# 01000000
127.0.0.1:16379> setbit k1 1 1
(integer) 0
127.0.0.1:16379> STRLEN k1
(integer) 1
127.0.0.1:16379> get k1
"@"
# 01000001
127.0.0.1:16379> setbit k1 7 1
(integer) 0
# 还是一个字节
127.0.0.1:16379> STRLEN k1
(integer) 1
127.0.0.1:16379> get k1
"A"
ascii 码!
127.0.0.1:16379> setbit k1 9 1
(integer) 0
# 这个时候已经成为两个字节了
127.0.0.1:16379> STRLEN k1
(integer) 2
127.0.0.1:16379> get k1
"A@"
bitpos 返回字符串里面第一个被设置为1或者0的bit位。
127.0.0.1:16379> help bitpos
BITPOS key bit [start] [end]
summary: Find first bit set or clear in a string
since: 2.8.7
group: string
目前k1 得 A@ 二进制值 01000001 | 01000000
k1 二进制中 第0个二进制下面 第零个出现得1
127.0.0.1:16379> bitpos k1 1 0 0
(integer) 1
k1 二进制中 第1个二进制下面 出现得1位置下标
127.0.0.1:16379> bitpos k1 1 1 1
(integer) 9
k1 二进制中 第0个二进制下面 出现得1位置下标
127.0.0.1:16379> bitpos k1 1 0 1
(integer) 1
BITCOUNT 统计字符串被设置为1的bit数. start 第一个字节 end 第二个第三个字节
127.0.0.1:16379> SET K1 @A
OK
127.0.0.1:16379> BITCOUNT k1
(integer) 3
127.0.0.1:16379> BITCOUNT k1 0 1
(integer) 3
127.0.0.1:16379> BITCOUNT k1 0 0
(integer) 2
127.0.0.1:16379> BITCOUNT k1 1 1
(integer) 1
BITOP
对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数:
BITOP AND destkey srckey1 srckey2 srckey3 … srckeyN ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。
BITOP OR destkey srckey1 srckey2 srckey3 … srckeyN,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。
BITOP XOR destkey srckey1 srckey2 srckey3 … srckeyN,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。
BITOP NOT destkey srckey,对给定 key 求逻辑非,并将结果保存到 destkey 。
除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。
执行结果将始终保持到destkey里面。
127.0.0.1:16379> setbit k1 1 1
(integer) 0
127.0.0.1:16379> setbit k1 7 1
(integer) 0
127.0.0.1:16379> get k1
"A"
--------------------此时 01000001
127.0.0.1:16379> setbit k2 1 1
(integer) 0
127.0.0.1:16379> get k2
"@"
127.0.0.1:16379> setbit k2 6 1
(integer) 0
--------------------此时 01000001
127.0.0.1:16379> get k2
"B"
--------------------此时 01000010
bitop and 与操作,都是1 为1 其余都为0
127.0.0.1:16379> bitop and andkey k1 k2
(integer) 1
127.0.0.1:16379> get andkey
"@"
--------------------此时 01000001 A
--------------------此时 01000010 B
--------------------此时 01000000 @
BITOP or 或操作,有1则1,有0为0
127.0.0.1:16379> BITOP or ortoy k1 k2
(integer) 1
127.0.0.1:16379> get ortoy
"C"
--------------------此时 01000001 A
--------------------此时 01000010 B
--------------------此时 01000011 C
bitmap挺重要的
1,有用户系统,统计用户登录天数,且窗口随机
setbit sean 1 1
setbit sean 7 1
setbit sean 364 1
365天最大也才46个字节
STRLEN sean
BITCOUNT sean -2 -1
2.统计活跃用户量
有2E用户僵尸用户冷热用户/忠诚用户活跃用户统计!
随即窗口比如说 1号~3号 连续登录要
去重setbit 20190101 1 1
setbit 20190102 1 1
setbit 20190102 7 1
bitop or destkey 20190101 20190102
BITCOUNT destkey 0 -1