<架构师必修课>-redis

1 引言

redis的重要性不必多说,几乎在任何项目中都可以看到redis的身影,本文不介绍redis的安装与配置,着重说redis应用,我使用的环境是阿里云服务器加上docker,在docker hub上拉取到redis镜像,然后创造一个容器,运行在docker上面。

2 redis常用数据类型

2.1 常用key操作

显示所有key

keys * (* 表示通配符)

127.0.0.1:6379[1]> keys *
(empty array)

设置key

set key value

127.0.0.1:6379[1]> set k1 kobe 
OK
127.0.0.1:6379[1]> set k2 wade
OK
127.0.0.1:6379[1]> set k3 paul
OK
127.0.0.1:6379[1]> keys *
1) "k3"
2) "k1"
3) "k2"

检查key的类型

type key

127.0.0.1:6379[1]> type key1
none
127.0.0.1:6379[1]> type k1
string

判断key是否存在

exists key

127.0.0.1:6379[1]> exists k1
(integer) 1
127.0.0.1:6379[1]> exists k4
(integer) 0

设置key的过期时间

expire key seconds
ttl key
-1 表示永不过期,-2 表示已经过期,正整数表示还剩几秒过期

127.0.0.1:6379[1]> expire k1 10
(integer) 1
127.0.0.1:6379[1]> ttl k1
(integer) 7
127.0.0.1:6379[1]> ttl k1
(integer) 2
127.0.0.1:6379[1]> ttl k1
(integer) 0
127.0.0.1:6379[1]> ttl k1
(integer) -2

删除元素

del key : 同步删除
unlink key :异步删除

127.0.0.1:6379[1]> del k2
(integer) 1
127.0.0.1:6379[1]> unlink k3 
(integer) 1

切换数据库

redis 默认有16个DB,索引是0~15,默认是0

select index

127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> select 0
OK

查看db中key的个数

dbsize

127.0.0.1:6379[1]> dbsize
(integer) 1

清空当前库

flushdb

清空所有库

flushall

2.2 String

string是最基本的数据类型,一个key对应一个value,String类型二进制安全,value可以是任何数据,比如图片或者序列化对象,最大不能超过512MB.

添加键值对

在这里插入图片描述

127.0.0.1:6379[1]> set k1 v1
OK

设置超时时间键值对

setex key seconds value

127.0.0.1:6379[1]> setex k2 10 v2
OK
127.0.0.1:6379[1]> ttl k2
(integer) 6
127.0.0.1:6379[1]> ttl k2
(integer) 4
127.0.0.1:6379[1]> ttl k2
(integer) 0
127.0.0.1:6379[1]> ttl k2
(integer) -2

设置库中没有的key

setnx key value 这里面的key必须是新key

127.0.0.1:6379[1]> keys *
1) "k1"
127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> setnx k1 v100  # 库中有k1,设置不成功
(integer) 0
127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> setnx k2 v2 # 库中没有k2,设置成功
(integer) 1
127.0.0.1:6379[1]> get k2
"v2"

在key对应的值尾部添加一些字符

append key value

127.0.0.1:6379[1]> get k1
"v1"
127.0.0.1:6379[1]> append k1 haha
(integer) 6
127.0.0.1:6379[1]> get k1
"v1haha"

获取key对应的值长度

strlen key

127.0.0.1:6379[1]> strlen k1
(integer) 6

数值型值递增,递减

redis的递增和递减是原子性操作

incr key
decr key
incrby key increment
decrby key decrement

127.0.0.1:6379[1]> get k3
"1"
127.0.0.1:6379[1]> incr k3
(integer) 2
127.0.0.1:6379[1]> incr k3
(integer) 3
127.0.0.1:6379[1]> decr k3
(integer) 2
127.0.0.1:6379[1]> decr k3
(integer) 1
127.0.0.1:6379[1]> incrby k4 10
(integer) 10
127.0.0.1:6379[1]> incrby k4 10
(integer) 20
127.0.0.1:6379[1]> incrby k4 10
(integer) 30
127.0.0.1:6379[1]> incrby k4 10
(integer) 40
127.0.0.1:6379[1]> decrby k4 20
(integer) 20
127.0.0.1:6379[1]> decrby k4 20
(integer) 0

