系列文章目录
Redis01 基础及安装
Redis02-架构及简单使用
Redis03-数据类型:应用及实操
Redis04-进阶使用(管道、发布/订阅)
Redis05-进阶使用(事务)
Redis06-进阶使用(过期 expire)
Redis07-RDB和AOF
redis的数据类型
应用
string
1、数值操作 incr :可以规避并发下对数据库的事务操作,完全由redis内存操作代替
使用场景: 抢购,秒杀,详情页,点赞,评论
2、位图bitmap的操作:
- 统计用户的登录天数,且窗口随机
- 统计活跃用户,且随机窗口
list
可以作为栈(同向命令),作为队列(反向命令),作为阻塞的单播队列。FIFO
hash
通过对field的数值进行计算,从而实现点赞,收藏,详情页等功能
set
去重
产生随机事件如抽奖(带正负参数决定是否取重复)
sorted_set
排序
实操
String类型
## 连接客户端
[root@node01 ~]# redis-cli -p 6379
127.0.0.1:6379> set key "hello world"
OK
127.0.0.1:6379> get key
"hello world"
##==========获取所有的keys==========
127.0.0.1:6379> keys *
1) "key"
##========== nx 不存在key时才能设置,即只能新建,不能修改
127.0.0.1:6379> set k1 hello nx
OK
127.0.0.1:6379> set k1 xxoo nx
(nil)
##========== xx 存在key时才能设置,即只能更新
127.0.0.1:6379> set k2 ooxx xx
(nil)
127.0.0.1:6379> set k2 ooxx
OK
127.0.0.1:6379> set k2 xxoo xx
OK
##========== 批量设置 ==========
127.0.0.1:6379> mset k3 asdf k4 asdfas
OK
127.0.0.1:6379> mget k3 k4
1) "asdf"
2) "asdfas"
##========== append ==========
127.0.0.1:6379> get k1
"hello"
127.0.0.1:6379> APPEND k1 world
(integer) 10
127.0.0.1:6379> get k1
"helloworld"
##========== 正反索引 ==========
127.0.0.1:6379> GETRANGE k1 0 -1
"helloworld"
127.0.0.1:6379> getrange k1 5 -1
"world"
127.0.0.1:6379> setrange k1 5 gaozx
(integer) 10
127.0.0.1:6379> get k1
"hellogaozx"
127.0.0.1:6379> strlen k1
(integer) 10
##========== 查看key对应的value的数据类型
127.0.0.1:6379> type k1
string
##==========数值操作 ==========
127.0.0.1:6379> set k1 11
OK
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> INCR k1
(integer) 12
127.0.0.1:6379> INCRBY k1 5
(integer) 17
127.0.0.1:6379> DECR k1
(integer) 16
127.0.0.1:6379> DECRBY k1 3
(integer) 13
127.0.0.1:6379> INCRBYFLOAT k1 0.5
"13.5"
##========== uft-8 和gbk 编码 ======
127.0.0.1:6379> set k1 a
OK
127.0.0.1:6379> get k1
"a"
127.0.0.1:6379> STRLEN k1
(integer) 1
127.0.0.1:6379> APPEND k1 中
(integer) 4
127.0.0.1:6379> get k1
"a\xe4\xb8\xad"
127.0.0.1:6379> STRLEN k1
(integer) 4
##========== 启动时加上 --raw 触发格式化操作 ,汉字可以正常显示
127.0.0.1:6379> exit
[root@node01 ~]# redis-cli --raw
127.0.0.1:6379> get k1
a中
##========== 原子性操作 =============
127.0.0.1:6379> SETNX k1 aaa
1
127.0.0.1:6379> get k1
aaa
127.0.0.1:6379> SETNX k1 bbb
0
127.0.0.1:6379> get k1
aaa
127.0.0.1:6379> msetnx k3 333 k4 444
1
127.0.0.1:6379> mget k3 k4
333
444
127.0.0.1:6379> msetnx k1 111 k2 222
0
127.0.0.1:6379> mget k1 k2 k3 k4
aaa
333
444
##========== 位图,一个字节8位========
127.0.0.1:6379> setbit k1 1 1
0
127.0.0.1:6379> STRLEN k1
1
127.0.0.1:6379> get k1
@ ##01000000
127.0.0.1:6379> setbit k1 7 1
0
127.0.0.1:6379> STRLEN k1
1
127.0.0.1:6379> get k1
A ##01000001
127.0.0.1:6379> setbit k1 9 1
0
127.0.0.1:6379> STRLEN k1
2
127.0.0.1:6379> get k1
A@ ##01000001 01000000
##======== 就算是只找第二个字节,依然会返回全量字节的索引下标
127.0.0.1:6379> help bitpos
BITPOS key bit [start] [end]
summary: Find first bit set or clear in a string
since: 2.8.7
group: string
127.0.0.1:6379> bitpos k1 1 0 0
1
127.0.0.1:6379> bitpos k1 1 1 1
9
127.0.0.1:6379> bitpos k1 1 0 1
1
##======= 统计次数 ============
127.0.0.1:6379> help BITCOUNT
BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0
group: string
127.0.0.1:6379> bitcount k1 0 1
3
##======== 位操作 =============
127.0.0.1:6379> setbit k1 1 1
0
127.0.0.1:6379> setbit k1 7 1
0
127.0.0.1:6379> get k1
A
127.0.0.1:6379> setbit k2 1 1
0
127.0.0.1:6379> setbit k2 6 1
0
127.0.0.1:6379> get k2
B
127.0.0.1:6379> bitop and andkey k1 k2
1
127.0.0.1:6379> get andkey
@
127.0.0.1:6379> bitop or orkey k1 k2
1
127.0.0.1:6379> get orkey
C
List
##========== 先来查看list的操作 ==========
127.0.0.1:6379> help @list
##========== 添加 ===============
## l代表左边,插入的结构实际为f e d c b a
127.0.0.1:6379> lpush k1 a b c d e f
6
## r代表右边,插入的结构实际为a b c d e f
127.0.0.1:6379> rpush k2 a b c d e f
6
##========== 查看 ===============
127.0.0.1:6379> lrange k1 0 -1
f
e
d
c
b
a
127.0.0.1:6379> lrange k2 0 -1
a
b
c
d
e
f
##========== 弹出一个元素 ============
## 同向命令 等同栈
## 反向命令 等同队列
127.0.0.1:6379> lpop k1
"f"
127.0.0.1:6379> rpop k1
"a"
127.0.0.1:6379>
##========== 根据下标取值,等同数组 ============
## 这里l代表list
127.0.0.1:6379> lindex k2 2
"c"
127.0.0.1:6379> lindex k2 -1
"f"
##========== 设置 ============
127.0.0.1:6379> lset k2 0 xxx
OK
127.0.0.1:6379> lrange k2 0 -1
1) "xxx"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
##========== 删除 ============
## 移除count数量的value
## count是正数,从左开始删除,负数,从右开始删除
127.0.0.1:6379> rpush k1 a b a c b s e
(integer) 7
127.0.0.1:6379> lrem k1 1 c
(integer) 1
127.0.0.1:6379> lrange k1 0 -1
1) "a"
2) "b"
3) "a"
4) "b"
5) "s"
6) "e"
127.0.0.1:6379> lrem k1 2 b
(integer) 2
127.0.0.1:6379> lrange k1 0 -1
1) "a"
2) "a"
3) "s"
4) "e"
127.0.0.1:6379> lrem k1 1 a
(integer) 1
127.0.0.1:6379> lrange k1 0 -1
1) "a"
2) "s"
3) "e"
127.0.0.1:6379> lrem k1 3 s
(integer) 1
127.0.0.1:6379> lrange k1 0 -1
1) "a"
2) "e"
127.0.0.1:6379>
##========== 插入 ============
## 在元素e之后插入,而不是下标了
## 如果有两个相同元素,会在第一个元素e之后插入,而不是两个e全插入
127.0.0.1:6379> linsert k1 after e f
(integer) 3
127.0.0.1:6379> lrange k1 0 -1
1) "a"
2) "e"
3) "f"
##========== 统计长度 ============
127.0.0.1:6379> llen k1
(integer) 3
##========== 阻塞式取值 ============
## 首先起两个cli 阻塞,再起一个cli 新增数据
127.0.0.1:6379> blpop k1 0
1) "k1"
2) "aaa"
(32.85s)
127.0.0.1:6379> LPUSH k1 aaa
(integer) 1
##========== trim ============
## 两端删除,不包含start和stop
127.0.0.1:6379> rpush k1 a b c d e f g
(integer) 7
127.0.0.1:6379> ltrim k1 0 -1
OK
127.0.0.1:6379> llen k1
(integer) 7
127.0.0.1:6379> ltrim k1 1 -2
OK
127.0.0.1:6379> llen k1
(integer) 5
127.0.0.1:6379> lrange k1 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
Hash
##========== 先来看看hash的操作 ==========
127.0.0.1:6379> help @hash
127.0.0.1:6379> hset jeff name 'zhangsan'
(integer) 1
127.0.0.1:6379> hget jeff name
"zhangsan"
127.0.0.1:6379> hmset jeff name 'lisi' age 18 addr hangzhou
OK
127.0.0.1:6379> hget jeff age
"18"
127.0.0.1:6379> hget jeff name
"lisi"
127.0.0.1:6379> hget jeff addr
"hangzhou"
127.0.0.1:6379> hkeys jeff
1) "name"
2) "age"
3) "addr"
127.0.0.1:6379> hvals jeff
1) "lisi"
2) "18"
3) "hangzhou"
127.0.0.1:6379> hgetall jeff
1) "name"
2) "lisi"
3) "age"
4) "18"
5) "addr"
6) "hangzhou"
127.0.0.1:6379> HINCRBYFLOAT jeff age 0.5
"18.5"
Set
##========== 先来看看set的操作 ==========
127.0.0.1:6379> help @set
##========== 加入数据 ==========
127.0.0.1:6379> sadd k1 gaozx zxx long li chen
(integer) 5
127.0.0.1:6379> SMEMBERS k1
1) "long"
2) "zxx"
3) "gaozx"
4) "li"
5) "chen"
127.0.0.1:6379> srem k1 zxx long
(integer) 2
127.0.0.1:6379>
127.0.0.1:6379> sadd k2 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd k3 4 5 6 7 8
(integer) 5
##========== 取交集 ==========
127.0.0.1:6379> sinter k2 k3
1) "4"
2) "5"
127.0.0.1:6379> SINTERSTORE dest k2 k3
(integer) 2
##========== 取并集 ==========
127.0.0.1:6379> sunion k2 k3
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
127.0.0.1:6379> SUNIONSTORE udest k2 k3
(integer) 8
127.0.0.1:6379> SMEMBERS udest
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
##========== 取差集 ==========
127.0.0.1:6379> sdiff k2 k3
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> sdiff k3 k2
1) "6"
2) "7"
3) "8"
## 为正数的时候,取出一个去重的结果集(不能超过已有结果集)
## 为负数的时候,取出一个带重复的结果集(一定会满足你要的数量)
## 为0,不返回结果
127.0.0.1:6379> SRANDMEMBER k2 3
1) "5"
2) "4"
3) "1"
127.0.0.1:6379> SRANDMEMBER k2 3
1) "2"
2) "4"
3) "1"
127.0.0.1:6379> SRANDMEMBER k2 -3
1) "3"
2) "5"
3) "3"
127.0.0.1:6379> SRANDMEMBER k2 6
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> SRANDMEMBER k2 -6
1) "2"
2) "4"
3) "4"
4) "4"
5) "3"
6) "1"
127.0.0.1:6379> SRANDMEMBER k2 0
(empty list or set)
127.0.0.1:6379> spop k1
"gaozx"
Sorted_set
##========== 先来看看sorted_set的操作 ==========
## sorted_set 的操作都是Z开头的
## 物理内存左小右大,不随命令发生变化
127.0.0.1:6379> help @sorted_set
## 加入score member
127.0.0.1:6379> zadd k1 8 apple 2 banana 3 orange
(integer) 3
## 查看
127.0.0.1:6379> zrange k1 0 -1
1) "banana"
2) "orange"
3) "apple"
## 查看,带分值
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "banana"
2) "2"
3) "orange"
4) "3"
5) "apple"
6) "8"
## 取分值范围内的member
127.0.0.1:6379> zrangebyscore k1 3 8
1) "orange"
2) "apple"
##正向取
127.0.0.1:6379> zrange k1 0 1
1) "banana"
2) "orange"
## 反向取
127.0.0.1:6379> zrevrange k1 0 1
1) "apple"
2) "orange"
## 注意比较上下两张取法的差异
127.0.0.1:6379> zrange k1 -2 -1
1) "orange"
2) "apple"
## 通过值取分值
127.0.0.1:6379> zscore k1 apple
"8"
## 通过值取排名
127.0.0.1:6379> zrank k1 apple
(integer) 2
## 增加
127.0.0.1:6379> ZINCRBY k1 2.5 banana
"4.5"
## 实时根据修改更新排序
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "orange"
2) "3"
3) "banana"
4) "4.5"
5) "apple"
6) "8"
127.0.0.1:6379> zadd k1 80 tom 60 bob 70 gaozx
(integer) 3
127.0.0.1:6379> zadd k2 60 tom 100 bob 20 zxx
(integer) 3
## 取并集
127.0.0.1:6379> zunionstore unkey 2 k1 k2
(integer) 4
127.0.0.1:6379> zrange unkey 0 -1 withscores
1) "zxx"
2) "20"
3) "gaozx"
4) "70"
5) "tom"
6) "140"
7) "bob"
8) "160"
## 并集加权重
127.0.0.1:6379> zunionstore unkey1 2 k1 k2 weights 1 0.5
(integer) 4
127.0.0.1:6379> zrange unkey1 0 -1 withscores
1) "zxx"
2) "10"
3) "gaozx"
4) "70"
5) "bob"
6) "110"
7) "tom"
8) "110"
## 并集 取最大值
127.0.0.1:6379> zunionstore unkey2 2 k1 k2 aggregate max
(integer) 4
127.0.0.1:6379> zrange unkey2 0 -1 withscores
1) "zxx"
2) "20"
3) "gaozx"
4) "70"
5) "tom"
6) "80"
7) "bob"
8) "100"
二进制安全
一个字符一个字节
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
127.0.0.1:6379> mget k1 k2
1) "asdfas"
2) "99"
## 对于String类型,value有3种编码类型
127.0.0.1:6379> OBJECT encoding k1
"embstr"
127.0.0.1:6379> OBJECT encoding k2
"int"
127.0.0.1:6379> append k1 ooxx
(integer) 10
127.0.0.1:6379> OBJECT encoding k1
"raw"
127.0.0.1:6379> INCR k2
(integer) 100
127.0.0.1:6379> OBJECT encoding k2
"int"
127.0.0.1:6379> APPEND k2 00
(integer) 5
127.0.0.1:6379> get k2
"10000"
127.0.0.1:6379> OBJECT encoding k2
"raw"
127.0.0.1:6379> INCR k2
(integer) 10001
127.0.0.1:6379> OBJECT encoding k2
"int"
127.0.0.1:6379> STRLEN k2
(integer) 5