【Redis】--- 不同数据结构命令
前言
数据结构
string (字符串)
使用场景
一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户信息会经过一次反序列化的过程。
命令
说明 | 命令 | 结果 |
---|---|---|
设置值 | set name abner | |
取值 | get name | |
批量取值 | mget name name1 | |
已有的key设置过期时间 | expire local 2 | |
设置值并且设置过期时间 | setex local 20 Beijing | |
不存在则创建 | setnx local shanghai | 成功返回1,失败0 |
本地:0>set name abner
"OK"
本地:0>get name
"abner"
本地:0>set name1 condy
"OK"
本地:0>mget name name1
1) "abner"
2) "condy"
本地:0>mget name name1 name2
1) "abner"
2) "condy"
3) null
本地:0>set local BeJing
"OK"
本地:0>get local
"BeJing"
本地:0>expire local 2
"1"
本地:0>get local
null
本地:0>setex local 20 Beijing
"OK"
本地:0>get local
"Beijing"
本地:0>get local
"Beijing"
本地:0>get local
null
本地:0>setnx local shanghai
"1"
本地:0>get local
"shanghai"
本地:0>setnx local chongqing
"0"
原子计数
如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是 signed long 的最大最小值,超过了这个值,Redis 会报错
本地:0>set day 1
"OK"
本地:0>incr day
"2"
本地:0>get day
"2"
本地:0>incrby day 5
"7"
本地:0>incrby day -5
"2"
本地:0>set day 9223372036854775807
"OK"
本地:0>incrby day
"ERR wrong number of arguments for 'incrby' command"
list (列表)
使用场景
类似于java中的链表,增删快,查找慢。当列表中弹出最后一个元素,该数据结构自动被删除,内存被回收。通常用作异步队列使用
- 右边进左边出:队列
- 右边进右边出:栈
命令
说明 | 命令 | 结果 |
---|---|---|
右进设置值 | rpush books python java c++ go | |
list长度 | llen books | |
左弹出数据 | lpop books | |
左获取list中的元素 | lrange books 0 -1 | |
左获取list中的元素 | lrange books 0 -1 | |
右弹出数据 | rpop books |
本地:0>rpush books python java c++ go
"4"
本地:0>llen books
"4"
本地:0>lpop books
"python"
本地:0>lpop books
"java"
本地:0>lpop books
"c++"
本地:0>lpop books
"go"
本地:0>lpop books
null
本地:0>get books
null
本地:0>rpush books python java c++
"3"
本地:0>get books
"WRONGTYPE Operation against a key holding the wrong kind of value"
本地:0>lrange books 0 -1
1) "python"
2) "java"
3) "c++"
本地:0>lrange booke 1 2
本地:0>lrange books 1 2
1) "java"
2) "c++"
本地:0>rpush books go
"4"
本地:0>lrange books 0 -1
1) "python"
2) "java"
3) "c++"
4) "go"
本地:0>lpush books asd
"5"
本地:0>lrange books 0 -1
1) "asd"
2) "python"
3) "java"
4) "c++"
5) "go"
本地:0>rpop books
"go"
本地:0>
hash (字典)
使用场景
类似于java中的HashMap,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对 用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。 hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情况再三权衡。
命令
说明 | 命令 | 结果 |
---|---|---|
设置值 | hset company name "CIH" | |
获取对象所有属性 | hgetall company | |
批量设置对象属性 | hset company business "房地产" staff "程序猿&程序媛" | |
获取对象属性个数 | hlen company |
本地:0>hset company name "CIH"
"1"
本地:0>hset company local "郭公庄地铁站"
"1"
本地:0>hgetall company
1) "name"
2) "CIH"
3) "local"
4) "郭公庄地铁站"
本地:0>hlen company
"2"
本地:0>hget company local
"郭公庄地铁站"
本地:0>hset company business "房地产" staff "程序猿&程序媛"
"2"
本地:0>hgetall company
1) "name"
2) "CIH"
3) "local"
4) "郭公庄地铁站"
5) "business"
6) "房地产"
7) "staff"
8) "程序猿&程序媛"
本地:0>
set (集合)
使用场景
相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值NULL。 当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。
命令
说明 | 命令 | 结果 |
---|---|---|
设置值 | sadd infos java | |
批量设置值 | sadd infos c++ go | |
获取set中所有值 | smembers infos | |
判断某个值是否存在 | sismember infos go | |
获取长度 | scard infos | |
弹出值 | spop infos |
本地:0>sadd infos java
"1"
本地:0>sadd infos python
"1"
本地:0>sadd infos c++ go
"2"
本地:0>smembers infos
1) "go"
2) "python"
3) "c++"
4) "java"
本地:0>sismember infos go
"1"
本地:0>scard infos
"4"
本地:0>spop infos
"c++"
本地:0>
zset (有序集合)
使用场景
zset 似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。
zset 可以用来存粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。我们可以对粉丝列表按关注时间进行排序。
zset 还可以用来存储学生的成绩,value 值是学生的 ID,score 是他的考试成绩。我们可以对成绩按分数进行排序就可以得到他的名次。
命令
说明 | 命令 | 结果 |
---|---|---|
设置值 | zadd car 100 "劳斯莱斯" | |
获取全部值升序 | zrange car 0 -1 | |
获取全部值降序 | zrevrange car 0 -1 | |
获取长度 | zcard car | |
获取权重 | zscore car "布加迪" | |
获取某个值排名 | zrank car "兰博基尼" | |
根据分值区间遍历 | zrangebyscore car 0 87 | |
移除某个元素 | zrem car "法拉利" |
本地:0>zadd car 100 "劳斯莱斯"
"1"
本地:0>zadd car 90 "迈巴赫"
"1"
本地:0>zadd car 80 "布加迪"
"1"
本地:0>zadd car 85 "兰博基尼"
"1"
本地:0>zrange car 0 -1
1) "布加迪"
2) "兰博基尼"
3) "迈巴赫"
4) "劳斯莱斯"
本地:0>zrevrange car 0 -1
1) "劳斯莱斯"
2) "迈巴赫"
3) "兰博基尼"
4) "布加迪"
本地:0>zcard car
"4"
本地:0>zscore car "布加迪"
"80"
本地:0>zadd car 85.5 "法拉利"
"1"
本地:0>zrange car 0 -1
1) "布加迪"
2) "兰博基尼"
3) "法拉利"
4) "迈巴赫"
5) "劳斯莱斯"
本地:0>zscore car "法拉利"
"85.5"
本地:0>zrange car "劳斯莱斯"
"ERR wrong number of arguments for 'zrange' command"
本地:0>zrank car "布加迪"
"0"
本地:0>zrank car "兰博基尼"
"1"
本地:0>zrangebyscore car 0 87
1) "布加迪"
2) "兰博基尼"
3) "法拉利"
本地:0>zrangebyscore car -inf 87 withscores
1) "布加迪"
2) "80"
3) "兰博基尼"
4) "85"
5) "法拉利"
6) "85.5"
本地:0>zrem car "法拉利"
"1"
本地:0>zrem car "wuxiao"
"0"
高级命令
获取全部Key
说明 | 命令 | 缺点 |
---|---|---|
获取全部Key | keys * | 当redis数据量比较大时,性能比较差 |
渐进式遍历键 | SCAN cursor [MATCH pattern] [COUNT count] | 通过游标分步进行的,不会阻塞线程 |
渐进式遍历键
参数
- cursor :整数值,光标值
- MATCH :key 的正则模式
- COUNT :限定服务器单次遍历的字典槽位数量(下图中绿色部分)
原理分析
在 Redis 中所有的 key 都存储在一个很大的字典中,这个字典的结构和 Java 中的 HashMap 一样,是一维数组 + 二维链表结构,第一维数组的大小总是 2^n(n>=0),扩容一次数组大小空间加倍,也就是 n++。
scan 的遍历顺序非常特别。它不是从第一维数组的第 0 位一直遍历到末尾,而是采用了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。
普通加法和高位进位加法的区别
高位进位法从左边加,进位往右边移动,同普通加法正好相反。但是最终它们都会遍历所有的槽位并且没有重复。
————————————————
版权声明:本文为CSDN博主「damanchen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/damanchen/article/details/89314930
Info:查看redis服务运行信息,分为 9 大块,每个块都有非常多的参数,这 9 个块分别是:
Server 服务器运行的环境参数
Clients 客户端相关信息
Memory 服务器运行内存统计数据
Persistence 持久化信息
Stats 通用统计数据
Replication 主从复制相关信息
CPU CPU 使用情况
Cluster 集群信息