同时设置一个或多个

mset key value [key value…]

127.0.0.1:6379[1]> mset k1 v1 k2 v2
OK
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"

同时读取多个

mget key [key…]

127.0.0.1:6379[1]> mget k1 k2
1) "v1"
2) "v2"

同时设置一个或多个不存在的key

msetnx key value [key value…]

127.0.0.1:6379[1]> msetnx k1 v1 k2 v2
(integer) 1
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"

获取指定范围的值
getrange key start end

127.0.0.1:6379[1]> set k3 "hello world"
OK
127.0.0.1:6379[1]> get k3
"hello world"
127.0.0.1:6379[1]> getrange k3 0 5
"hello "

以新值换旧值

getset key value

127.0.0.1:6379[1]> get k3
"hello world"
127.0.0.1:6379[1]> getset k3 haha
"hello world"
127.0.0.1:6379[1]> get k3
"haha"

String的数据结构

String的数据结构为简单动态字符串(Simple Dynamic String SDS)。是可以修改的字符串,内部结构实现类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
内部为当前字符串实际分配的空间一般要高于实际字符串长度len,当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时只会多扩1M的空间,需要注意的是字符串最大长度为512M。

2.3 List

简介

单键多值

Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素列表的头部(左边)或者尾部(右边)它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会比较差

从List左侧插入值

lpush key element [element…]

127.0.0.1:6379[1]> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"

在这里插入图片描述

通过输出结果可以看出lpush指令是链表的头插法

从List右侧插入值

在这里插入图片描述

127.0.0.1:6379[1]> rpush k2 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v1"
2) "v2"
3) "v3"

通过输出结果可以看出rpush指令是链表的尾插法

从列表的左边或右边取值

lpop/rpop key [count] 值在健在,值没有健就没有了

127.0.0.1:6379[1]> lpop k1 
"v3"
127.0.0.1:6379[1]> rpop k1 
"v1"
127.0.0.1:6379[1]> rpop k1 
"v2"
127.0.0.1:6379[1]> rpop k1 
(nil)

从一个键的右侧取值,插到另一个键的左侧

rpoplpush source destination

在这里插入图片描述

127.0.0.1:6379[1]> lpush k1 v1 v2 v3
(integer) 3
127.0.0.1:6379[1]> lpush k2 v11 v12 v13
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
3) "v1"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v13"
2) "v12"
3) "v11"
127.0.0.1:6379[1]> rpoplpush k1 k2
"v1"
127.0.0.1:6379[1]> lrange k2 0 -1
1) "v1"
2) "v13"
3) "v12"
4) "v11"

获取指定索引的数据
lindex key index

127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "v2"
127.0.0.1:6379[1]> lindex k1 0
"v3"

获取列表的长度

llen key

127.0.0.1:6379[1]> llen k1
(integer) 2

在列表某个元素的前或后插入一个新元素
linsert key before|after pivot element

127.0.0.1:6379[1]> linsert k1 after "v3" "hello"
(integer) 3
127.0.0.1:6379[1]> lrange k1 0 -1
1) "v3"
2) "hello"
3) "v2"
127.0.0.1:6379[1]> linsert k1 before "v3" "world"
(integer) 4
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "v3"
3) "hello"
4) "v2"

移除某个元素,可以指定移除的个数
lrem key count element

127.0.0.1:6379[1]> lrem k1 2 "v2"
(integer) 1
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "v3"
3) "hello"

修改指定索引位置的值

lset key index element

