Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。原文地址
String(字符串)
字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 的结构不一样。字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户信息会经过一次反序列化的过程。
键值对
127.0.0.1:6379> set name cb
OK
127.0.0.1:6379> get name
"cb"
127.0.0.1:6379> EXISTS name
(integer) 1
127.0.0.1:6379> DEL name
(integer) 1
批量键值对
可以批量对多个字符串进行读写,节省网络耗时开销
127.0.0.1:6379> mget name1 name2 name3
1) "cb"
2) "aj"
3) (nil)
127.0.0.1:6379> mset name1 boy name2 girl name2 uknow
OK
127.0.0.1:6379> mget name1 name2 name3
1) "boy"
2) "uknow"
3) (nil)
过期和set命令扩展
可以对 key 设置过期时间,到点自动删除,这个功能常用来控制缓存的失效时间
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> set name test
OK
127.0.0.1:6379> EXPIRE name 5
(integer) 1
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> get name
(nil)
# setex等于set + expire
127.0.0.1:6379> setex name 5 test
OK
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> get name
(nil)
# setnx 如果key已存在就set不成功
127.0.0.1:6379> setnx name test
(integer) 1
127.0.0.1:6379> setnx name test1
(integer) 0
原子计数
如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是 signed long 的最大最小值,超过了这个值,Redis 会报错
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incr age
(integer) 22
127.0.0.1:6379> incrby age 10
(integer) 32
127.0.0.1:6379> incrby age -5
list(列表)
Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n),这点让人非常意外。 当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。
Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。
右边进左边出:队列
127.0.0.1:6379> rpush books java python go
(integer) 3
127.0.0.1:6379> llen books
(integer) 3
127.0.0.1:6379> lpop books
"java"
127.0.0.1:6379> lpop books
"python"
127.0.0.1:6379> lpop books
"go"
127.0.0.1:6379> lpop books
(nil)
右边进右边出:栈
127.0.0.1:6379> rpush books java python go
(integer) 3
127.0.0.1:6379> rpop books
"go"
127.0.0.1:6379> rpop books
"python"
127.0.0.1:6379> rpop books
"java"
127.0.0.1:6379> rpop books
(nil)
hash(字典)
Redis 的字典相当于 Java 语言里面的 HashMap,它是无序字典。内部实现结构上同 Java 的 HashMap 也是一致的,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对 用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。 hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情况再三权衡。
127.0.0.1:6379> hset books java "think in java"
(integer) 1
127.0.0.1:6379> hset books go "concurrency in go"
(integer) 1
127.0.0.1:6379> hset books python "python cookbook"
(integer) 1
127.0.0.1:6379> hgetall books
1) "java"
2) "think in java"
3) "go"
4) "concurrency in go"
5) "python"
6) "python cookbook"
127.0.0.1:6379> hlen books
(integer) 3
127.0.0.1:6379> hget books java
"think in java"
# 更新操作,结果返回0
127.0.0.1:6379> hset books java "new think in java"
(integer) 0
127.0.0.1:6379> hget books java
"new think in java"
set (集合)
Redis 的集合相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值NULL。 当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。
127.0.0.1:6379> sadd books java
(integer) 1
127.0.0.1:6379> sadd books python
(integer) 1
127.0.0.1:6379> sadd books java
(integer) 0
127.0.0.1:6379> smembers books
1) "java"
2) "python"
127.0.0.1:6379> sismember books java
(integer) 1
127.0.0.1:6379> scard books
(integer) 2
127.0.0.1:6379> spop books
"python"
zset (有序集合)
zset 似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。
zset 可以用来存粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。我们可以对粉丝列表按关注时间进行排序。 zset 还可以用来存储学生的成绩,value 值是学生的 ID,score 是他的考试成绩。我们可以对成绩按分数进行排序就可以得到他的名次。
127.0.0.1:6379> zadd books 9.0 "think in jvava"
(integer) 1
127.0.0.1:6379> zadd books 8.9 "java concurrency"
(integer) 1
127.0.0.1:6379> zadd books 8.6 "java cookbook"
(integer) 1
127.0.0.1:6379> zrange books 0 -1
1) "java cookbook"
2) "java concurrency"
3) "think in jvava"
127.0.0.1:6379> zrevrange books 0 -1
1) "think in jvava"
2) "java concurrency"
3) "java cookbook"
127.0.0.1:6379> zcard books
(integer) 3
127.0.0.1:6379> zscore books "java cookbook"
"8.5999999999999996"
# 排名
127.0.0.1:6379> zrank books "java concurrency"
(integer) 1
127.0.0.1:6379> zrangebyscore books 8.8 9.5
1) "java concurrency"
2) "think in jvava"
127.0.0.1:6379> zrangebyscore books -inf 8.91 withscores
1) "java cookbook"
2) "8.5999999999999996"
3) "java concurrency"
4) "8.9000000000000004"
127.0.0.1:6379> zrem books "java cookbook"
(integer) 1
127.0.0.1:6379> zrange books 0 -1
1) "java concurrency"
2) "think in jvava"
其他高级用法
keys:全量遍历键
用来列出所有满足特定正则字符串规则的key,当redis数据量比较大时,性能比较差,要避免使用
Info
查看redis服务运行信息,分为 9 大块,每个块都有非常多的参数,这 9 个块分别是:
- Server 服务器运行的环境参数
- Clients 客户端相关信息
- Memory 服务器运行内存统计数据
- Persistence 持久化信息
- Stats 通用统计数据
- Replication 主从复制相关信息
- CPU CPU 使用情况
- Cluster 集群信息