127.0.0.1:6379[1]> lset k1 1 "ni"
OK
127.0.0.1:6379[1]> lrange k1 0 -1
1) "world"
2) "ni"
3) "hello"

数据结构

List的数据结构为quickList
数据很少时,会分配一块连续的内存空间,形成一个zipList(压缩列表)
数据很多时,会分配多个zipList ,多个zipList使用链表链接

在这里插入图片描述

2.4 Set

简介

Set与List类似是一个列表的功能,特殊之处是set内的元素不可以重复,用于存储和维护一个没有重复数据的列表数据。
Set是String类型的无序集合,底层是一个value为null的hash表,添加、删除、查找都是O(1)

往集合中添加元素

sadd key member [member …]

127.0.0.1:6379[1]> sadd k1 v1 v2 v3
(integer) 3

查看集合中的元素

smembers key

127.0.0.1:6379[1]> smembers k1
1) "v3"
2) "v2"
3) "v1"

判断某个元素是否在集合中

sismember key member

127.0.0.1:6379[1]> sismember k1 "v1"
(integer) 1
127.0.0.1:6379[1]> sismember k1 v2
(integer) 1
127.0.0.1:6379[1]> sismember k1 v4
(integer) 0

获取集合中元素的个数

scard key

127.0.0.1:6379[1]> scard k1
(integer) 3

删除集合中某个元素或多个元素

srem key member [member…]

127.0.0.1:6379[1]> srem k1 v1
(integer) 1
127.0.0.1:6379[1]> smembers k1
1) "v3"
2) "v2"

随机删除一个或多个元素并返回

spop key [count] 值没有了,健就消失了

127.0.0.1:6379[1]> spop k1 
"v2"
127.0.0.1:6379[1]> spop k1 
"v3"
127.0.0.1:6379[1]> spop k1 
(nil)

随机获取几个元素,不删除

127.0.0.1:6379[1]> sadd k2 v1 v2 v3 v4
(integer) 4
127.0.0.1:6379[1]> srandmember k2 2
1) "v1"
2) "v4"
127.0.0.1:6379[1]> srandmember k2 2
1) "v1"
2) "v2"
127.0.0.1:6379[1]> smembers k2
1) "v3"
2) "v4"
3) "v2"
4) "v1"

将一个集合的某个元素移动到另一个集合中

smove source destination member

127.0.0.1:6379[1]> sadd k1 v100 v200
(integer) 2
127.0.0.1:6379[1]> keys *
1) "k1"
2) "k2"
127.0.0.1:6379[1]> smove k1 k2 v100
(integer) 1
127.0.0.1:6379[1]> smembers k1
1) "v200"
127.0.0.1:6379[1]> smembers k2
1) "v3"
2) "v4"
3) "v2"
4) "v1"
5) "v100"

获取两个集合的交集

sinter key [key…]

127.0.0.1:6379[1]> sadd k3 v1 v2 v3 v4 v5
(integer) 5
127.0.0.1:6379[1]> sadd k4 v3 v4 v5 v6 v7
(integer) 5
127.0.0.1:6379[1]> sinter k3 k4 
1) "v3"
2) "v4"
3) "v5"

获取两个集合的并集

sunion key [key …]

127.0.0.1:6379[1]> sunion k3 k4
1) "v7"
2) "v4"
3) "v5"
4) "v6"
5) "v3"
6) "v2"
7) "v1"

获取两个集合的差集

sdiff key [key …]

127.0.0.1:6379[1]> sdiff k3 k4
1) "v1"
2) "v2"
127.0.0.1:6379[1]> sdiff k4 k3
1) "v7"
2) "v6"

数据结构

Set数据结构是dict字典,字典是用哈希表实现的。
Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一对象,Redis的set结构也是一样,内部也使用hash结构,所有的value都指向同一个内部值。

2.5 Hash

简介
Hash是一个键值对集合,是一个string类型的field和value映射表,hash特别适合存储对象。

添加一个hash数据

hset key field value

127.0.0.1:6379[1]> hset user:1001 id 1 name zhangsan
(integer) 2

给一个hash数据添加多个field

hmset key field value [field value …]

127.0.0.1:6379[1]> hmset user:1002 id 2 name lisi age 10
OK

获取某个key的某个field

hget key field

127.0.0.1:6379[1]> hget user:1001 id
"1"
127.0.0.1:6379[1]> hget user:1001 name
"zhangsan"

获取某个key的多个field

hmget key field [field…]

127.0.0.1:6379[1]> hmget user:1002 id name age
1) "2"
2) "lisi"
3) "10"

判断某个key中是否存在某个field

hexists key field

127.0.0.1:6379[1]> hexists user:1002 id 
(integer) 1
127.0.0.1:6379[1]> hexists user:1002 tt
(integer) 0

获取某个key中所有的field字段

hkeys key

127.0.0.1:6379[1]> hkeys user:1001
1) "id"
2) "name"
127.0.0.1:6379[1]> hkeys user:1002
1) "id"
2) "name"
3) "age"

获取某个key中所有field对应的value

hvals key

127.0.0.1:6379[1]> hvals user:1001
1) "1"
2) "zhangsan"
127.0.0.1:6379[1]> hvals user:1002
1) "2"
2) "lisi"
3) "10"

对某个key中的数值型field字段递增

hincrby key field increment

127.0.0.1:6379[1]> hincrby user:1002 age 2
(integer) 12

对某个key新增一对field-value对

hsetnx key field value field必须是不存在的,如果已经存在,设置不成功

127.0.0.1:6379[1]> hsetnx user:1002 age 40
(integer) 0
127.0.0.1:6379[1]> hsetnx user:1002 sex 1
(integer) 1

数据结构

当field-value 长度较短且个数较少时,使用ziplist
较多时时候hashtable

2.6 Zset(有序集合)

简介
Zset与set一样,是没有重复元素的字符串集合,有序集合的每个成员都关联一个评分,评分被用来排序,成员唯一,评分可以不唯一

添加有序集合元素

zadd key score member [score member…]

127.0.0.1:6379[1]> zadd topn 200 java 300 c++ 400 mysql 500 python
(integer) 4

获取指定范围的集合元素

zrange key min max [withscores]

127.0.0.1:6379[1]> zrange topn 0 -1
1) "java"
2) "c++"
3) "mysql"
4) "python"
127.0.0.1:6379[1]> zrange topn 0 -1 withscores
1) "java"
2) "200"
3) "c++"
4) "300"
5) "mysql"
6) "400"
7) "python"
8) "500"

按照score获取指定范围的值

zrangebyscore key min max [withscores]

127.0.0.1:6379[1]> zrangebyscore topn 300 500 
1) "c++"
2) "mysql"
3) "python"
127.0.0.1:6379[1]> zrangebyscore topn 300 500 withscores
1) "c++"
2) "300"
3) "mysql"
4) "400"
5) "python"
6) "500"

降序获取指定分数范围内的值

zrevrangebyscore key max min [withscores]

127.0.0.1:6379[1]> zrevrangebyscore topn 500 300 withscores 
1) "python"
2) "500"
3) "mysql"
4) "400"
5) "c++"
6) "300"

递增某个成员的分数

zincrby key increment member

127.0.0.1:6379[1]> zincrby topn 50 java
"250"

获取指定分数范围内成员的个数

zcount key min max

127.0.0.1:6379[1]> zcount topn 200 300
(integer) 2

获取某个成员的排名

zrank key member 第一位返回的是0

127.0.0.1:6379[1]> zrank topn java
(integer) 0
127.0.0.1:6379[1]> zrank topn python
(integer) 3

数据结构

hash: field是成员 value是评分
跳跃表:给元素value排序,根据score的范围获取元素列表

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kobe_OKOK_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值